Index: stable/11/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- stable/11/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp (revision 363091) +++ stable/11/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp (revision 363092) @@ -1,8548 +1,8544 @@ //===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// Implements semantic analysis for C++ expressions. /// //===----------------------------------------------------------------------===// #include "clang/Sema/Template.h" #include "clang/Sema/SemaInternal.h" #include "TreeTransform.h" #include "TypeLocBuilder.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTLambda.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/AlignedAllocation.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaLambda.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; using namespace sema; /// Handle the result of the special case name lookup for inheriting /// constructor declarations. 'NS::X::X' and 'NS::X<...>::X' are treated as /// constructor names in member using declarations, even if 'X' is not the /// name of the corresponding type. ParsedType Sema::getInheritingConstructorName(CXXScopeSpec &SS, SourceLocation NameLoc, IdentifierInfo &Name) { NestedNameSpecifier *NNS = SS.getScopeRep(); // Convert the nested-name-specifier into a type. QualType Type; switch (NNS->getKind()) { case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpecWithTemplate: Type = QualType(NNS->getAsType(), 0); break; case NestedNameSpecifier::Identifier: // Strip off the last layer of the nested-name-specifier and build a // typename type for it. assert(NNS->getAsIdentifier() == &Name && "not a constructor name"); Type = Context.getDependentNameType(ETK_None, NNS->getPrefix(), NNS->getAsIdentifier()); break; case NestedNameSpecifier::Global: case NestedNameSpecifier::Super: case NestedNameSpecifier::Namespace: case NestedNameSpecifier::NamespaceAlias: llvm_unreachable("Nested name specifier is not a type for inheriting ctor"); } // This reference to the type is located entirely at the location of the // final identifier in the qualified-id. return CreateParsedType(Type, Context.getTrivialTypeSourceInfo(Type, NameLoc)); } ParsedType Sema::getConstructorName(IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, bool EnteringContext) { CXXRecordDecl *CurClass = getCurrentClass(S, &SS); assert(CurClass && &II == CurClass->getIdentifier() && "not a constructor name"); // When naming a constructor as a member of a dependent context (eg, in a // friend declaration or an inherited constructor declaration), form an // unresolved "typename" type. if (CurClass->isDependentContext() && !EnteringContext && SS.getScopeRep()) { QualType T = Context.getDependentNameType(ETK_None, SS.getScopeRep(), &II); return ParsedType::make(T); } if (SS.isNotEmpty() && RequireCompleteDeclContext(SS, CurClass)) return ParsedType(); // Find the injected-class-name declaration. Note that we make no attempt to // diagnose cases where the injected-class-name is shadowed: the only // declaration that can validly shadow the injected-class-name is a // non-static data member, and if the class contains both a non-static data // member and a constructor then it is ill-formed (we check that in // CheckCompletedCXXClass). CXXRecordDecl *InjectedClassName = nullptr; for (NamedDecl *ND : CurClass->lookup(&II)) { auto *RD = dyn_cast(ND); if (RD && RD->isInjectedClassName()) { InjectedClassName = RD; break; } } if (!InjectedClassName) { if (!CurClass->isInvalidDecl()) { // FIXME: RequireCompleteDeclContext doesn't check dependent contexts // properly. Work around it here for now. Diag(SS.getLastQualifierNameLoc(), diag::err_incomplete_nested_name_spec) << CurClass << SS.getRange(); } return ParsedType(); } QualType T = Context.getTypeDeclType(InjectedClassName); DiagnoseUseOfDecl(InjectedClassName, NameLoc); MarkAnyDeclReferenced(NameLoc, InjectedClassName, /*OdrUse=*/false); return ParsedType::make(T); } ParsedType Sema::getDestructorName(SourceLocation TildeLoc, IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, ParsedType ObjectTypePtr, bool EnteringContext) { // Determine where to perform name lookup. // FIXME: This area of the standard is very messy, and the current // wording is rather unclear about which scopes we search for the // destructor name; see core issues 399 and 555. Issue 399 in // particular shows where the current description of destructor name // lookup is completely out of line with existing practice, e.g., // this appears to be ill-formed: // // namespace N { // template struct S { // ~S(); // }; // } // // void f(N::S* s) { // s->N::S::~S(); // } // // See also PR6358 and PR6359. // For this reason, we're currently only doing the C++03 version of this // code; the C++0x version has to wait until we get a proper spec. QualType SearchType; DeclContext *LookupCtx = nullptr; bool isDependent = false; bool LookInScope = false; if (SS.isInvalid()) return nullptr; // If we have an object type, it's because we are in a // pseudo-destructor-expression or a member access expression, and // we know what type we're looking for. if (ObjectTypePtr) SearchType = GetTypeFromParser(ObjectTypePtr); if (SS.isSet()) { NestedNameSpecifier *NNS = SS.getScopeRep(); bool AlreadySearched = false; bool LookAtPrefix = true; // C++11 [basic.lookup.qual]p6: // If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier, // the type-names are looked up as types in the scope designated by the // nested-name-specifier. Similarly, in a qualified-id of the form: // // nested-name-specifier[opt] class-name :: ~ class-name // // the second class-name is looked up in the same scope as the first. // // Here, we determine whether the code below is permitted to look at the // prefix of the nested-name-specifier. DeclContext *DC = computeDeclContext(SS, EnteringContext); if (DC && DC->isFileContext()) { AlreadySearched = true; LookupCtx = DC; isDependent = false; } else if (DC && isa(DC)) { LookAtPrefix = false; LookInScope = true; } // The second case from the C++03 rules quoted further above. NestedNameSpecifier *Prefix = nullptr; if (AlreadySearched) { // Nothing left to do. } else if (LookAtPrefix && (Prefix = NNS->getPrefix())) { CXXScopeSpec PrefixSS; PrefixSS.Adopt(NestedNameSpecifierLoc(Prefix, SS.location_data())); LookupCtx = computeDeclContext(PrefixSS, EnteringContext); isDependent = isDependentScopeSpecifier(PrefixSS); } else if (ObjectTypePtr) { LookupCtx = computeDeclContext(SearchType); isDependent = SearchType->isDependentType(); } else { LookupCtx = computeDeclContext(SS, EnteringContext); isDependent = LookupCtx && LookupCtx->isDependentContext(); } } else if (ObjectTypePtr) { // C++ [basic.lookup.classref]p3: // If the unqualified-id is ~type-name, the type-name is looked up // in the context of the entire postfix-expression. If the type T // of the object expression is of a class type C, the type-name is // also looked up in the scope of class C. At least one of the // lookups shall find a name that refers to (possibly // cv-qualified) T. LookupCtx = computeDeclContext(SearchType); isDependent = SearchType->isDependentType(); assert((isDependent || !SearchType->isIncompleteType()) && "Caller should have completed object type"); LookInScope = true; } else { // Perform lookup into the current scope (only). LookInScope = true; } TypeDecl *NonMatchingTypeDecl = nullptr; LookupResult Found(*this, &II, NameLoc, LookupOrdinaryName); for (unsigned Step = 0; Step != 2; ++Step) { // Look for the name first in the computed lookup context (if we // have one) and, if that fails to find a match, in the scope (if // we're allowed to look there). Found.clear(); if (Step == 0 && LookupCtx) { if (RequireCompleteDeclContext(SS, LookupCtx)) return nullptr; LookupQualifiedName(Found, LookupCtx); } else if (Step == 1 && LookInScope && S) { LookupName(Found, S); } else { continue; } // FIXME: Should we be suppressing ambiguities here? if (Found.isAmbiguous()) return nullptr; if (TypeDecl *Type = Found.getAsSingle()) { QualType T = Context.getTypeDeclType(Type); MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false); if (SearchType.isNull() || SearchType->isDependentType() || Context.hasSameUnqualifiedType(T, SearchType)) { // We found our type! return CreateParsedType(T, Context.getTrivialTypeSourceInfo(T, NameLoc)); } if (!SearchType.isNull()) NonMatchingTypeDecl = Type; } // If the name that we found is a class template name, and it is // the same name as the template name in the last part of the // nested-name-specifier (if present) or the object type, then // this is the destructor for that class. // FIXME: This is a workaround until we get real drafting for core // issue 399, for which there isn't even an obvious direction. if (ClassTemplateDecl *Template = Found.getAsSingle()) { QualType MemberOfType; if (SS.isSet()) { if (DeclContext *Ctx = computeDeclContext(SS, EnteringContext)) { // Figure out the type of the context, if it has one. if (CXXRecordDecl *Record = dyn_cast(Ctx)) MemberOfType = Context.getTypeDeclType(Record); } } if (MemberOfType.isNull()) MemberOfType = SearchType; if (MemberOfType.isNull()) continue; // We're referring into a class template specialization. If the // class template we found is the same as the template being // specialized, we found what we are looking for. if (const RecordType *Record = MemberOfType->getAs()) { if (ClassTemplateSpecializationDecl *Spec = dyn_cast(Record->getDecl())) { if (Spec->getSpecializedTemplate()->getCanonicalDecl() == Template->getCanonicalDecl()) return CreateParsedType( MemberOfType, Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc)); } continue; } // We're referring to an unresolved class template // specialization. Determine whether we class template we found // is the same as the template being specialized or, if we don't // know which template is being specialized, that it at least // has the same name. if (const TemplateSpecializationType *SpecType = MemberOfType->getAs()) { TemplateName SpecName = SpecType->getTemplateName(); // The class template we found is the same template being // specialized. if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) { if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl()) return CreateParsedType( MemberOfType, Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc)); continue; } // The class template we found has the same name as the // (dependent) template name being specialized. if (DependentTemplateName *DepTemplate = SpecName.getAsDependentTemplateName()) { if (DepTemplate->isIdentifier() && DepTemplate->getIdentifier() == Template->getIdentifier()) return CreateParsedType( MemberOfType, Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc)); continue; } } } } if (isDependent) { // We didn't find our type, but that's okay: it's dependent // anyway. // FIXME: What if we have no nested-name-specifier? QualType T = CheckTypenameType(ETK_None, SourceLocation(), SS.getWithLocInContext(Context), II, NameLoc); return ParsedType::make(T); } if (NonMatchingTypeDecl) { QualType T = Context.getTypeDeclType(NonMatchingTypeDecl); Diag(NameLoc, diag::err_destructor_expr_type_mismatch) << T << SearchType; Diag(NonMatchingTypeDecl->getLocation(), diag::note_destructor_type_here) << T; } else if (ObjectTypePtr) Diag(NameLoc, diag::err_ident_in_dtor_not_a_type) << &II; else { SemaDiagnosticBuilder DtorDiag = Diag(NameLoc, diag::err_destructor_class_name); if (S) { const DeclContext *Ctx = S->getEntity(); if (const CXXRecordDecl *Class = dyn_cast_or_null(Ctx)) DtorDiag << FixItHint::CreateReplacement(SourceRange(NameLoc), Class->getNameAsString()); } } return nullptr; } ParsedType Sema::getDestructorTypeForDecltype(const DeclSpec &DS, ParsedType ObjectType) { if (DS.getTypeSpecType() == DeclSpec::TST_error) return nullptr; if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto) { Diag(DS.getTypeSpecTypeLoc(), diag::err_decltype_auto_invalid); return nullptr; } assert(DS.getTypeSpecType() == DeclSpec::TST_decltype && "unexpected type in getDestructorType"); QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc()); // If we know the type of the object, check that the correct destructor // type was named now; we can give better diagnostics this way. QualType SearchType = GetTypeFromParser(ObjectType); if (!SearchType.isNull() && !SearchType->isDependentType() && !Context.hasSameUnqualifiedType(T, SearchType)) { Diag(DS.getTypeSpecTypeLoc(), diag::err_destructor_expr_type_mismatch) << T << SearchType; return nullptr; } return ParsedType::make(T); } bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Name) { assert(Name.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId); if (!SS.isValid()) return false; switch (SS.getScopeRep()->getKind()) { case NestedNameSpecifier::Identifier: case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpecWithTemplate: // Per C++11 [over.literal]p2, literal operators can only be declared at // namespace scope. Therefore, this unqualified-id cannot name anything. // Reject it early, because we have no AST representation for this in the // case where the scope is dependent. Diag(Name.getBeginLoc(), diag::err_literal_operator_id_outside_namespace) << SS.getScopeRep(); return true; case NestedNameSpecifier::Global: case NestedNameSpecifier::Super: case NestedNameSpecifier::Namespace: case NestedNameSpecifier::NamespaceAlias: return false; } llvm_unreachable("unknown nested name specifier kind"); } /// Build a C++ typeid expression with a type operand. ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc) { // C++ [expr.typeid]p4: // The top-level cv-qualifiers of the lvalue expression or the type-id // that is the operand of typeid are always ignored. // If the type of the type-id is a class type or a reference to a class // type, the class shall be completely-defined. Qualifiers Quals; QualType T = Context.getUnqualifiedArrayType(Operand->getType().getNonReferenceType(), Quals); if (T->getAs() && RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid)) return ExprError(); if (T->isVariablyModifiedType()) return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << T); if (CheckQualifiedFunctionForTypeId(T, TypeidLoc)) return ExprError(); return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand, SourceRange(TypeidLoc, RParenLoc)); } /// Build a C++ typeid expression with an expression operand. ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, SourceLocation TypeidLoc, Expr *E, SourceLocation RParenLoc) { bool WasEvaluated = false; if (E && !E->isTypeDependent()) { if (E->getType()->isPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(E); if (result.isInvalid()) return ExprError(); E = result.get(); } QualType T = E->getType(); if (const RecordType *RecordT = T->getAs()) { CXXRecordDecl *RecordD = cast(RecordT->getDecl()); // C++ [expr.typeid]p3: // [...] If the type of the expression is a class type, the class // shall be completely-defined. if (RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid)) return ExprError(); // C++ [expr.typeid]p3: // When typeid is applied to an expression other than an glvalue of a // polymorphic class type [...] [the] expression is an unevaluated // operand. [...] if (RecordD->isPolymorphic() && E->isGLValue()) { // The subexpression is potentially evaluated; switch the context // and recheck the subexpression. ExprResult Result = TransformToPotentiallyEvaluated(E); if (Result.isInvalid()) return ExprError(); E = Result.get(); // We require a vtable to query the type at run time. MarkVTableUsed(TypeidLoc, RecordD); WasEvaluated = true; } } ExprResult Result = CheckUnevaluatedOperand(E); if (Result.isInvalid()) return ExprError(); E = Result.get(); // C++ [expr.typeid]p4: // [...] If the type of the type-id is a reference to a possibly // cv-qualified type, the result of the typeid expression refers to a // std::type_info object representing the cv-unqualified referenced // type. Qualifiers Quals; QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals); if (!Context.hasSameType(T, UnqualT)) { T = UnqualT; E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).get(); } } if (E->getType()->isVariablyModifiedType()) return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << E->getType()); else if (!inTemplateInstantiation() && E->HasSideEffects(Context, WasEvaluated)) { // The expression operand for typeid is in an unevaluated expression // context, so side effects could result in unintended consequences. Diag(E->getExprLoc(), WasEvaluated ? diag::warn_side_effects_typeid : diag::warn_side_effects_unevaluated_context); } return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E, SourceRange(TypeidLoc, RParenLoc)); } /// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression); ExprResult Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, bool isType, void *TyOrExpr, SourceLocation RParenLoc) { // typeid is not supported in OpenCL. if (getLangOpts().OpenCLCPlusPlus) { return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported) << "typeid"); } // Find the std::type_info type. if (!getStdNamespace()) return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); if (!CXXTypeInfoDecl) { IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info"); LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName); LookupQualifiedName(R, getStdNamespace()); CXXTypeInfoDecl = R.getAsSingle(); // Microsoft's typeinfo doesn't have type_info in std but in the global // namespace if _HAS_EXCEPTIONS is defined to 0. See PR13153. if (!CXXTypeInfoDecl && LangOpts.MSVCCompat) { LookupQualifiedName(R, Context.getTranslationUnitDecl()); CXXTypeInfoDecl = R.getAsSingle(); } if (!CXXTypeInfoDecl) return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); } if (!getLangOpts().RTTI) { return ExprError(Diag(OpLoc, diag::err_no_typeid_with_fno_rtti)); } QualType TypeInfoType = Context.getTypeDeclType(CXXTypeInfoDecl); if (isType) { // The operand is a type; handle it as such. TypeSourceInfo *TInfo = nullptr; QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr), &TInfo); if (T.isNull()) return ExprError(); if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc); return BuildCXXTypeId(TypeInfoType, OpLoc, TInfo, RParenLoc); } // The operand is an expression. return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc); } /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to /// a single GUID. static void getUuidAttrOfType(Sema &SemaRef, QualType QT, llvm::SmallSetVector &UuidAttrs) { // Optionally remove one level of pointer, reference or array indirection. const Type *Ty = QT.getTypePtr(); if (QT->isPointerType() || QT->isReferenceType()) Ty = QT->getPointeeType().getTypePtr(); else if (QT->isArrayType()) Ty = Ty->getBaseElementTypeUnsafe(); const auto *TD = Ty->getAsTagDecl(); if (!TD) return; if (const auto *Uuid = TD->getMostRecentDecl()->getAttr()) { UuidAttrs.insert(Uuid); return; } // __uuidof can grab UUIDs from template arguments. if (const auto *CTSD = dyn_cast(TD)) { const TemplateArgumentList &TAL = CTSD->getTemplateArgs(); for (const TemplateArgument &TA : TAL.asArray()) { const UuidAttr *UuidForTA = nullptr; if (TA.getKind() == TemplateArgument::Type) getUuidAttrOfType(SemaRef, TA.getAsType(), UuidAttrs); else if (TA.getKind() == TemplateArgument::Declaration) getUuidAttrOfType(SemaRef, TA.getAsDecl()->getType(), UuidAttrs); if (UuidForTA) UuidAttrs.insert(UuidForTA); } } } /// Build a Microsoft __uuidof expression with a type operand. ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc) { StringRef UuidStr; if (!Operand->getType()->isDependentType()) { llvm::SmallSetVector UuidAttrs; getUuidAttrOfType(*this, Operand->getType(), UuidAttrs); if (UuidAttrs.empty()) return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); if (UuidAttrs.size() > 1) return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids)); UuidStr = UuidAttrs.back()->getGuid(); } return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UuidStr, SourceRange(TypeidLoc, RParenLoc)); } /// Build a Microsoft __uuidof expression with an expression operand. ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, SourceLocation TypeidLoc, Expr *E, SourceLocation RParenLoc) { StringRef UuidStr; if (!E->getType()->isDependentType()) { if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { UuidStr = "00000000-0000-0000-0000-000000000000"; } else { llvm::SmallSetVector UuidAttrs; getUuidAttrOfType(*this, E->getType(), UuidAttrs); if (UuidAttrs.empty()) return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); if (UuidAttrs.size() > 1) return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids)); UuidStr = UuidAttrs.back()->getGuid(); } } return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E, UuidStr, SourceRange(TypeidLoc, RParenLoc)); } /// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression); ExprResult Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc, bool isType, void *TyOrExpr, SourceLocation RParenLoc) { // If MSVCGuidDecl has not been cached, do the lookup. if (!MSVCGuidDecl) { IdentifierInfo *GuidII = &PP.getIdentifierTable().get("_GUID"); LookupResult R(*this, GuidII, SourceLocation(), LookupTagName); LookupQualifiedName(R, Context.getTranslationUnitDecl()); MSVCGuidDecl = R.getAsSingle(); if (!MSVCGuidDecl) return ExprError(Diag(OpLoc, diag::err_need_header_before_ms_uuidof)); } QualType GuidType = Context.getTypeDeclType(MSVCGuidDecl); if (isType) { // The operand is a type; handle it as such. TypeSourceInfo *TInfo = nullptr; QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr), &TInfo); if (T.isNull()) return ExprError(); if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc); return BuildCXXUuidof(GuidType, OpLoc, TInfo, RParenLoc); } // The operand is an expression. return BuildCXXUuidof(GuidType, OpLoc, (Expr*)TyOrExpr, RParenLoc); } /// ActOnCXXBoolLiteral - Parse {true,false} literals. ExprResult Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { assert((Kind == tok::kw_true || Kind == tok::kw_false) && "Unknown C++ Boolean value!"); return new (Context) CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc); } /// ActOnCXXNullPtrLiteral - Parse 'nullptr'. ExprResult Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) { return new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc); } /// ActOnCXXThrow - Parse throw expressions. ExprResult Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) { bool IsThrownVarInScope = false; if (Ex) { // C++0x [class.copymove]p31: // When certain criteria are met, an implementation is allowed to omit the // copy/move construction of a class object [...] // // - in a throw-expression, when the operand is the name of a // non-volatile automatic object (other than a function or catch- // clause parameter) whose scope does not extend beyond the end of the // innermost enclosing try-block (if there is one), the copy/move // operation from the operand to the exception object (15.1) can be // omitted by constructing the automatic object directly into the // exception object if (DeclRefExpr *DRE = dyn_cast(Ex->IgnoreParens())) if (VarDecl *Var = dyn_cast(DRE->getDecl())) { if (Var->hasLocalStorage() && !Var->getType().isVolatileQualified()) { for( ; S; S = S->getParent()) { if (S->isDeclScope(Var)) { IsThrownVarInScope = true; break; } if (S->getFlags() & (Scope::FnScope | Scope::ClassScope | Scope::BlockScope | Scope::FunctionPrototypeScope | Scope::ObjCMethodScope | Scope::TryScope)) break; } } } } return BuildCXXThrow(OpLoc, Ex, IsThrownVarInScope); } ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, bool IsThrownVarInScope) { // Don't report an error if 'throw' is used in system headers. if (!getLangOpts().CXXExceptions && !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) { // Delay error emission for the OpenMP device code. targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw"; } // Exceptions aren't allowed in CUDA device code. if (getLangOpts().CUDA) CUDADiagIfDeviceCode(OpLoc, diag::err_cuda_device_exceptions) << "throw" << CurrentCUDATarget(); if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope()) Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw"; if (Ex && !Ex->isTypeDependent()) { QualType ExceptionObjectTy = Context.getExceptionObjectType(Ex->getType()); if (CheckCXXThrowOperand(OpLoc, ExceptionObjectTy, Ex)) return ExprError(); // Initialize the exception result. This implicitly weeds out // abstract types or types with inaccessible copy constructors. // C++0x [class.copymove]p31: // When certain criteria are met, an implementation is allowed to omit the // copy/move construction of a class object [...] // // - in a throw-expression, when the operand is the name of a // non-volatile automatic object (other than a function or // catch-clause // parameter) whose scope does not extend beyond the end of the // innermost enclosing try-block (if there is one), the copy/move // operation from the operand to the exception object (15.1) can be // omitted by constructing the automatic object directly into the // exception object const VarDecl *NRVOVariable = nullptr; if (IsThrownVarInScope) NRVOVariable = getCopyElisionCandidate(QualType(), Ex, CES_Strict); InitializedEntity Entity = InitializedEntity::InitializeException( OpLoc, ExceptionObjectTy, /*NRVO=*/NRVOVariable != nullptr); ExprResult Res = PerformMoveOrCopyInitialization( Entity, NRVOVariable, QualType(), Ex, IsThrownVarInScope); if (Res.isInvalid()) return ExprError(); Ex = Res.get(); } return new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope); } static void collectPublicBases(CXXRecordDecl *RD, llvm::DenseMap &SubobjectsSeen, llvm::SmallPtrSetImpl &VBases, llvm::SetVector &PublicSubobjectsSeen, bool ParentIsPublic) { for (const CXXBaseSpecifier &BS : RD->bases()) { CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl(); bool NewSubobject; // Virtual bases constitute the same subobject. Non-virtual bases are // always distinct subobjects. if (BS.isVirtual()) NewSubobject = VBases.insert(BaseDecl).second; else NewSubobject = true; if (NewSubobject) ++SubobjectsSeen[BaseDecl]; // Only add subobjects which have public access throughout the entire chain. bool PublicPath = ParentIsPublic && BS.getAccessSpecifier() == AS_public; if (PublicPath) PublicSubobjectsSeen.insert(BaseDecl); // Recurse on to each base subobject. collectPublicBases(BaseDecl, SubobjectsSeen, VBases, PublicSubobjectsSeen, PublicPath); } } static void getUnambiguousPublicSubobjects( CXXRecordDecl *RD, llvm::SmallVectorImpl &Objects) { llvm::DenseMap SubobjectsSeen; llvm::SmallSet VBases; llvm::SetVector PublicSubobjectsSeen; SubobjectsSeen[RD] = 1; PublicSubobjectsSeen.insert(RD); collectPublicBases(RD, SubobjectsSeen, VBases, PublicSubobjectsSeen, /*ParentIsPublic=*/true); for (CXXRecordDecl *PublicSubobject : PublicSubobjectsSeen) { // Skip ambiguous objects. if (SubobjectsSeen[PublicSubobject] > 1) continue; Objects.push_back(PublicSubobject); } } /// CheckCXXThrowOperand - Validate the operand of a throw. bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ExceptionObjectTy, Expr *E) { // If the type of the exception would be an incomplete type or a pointer // to an incomplete type other than (cv) void the program is ill-formed. QualType Ty = ExceptionObjectTy; bool isPointer = false; if (const PointerType* Ptr = Ty->getAs()) { Ty = Ptr->getPointeeType(); isPointer = true; } if (!isPointer || !Ty->isVoidType()) { if (RequireCompleteType(ThrowLoc, Ty, isPointer ? diag::err_throw_incomplete_ptr : diag::err_throw_incomplete, E->getSourceRange())) return true; if (RequireNonAbstractType(ThrowLoc, ExceptionObjectTy, diag::err_throw_abstract_type, E)) return true; } // If the exception has class type, we need additional handling. CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); if (!RD) return false; // If we are throwing a polymorphic class type or pointer thereof, // exception handling will make use of the vtable. MarkVTableUsed(ThrowLoc, RD); // If a pointer is thrown, the referenced object will not be destroyed. if (isPointer) return false; // If the class has a destructor, we must be able to call it. if (!RD->hasIrrelevantDestructor()) { if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) { MarkFunctionReferenced(E->getExprLoc(), Destructor); CheckDestructorAccess(E->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_exception) << Ty); if (DiagnoseUseOfDecl(Destructor, E->getExprLoc())) return true; } } // The MSVC ABI creates a list of all types which can catch the exception // object. This list also references the appropriate copy constructor to call // if the object is caught by value and has a non-trivial copy constructor. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { // We are only interested in the public, unambiguous bases contained within // the exception object. Bases which are ambiguous or otherwise // inaccessible are not catchable types. llvm::SmallVector UnambiguousPublicSubobjects; getUnambiguousPublicSubobjects(RD, UnambiguousPublicSubobjects); for (CXXRecordDecl *Subobject : UnambiguousPublicSubobjects) { // Attempt to lookup the copy constructor. Various pieces of machinery // will spring into action, like template instantiation, which means this // cannot be a simple walk of the class's decls. Instead, we must perform // lookup and overload resolution. CXXConstructorDecl *CD = LookupCopyingConstructor(Subobject, 0); if (!CD || CD->isDeleted()) continue; // Mark the constructor referenced as it is used by this throw expression. MarkFunctionReferenced(E->getExprLoc(), CD); // Skip this copy constructor if it is trivial, we don't need to record it // in the catchable type data. if (CD->isTrivial()) continue; // The copy constructor is non-trivial, create a mapping from this class // type to this constructor. // N.B. The selection of copy constructor is not sensitive to this // particular throw-site. Lookup will be performed at the catch-site to // ensure that the copy constructor is, in fact, accessible (via // friendship or any other means). Context.addCopyConstructorForExceptionObject(Subobject, CD); // We don't keep the instantiated default argument expressions around so // we must rebuild them here. for (unsigned I = 1, E = CD->getNumParams(); I != E; ++I) { if (CheckCXXDefaultArgExpr(ThrowLoc, CD, CD->getParamDecl(I))) return true; } } } // Under the Itanium C++ ABI, memory for the exception object is allocated by // the runtime with no ability for the compiler to request additional // alignment. Warn if the exception type requires alignment beyond the minimum // guaranteed by the target C++ runtime. if (Context.getTargetInfo().getCXXABI().isItaniumFamily()) { CharUnits TypeAlign = Context.getTypeAlignInChars(Ty); CharUnits ExnObjAlign = Context.getExnObjectAlignment(); if (ExnObjAlign < TypeAlign) { Diag(ThrowLoc, diag::warn_throw_underaligned_obj); Diag(ThrowLoc, diag::note_throw_underaligned_obj) << Ty << (unsigned)TypeAlign.getQuantity() << (unsigned)ExnObjAlign.getQuantity(); } } return false; } static QualType adjustCVQualifiersForCXXThisWithinLambda( ArrayRef FunctionScopes, QualType ThisTy, DeclContext *CurSemaContext, ASTContext &ASTCtx) { QualType ClassType = ThisTy->getPointeeType(); LambdaScopeInfo *CurLSI = nullptr; DeclContext *CurDC = CurSemaContext; // Iterate through the stack of lambdas starting from the innermost lambda to // the outermost lambda, checking if '*this' is ever captured by copy - since // that could change the cv-qualifiers of the '*this' object. // The object referred to by '*this' starts out with the cv-qualifiers of its // member function. We then start with the innermost lambda and iterate // outward checking to see if any lambda performs a by-copy capture of '*this' // - and if so, any nested lambda must respect the 'constness' of that // capturing lamdbda's call operator. // // Since the FunctionScopeInfo stack is representative of the lexical // nesting of the lambda expressions during initial parsing (and is the best // place for querying information about captures about lambdas that are // partially processed) and perhaps during instantiation of function templates // that contain lambda expressions that need to be transformed BUT not // necessarily during instantiation of a nested generic lambda's function call // operator (which might even be instantiated at the end of the TU) - at which // time the DeclContext tree is mature enough to query capture information // reliably - we use a two pronged approach to walk through all the lexically // enclosing lambda expressions: // // 1) Climb down the FunctionScopeInfo stack as long as each item represents // a Lambda (i.e. LambdaScopeInfo) AND each LSI's 'closure-type' is lexically // enclosed by the call-operator of the LSI below it on the stack (while // tracking the enclosing DC for step 2 if needed). Note the topmost LSI on // the stack represents the innermost lambda. // // 2) If we run out of enclosing LSI's, check if the enclosing DeclContext // represents a lambda's call operator. If it does, we must be instantiating // a generic lambda's call operator (represented by the Current LSI, and // should be the only scenario where an inconsistency between the LSI and the // DeclContext should occur), so climb out the DeclContexts if they // represent lambdas, while querying the corresponding closure types // regarding capture information. // 1) Climb down the function scope info stack. for (int I = FunctionScopes.size(); I-- && isa(FunctionScopes[I]) && (!CurLSI || !CurLSI->Lambda || CurLSI->Lambda->getDeclContext() == cast(FunctionScopes[I])->CallOperator); CurDC = getLambdaAwareParentOfDeclContext(CurDC)) { CurLSI = cast(FunctionScopes[I]); if (!CurLSI->isCXXThisCaptured()) continue; auto C = CurLSI->getCXXThisCapture(); if (C.isCopyCapture()) { ClassType.removeLocalCVRQualifiers(Qualifiers::CVRMask); if (CurLSI->CallOperator->isConst()) ClassType.addConst(); return ASTCtx.getPointerType(ClassType); } } // 2) We've run out of ScopeInfos but check if CurDC is a lambda (which can // happen during instantiation of its nested generic lambda call operator) if (isLambdaCallOperator(CurDC)) { assert(CurLSI && "While computing 'this' capture-type for a generic " "lambda, we must have a corresponding LambdaScopeInfo"); assert(isGenericLambdaCallOperatorSpecialization(CurLSI->CallOperator) && "While computing 'this' capture-type for a generic lambda, when we " "run out of enclosing LSI's, yet the enclosing DC is a " "lambda-call-operator we must be (i.e. Current LSI) in a generic " "lambda call oeprator"); assert(CurDC == getLambdaAwareParentOfDeclContext(CurLSI->CallOperator)); auto IsThisCaptured = [](CXXRecordDecl *Closure, bool &IsByCopy, bool &IsConst) { IsConst = false; IsByCopy = false; for (auto &&C : Closure->captures()) { if (C.capturesThis()) { if (C.getCaptureKind() == LCK_StarThis) IsByCopy = true; if (Closure->getLambdaCallOperator()->isConst()) IsConst = true; return true; } } return false; }; bool IsByCopyCapture = false; bool IsConstCapture = false; CXXRecordDecl *Closure = cast(CurDC->getParent()); while (Closure && IsThisCaptured(Closure, IsByCopyCapture, IsConstCapture)) { if (IsByCopyCapture) { ClassType.removeLocalCVRQualifiers(Qualifiers::CVRMask); if (IsConstCapture) ClassType.addConst(); return ASTCtx.getPointerType(ClassType); } Closure = isLambdaCallOperator(Closure->getParent()) ? cast(Closure->getParent()->getParent()) : nullptr; } } return ASTCtx.getPointerType(ClassType); } QualType Sema::getCurrentThisType() { DeclContext *DC = getFunctionLevelDeclContext(); QualType ThisTy = CXXThisTypeOverride; if (CXXMethodDecl *method = dyn_cast(DC)) { if (method && method->isInstance()) ThisTy = method->getThisType(); } if (ThisTy.isNull() && isLambdaCallOperator(CurContext) && inTemplateInstantiation()) { assert(isa(DC) && "Trying to get 'this' type from static method?"); // This is a lambda call operator that is being instantiated as a default // initializer. DC must point to the enclosing class type, so we can recover // the 'this' type from it. QualType ClassTy = Context.getTypeDeclType(cast(DC)); // There are no cv-qualifiers for 'this' within default initializers, // per [expr.prim.general]p4. ThisTy = Context.getPointerType(ClassTy); } // If we are within a lambda's call operator, the cv-qualifiers of 'this' // might need to be adjusted if the lambda or any of its enclosing lambda's // captures '*this' by copy. if (!ThisTy.isNull() && isLambdaCallOperator(CurContext)) return adjustCVQualifiersForCXXThisWithinLambda(FunctionScopes, ThisTy, CurContext, Context); return ThisTy; } Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S, Decl *ContextDecl, Qualifiers CXXThisTypeQuals, bool Enabled) : S(S), OldCXXThisTypeOverride(S.CXXThisTypeOverride), Enabled(false) { if (!Enabled || !ContextDecl) return; CXXRecordDecl *Record = nullptr; if (ClassTemplateDecl *Template = dyn_cast(ContextDecl)) Record = Template->getTemplatedDecl(); else Record = cast(ContextDecl); QualType T = S.Context.getRecordType(Record); T = S.getASTContext().getQualifiedType(T, CXXThisTypeQuals); S.CXXThisTypeOverride = S.Context.getPointerType(T); this->Enabled = true; } Sema::CXXThisScopeRAII::~CXXThisScopeRAII() { if (Enabled) { S.CXXThisTypeOverride = OldCXXThisTypeOverride; } } bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit, bool BuildAndDiagnose, const unsigned *const FunctionScopeIndexToStopAt, const bool ByCopy) { // We don't need to capture this in an unevaluated context. if (isUnevaluatedContext() && !Explicit) return true; assert((!ByCopy || Explicit) && "cannot implicitly capture *this by value"); const int MaxFunctionScopesIndex = FunctionScopeIndexToStopAt ? *FunctionScopeIndexToStopAt : FunctionScopes.size() - 1; // Check that we can capture the *enclosing object* (referred to by '*this') // by the capturing-entity/closure (lambda/block/etc) at // MaxFunctionScopesIndex-deep on the FunctionScopes stack. // Note: The *enclosing object* can only be captured by-value by a // closure that is a lambda, using the explicit notation: // [*this] { ... }. // Every other capture of the *enclosing object* results in its by-reference // capture. // For a closure 'L' (at MaxFunctionScopesIndex in the FunctionScopes // stack), we can capture the *enclosing object* only if: // - 'L' has an explicit byref or byval capture of the *enclosing object* // - or, 'L' has an implicit capture. // AND // -- there is no enclosing closure // -- or, there is some enclosing closure 'E' that has already captured the // *enclosing object*, and every intervening closure (if any) between 'E' // and 'L' can implicitly capture the *enclosing object*. // -- or, every enclosing closure can implicitly capture the // *enclosing object* unsigned NumCapturingClosures = 0; for (int idx = MaxFunctionScopesIndex; idx >= 0; idx--) { if (CapturingScopeInfo *CSI = dyn_cast(FunctionScopes[idx])) { if (CSI->CXXThisCaptureIndex != 0) { // 'this' is already being captured; there isn't anything more to do. CSI->Captures[CSI->CXXThisCaptureIndex - 1].markUsed(BuildAndDiagnose); break; } LambdaScopeInfo *LSI = dyn_cast(CSI); if (LSI && isGenericLambdaCallOperatorSpecialization(LSI->CallOperator)) { // This context can't implicitly capture 'this'; fail out. if (BuildAndDiagnose) Diag(Loc, diag::err_this_capture) << (Explicit && idx == MaxFunctionScopesIndex); return true; } if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref || CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval || CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block || CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_CapturedRegion || (Explicit && idx == MaxFunctionScopesIndex)) { // Regarding (Explicit && idx == MaxFunctionScopesIndex): only the first // iteration through can be an explicit capture, all enclosing closures, // if any, must perform implicit captures. // This closure can capture 'this'; continue looking upwards. NumCapturingClosures++; continue; } // This context can't implicitly capture 'this'; fail out. if (BuildAndDiagnose) Diag(Loc, diag::err_this_capture) << (Explicit && idx == MaxFunctionScopesIndex); return true; } break; } if (!BuildAndDiagnose) return false; // If we got here, then the closure at MaxFunctionScopesIndex on the // FunctionScopes stack, can capture the *enclosing object*, so capture it // (including implicit by-reference captures in any enclosing closures). // In the loop below, respect the ByCopy flag only for the closure requesting // the capture (i.e. first iteration through the loop below). Ignore it for // all enclosing closure's up to NumCapturingClosures (since they must be // implicitly capturing the *enclosing object* by reference (see loop // above)). assert((!ByCopy || dyn_cast(FunctionScopes[MaxFunctionScopesIndex])) && "Only a lambda can capture the enclosing object (referred to by " "*this) by copy"); QualType ThisTy = getCurrentThisType(); for (int idx = MaxFunctionScopesIndex; NumCapturingClosures; --idx, --NumCapturingClosures) { CapturingScopeInfo *CSI = cast(FunctionScopes[idx]); // The type of the corresponding data member (not a 'this' pointer if 'by // copy'). QualType CaptureType = ThisTy; if (ByCopy) { // If we are capturing the object referred to by '*this' by copy, ignore // any cv qualifiers inherited from the type of the member function for // the type of the closure-type's corresponding data member and any use // of 'this'. CaptureType = ThisTy->getPointeeType(); CaptureType.removeLocalCVRQualifiers(Qualifiers::CVRMask); } bool isNested = NumCapturingClosures > 1; CSI->addThisCapture(isNested, Loc, CaptureType, ByCopy); } return false; } ExprResult Sema::ActOnCXXThis(SourceLocation Loc) { /// C++ 9.3.2: In the body of a non-static member function, the keyword this /// is a non-lvalue expression whose value is the address of the object for /// which the function is called. QualType ThisTy = getCurrentThisType(); if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use); return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false); } Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit) { auto *This = new (Context) CXXThisExpr(Loc, Type, IsImplicit); MarkThisReferenced(This); return This; } void Sema::MarkThisReferenced(CXXThisExpr *This) { CheckCXXThisCapture(This->getExprLoc()); } bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) { // If we're outside the body of a member function, then we'll have a specified // type for 'this'. if (CXXThisTypeOverride.isNull()) return false; // Determine whether we're looking into a class that's currently being // defined. CXXRecordDecl *Class = BaseType->getAsCXXRecordDecl(); return Class && Class->isBeingDefined(); } /// Parse construction of a specified type. /// Can be interpreted either as function-style casting ("int(x)") /// or class type construction ("ClassType(x,y,z)") /// or creation of a value-initialized type ("int()"). ExprResult Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep, SourceLocation LParenOrBraceLoc, MultiExprArg exprs, SourceLocation RParenOrBraceLoc, bool ListInitialization) { if (!TypeRep) return ExprError(); TypeSourceInfo *TInfo; QualType Ty = GetTypeFromParser(TypeRep, &TInfo); if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation()); auto Result = BuildCXXTypeConstructExpr(TInfo, LParenOrBraceLoc, exprs, RParenOrBraceLoc, ListInitialization); // Avoid creating a non-type-dependent expression that contains typos. // Non-type-dependent expressions are liable to be discarded without // checking for embedded typos. if (!Result.isInvalid() && Result.get()->isInstantiationDependent() && !Result.get()->isTypeDependent()) Result = CorrectDelayedTyposInExpr(Result.get()); return Result; } ExprResult Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, SourceLocation LParenOrBraceLoc, MultiExprArg Exprs, SourceLocation RParenOrBraceLoc, bool ListInitialization) { QualType Ty = TInfo->getType(); SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc(); if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) { // FIXME: CXXUnresolvedConstructExpr does not model list-initialization // directly. We work around this by dropping the locations of the braces. SourceRange Locs = ListInitialization ? SourceRange() : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc); return CXXUnresolvedConstructExpr::Create(Context, TInfo, Locs.getBegin(), Exprs, Locs.getEnd()); } assert((!ListInitialization || (Exprs.size() == 1 && isa(Exprs[0]))) && "List initialization must have initializer list as expression."); SourceRange FullRange = SourceRange(TyBeginLoc, RParenOrBraceLoc); InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo); InitializationKind Kind = Exprs.size() ? ListInitialization ? InitializationKind::CreateDirectList( TyBeginLoc, LParenOrBraceLoc, RParenOrBraceLoc) : InitializationKind::CreateDirect(TyBeginLoc, LParenOrBraceLoc, RParenOrBraceLoc) : InitializationKind::CreateValue(TyBeginLoc, LParenOrBraceLoc, RParenOrBraceLoc); // C++1z [expr.type.conv]p1: // If the type is a placeholder for a deduced class type, [...perform class // template argument deduction...] DeducedType *Deduced = Ty->getContainedDeducedType(); if (Deduced && isa(Deduced)) { Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity, Kind, Exprs); if (Ty.isNull()) return ExprError(); Entity = InitializedEntity::InitializeTemporary(TInfo, Ty); } // C++ [expr.type.conv]p1: // If the expression list is a parenthesized single expression, the type // conversion expression is equivalent (in definedness, and if defined in // meaning) to the corresponding cast expression. if (Exprs.size() == 1 && !ListInitialization && !isa(Exprs[0])) { Expr *Arg = Exprs[0]; return BuildCXXFunctionalCastExpr(TInfo, Ty, LParenOrBraceLoc, Arg, RParenOrBraceLoc); } // For an expression of the form T(), T shall not be an array type. QualType ElemTy = Ty; if (Ty->isArrayType()) { if (!ListInitialization) return ExprError(Diag(TyBeginLoc, diag::err_value_init_for_array_type) << FullRange); ElemTy = Context.getBaseElementType(Ty); } // There doesn't seem to be an explicit rule against this but sanity demands // we only construct objects with object types. if (Ty->isFunctionType()) return ExprError(Diag(TyBeginLoc, diag::err_init_for_function_type) << Ty << FullRange); // C++17 [expr.type.conv]p2: // If the type is cv void and the initializer is (), the expression is a // prvalue of the specified type that performs no initialization. if (!Ty->isVoidType() && RequireCompleteType(TyBeginLoc, ElemTy, diag::err_invalid_incomplete_type_use, FullRange)) return ExprError(); // Otherwise, the expression is a prvalue of the specified type whose // result object is direct-initialized (11.6) with the initializer. InitializationSequence InitSeq(*this, Entity, Kind, Exprs); ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Exprs); if (Result.isInvalid()) return Result; Expr *Inner = Result.get(); if (CXXBindTemporaryExpr *BTE = dyn_cast_or_null(Inner)) Inner = BTE->getSubExpr(); if (!isa(Inner) && !isa(Inner)) { // If we created a CXXTemporaryObjectExpr, that node also represents the // functional cast. Otherwise, create an explicit cast to represent // the syntactic form of a functional-style cast that was used here. // // FIXME: Creating a CXXFunctionalCastExpr around a CXXConstructExpr // would give a more consistent AST representation than using a // CXXTemporaryObjectExpr. It's also weird that the functional cast // is sometimes handled by initialization and sometimes not. QualType ResultType = Result.get()->getType(); SourceRange Locs = ListInitialization ? SourceRange() : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc); Result = CXXFunctionalCastExpr::Create( Context, ResultType, Expr::getValueKindForType(Ty), TInfo, CK_NoOp, Result.get(), /*Path=*/nullptr, Locs.getBegin(), Locs.getEnd()); } return Result; } bool Sema::isUsualDeallocationFunction(const CXXMethodDecl *Method) { // [CUDA] Ignore this function, if we can't call it. const FunctionDecl *Caller = dyn_cast(CurContext); if (getLangOpts().CUDA && IdentifyCUDAPreference(Caller, Method) <= CFP_WrongSide) return false; SmallVector PreventedBy; bool Result = Method->isUsualDeallocationFunction(PreventedBy); if (Result || !getLangOpts().CUDA || PreventedBy.empty()) return Result; // In case of CUDA, return true if none of the 1-argument deallocator // functions are actually callable. return llvm::none_of(PreventedBy, [&](const FunctionDecl *FD) { assert(FD->getNumParams() == 1 && "Only single-operand functions should be in PreventedBy"); return IdentifyCUDAPreference(Caller, FD) >= CFP_HostDevice; }); } /// Determine whether the given function is a non-placement /// deallocation function. static bool isNonPlacementDeallocationFunction(Sema &S, FunctionDecl *FD) { if (CXXMethodDecl *Method = dyn_cast(FD)) return S.isUsualDeallocationFunction(Method); if (FD->getOverloadedOperator() != OO_Delete && FD->getOverloadedOperator() != OO_Array_Delete) return false; unsigned UsualParams = 1; if (S.getLangOpts().SizedDeallocation && UsualParams < FD->getNumParams() && S.Context.hasSameUnqualifiedType( FD->getParamDecl(UsualParams)->getType(), S.Context.getSizeType())) ++UsualParams; if (S.getLangOpts().AlignedAllocation && UsualParams < FD->getNumParams() && S.Context.hasSameUnqualifiedType( FD->getParamDecl(UsualParams)->getType(), S.Context.getTypeDeclType(S.getStdAlignValT()))) ++UsualParams; return UsualParams == FD->getNumParams(); } namespace { struct UsualDeallocFnInfo { UsualDeallocFnInfo() : Found(), FD(nullptr) {} UsualDeallocFnInfo(Sema &S, DeclAccessPair Found) : Found(Found), FD(dyn_cast(Found->getUnderlyingDecl())), Destroying(false), HasSizeT(false), HasAlignValT(false), CUDAPref(Sema::CFP_Native) { // A function template declaration is never a usual deallocation function. if (!FD) return; unsigned NumBaseParams = 1; if (FD->isDestroyingOperatorDelete()) { Destroying = true; ++NumBaseParams; } if (NumBaseParams < FD->getNumParams() && S.Context.hasSameUnqualifiedType( FD->getParamDecl(NumBaseParams)->getType(), S.Context.getSizeType())) { ++NumBaseParams; HasSizeT = true; } if (NumBaseParams < FD->getNumParams() && FD->getParamDecl(NumBaseParams)->getType()->isAlignValT()) { ++NumBaseParams; HasAlignValT = true; } // In CUDA, determine how much we'd like / dislike to call this. if (S.getLangOpts().CUDA) if (auto *Caller = dyn_cast(S.CurContext)) CUDAPref = S.IdentifyCUDAPreference(Caller, FD); } explicit operator bool() const { return FD; } bool isBetterThan(const UsualDeallocFnInfo &Other, bool WantSize, bool WantAlign) const { // C++ P0722: // A destroying operator delete is preferred over a non-destroying // operator delete. if (Destroying != Other.Destroying) return Destroying; // C++17 [expr.delete]p10: // If the type has new-extended alignment, a function with a parameter // of type std::align_val_t is preferred; otherwise a function without // such a parameter is preferred if (HasAlignValT != Other.HasAlignValT) return HasAlignValT == WantAlign; if (HasSizeT != Other.HasSizeT) return HasSizeT == WantSize; // Use CUDA call preference as a tiebreaker. return CUDAPref > Other.CUDAPref; } DeclAccessPair Found; FunctionDecl *FD; bool Destroying, HasSizeT, HasAlignValT; Sema::CUDAFunctionPreference CUDAPref; }; } /// Determine whether a type has new-extended alignment. This may be called when /// the type is incomplete (for a delete-expression with an incomplete pointee /// type), in which case it will conservatively return false if the alignment is /// not known. static bool hasNewExtendedAlignment(Sema &S, QualType AllocType) { return S.getLangOpts().AlignedAllocation && S.getASTContext().getTypeAlignIfKnown(AllocType) > S.getASTContext().getTargetInfo().getNewAlign(); } /// Select the correct "usual" deallocation function to use from a selection of /// deallocation functions (either global or class-scope). static UsualDeallocFnInfo resolveDeallocationOverload( Sema &S, LookupResult &R, bool WantSize, bool WantAlign, llvm::SmallVectorImpl *BestFns = nullptr) { UsualDeallocFnInfo Best; for (auto I = R.begin(), E = R.end(); I != E; ++I) { UsualDeallocFnInfo Info(S, I.getPair()); if (!Info || !isNonPlacementDeallocationFunction(S, Info.FD) || Info.CUDAPref == Sema::CFP_Never) continue; if (!Best) { Best = Info; if (BestFns) BestFns->push_back(Info); continue; } if (Best.isBetterThan(Info, WantSize, WantAlign)) continue; // If more than one preferred function is found, all non-preferred // functions are eliminated from further consideration. if (BestFns && Info.isBetterThan(Best, WantSize, WantAlign)) BestFns->clear(); Best = Info; if (BestFns) BestFns->push_back(Info); } return Best; } /// Determine whether a given type is a class for which 'delete[]' would call /// a member 'operator delete[]' with a 'size_t' parameter. This implies that /// we need to store the array size (even if the type is /// trivially-destructible). static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc, QualType allocType) { const RecordType *record = allocType->getBaseElementTypeUnsafe()->getAs(); if (!record) return false; // Try to find an operator delete[] in class scope. DeclarationName deleteName = S.Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete); LookupResult ops(S, deleteName, loc, Sema::LookupOrdinaryName); S.LookupQualifiedName(ops, record->getDecl()); // We're just doing this for information. ops.suppressDiagnostics(); // Very likely: there's no operator delete[]. if (ops.empty()) return false; // If it's ambiguous, it should be illegal to call operator delete[] // on this thing, so it doesn't matter if we allocate extra space or not. if (ops.isAmbiguous()) return false; // C++17 [expr.delete]p10: // If the deallocation functions have class scope, the one without a // parameter of type std::size_t is selected. auto Best = resolveDeallocationOverload( S, ops, /*WantSize*/false, /*WantAlign*/hasNewExtendedAlignment(S, allocType)); return Best && Best.HasSizeT; } /// Parsed a C++ 'new' expression (C++ 5.3.4). /// /// E.g.: /// @code new (memory) int[size][4] @endcode /// or /// @code ::new Foo(23, "hello") @endcode /// /// \param StartLoc The first location of the expression. /// \param UseGlobal True if 'new' was prefixed with '::'. /// \param PlacementLParen Opening paren of the placement arguments. /// \param PlacementArgs Placement new arguments. /// \param PlacementRParen Closing paren of the placement arguments. /// \param TypeIdParens If the type is in parens, the source range. /// \param D The type to be allocated, as well as array dimensions. /// \param Initializer The initializing expression or initializer-list, or null /// if there is none. ExprResult Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, Declarator &D, Expr *Initializer) { Optional ArraySize; // If the specified type is an array, unwrap it and save the expression. if (D.getNumTypeObjects() > 0 && D.getTypeObject(0).Kind == DeclaratorChunk::Array) { DeclaratorChunk &Chunk = D.getTypeObject(0); if (D.getDeclSpec().hasAutoTypeSpec()) return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto) << D.getSourceRange()); if (Chunk.Arr.hasStatic) return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new) << D.getSourceRange()); if (!Chunk.Arr.NumElts && !Initializer) return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size) << D.getSourceRange()); ArraySize = static_cast(Chunk.Arr.NumElts); D.DropFirstTypeObject(); } // Every dimension shall be of constant size. if (ArraySize) { for (unsigned I = 0, N = D.getNumTypeObjects(); I < N; ++I) { if (D.getTypeObject(I).Kind != DeclaratorChunk::Array) break; DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr; if (Expr *NumElts = (Expr *)Array.NumElts) { if (!NumElts->isTypeDependent() && !NumElts->isValueDependent()) { if (getLangOpts().CPlusPlus14) { // C++1y [expr.new]p6: Every constant-expression in a noptr-new-declarator // shall be a converted constant expression (5.19) of type std::size_t // and shall evaluate to a strictly positive value. unsigned IntWidth = Context.getTargetInfo().getIntWidth(); assert(IntWidth && "Builtin type of size 0?"); llvm::APSInt Value(IntWidth); Array.NumElts = CheckConvertedConstantExpression(NumElts, Context.getSizeType(), Value, CCEK_NewExpr) .get(); } else { Array.NumElts = VerifyIntegerConstantExpression(NumElts, nullptr, diag::err_new_array_nonconst) .get(); } if (!Array.NumElts) return ExprError(); } } } } TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/nullptr); QualType AllocType = TInfo->getType(); if (D.isInvalidType()) return ExprError(); SourceRange DirectInitRange; if (ParenListExpr *List = dyn_cast_or_null(Initializer)) DirectInitRange = List->getSourceRange(); return BuildCXXNew(SourceRange(StartLoc, D.getEndLoc()), UseGlobal, PlacementLParen, PlacementArgs, PlacementRParen, TypeIdParens, AllocType, TInfo, ArraySize, DirectInitRange, Initializer); } static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style, Expr *Init) { if (!Init) return true; if (ParenListExpr *PLE = dyn_cast(Init)) return PLE->getNumExprs() == 0; if (isa(Init)) return true; else if (CXXConstructExpr *CCE = dyn_cast(Init)) return !CCE->isListInitialization() && CCE->getConstructor()->isDefaultConstructor(); else if (Style == CXXNewExpr::ListInit) { assert(isa(Init) && "Shouldn't create list CXXConstructExprs for arrays."); return true; } return false; } bool Sema::isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const { if (!getLangOpts().AlignedAllocationUnavailable) return false; if (FD.isDefined()) return false; bool IsAligned = false; if (FD.isReplaceableGlobalAllocationFunction(&IsAligned) && IsAligned) return true; return false; } // Emit a diagnostic if an aligned allocation/deallocation function that is not // implemented in the standard library is selected. void Sema::diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD, SourceLocation Loc) { if (isUnavailableAlignedAllocationFunction(FD)) { const llvm::Triple &T = getASTContext().getTargetInfo().getTriple(); StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling( getASTContext().getTargetInfo().getPlatformName()); OverloadedOperatorKind Kind = FD.getDeclName().getCXXOverloadedOperator(); bool IsDelete = Kind == OO_Delete || Kind == OO_Array_Delete; Diag(Loc, diag::err_aligned_allocation_unavailable) << IsDelete << FD.getType().getAsString() << OSName << alignedAllocMinVersion(T.getOS()).getAsString(); Diag(Loc, diag::note_silence_aligned_allocation_unavailable); } } ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, QualType AllocType, TypeSourceInfo *AllocTypeInfo, Optional ArraySize, SourceRange DirectInitRange, Expr *Initializer) { SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange(); SourceLocation StartLoc = Range.getBegin(); CXXNewExpr::InitializationStyle initStyle; if (DirectInitRange.isValid()) { assert(Initializer && "Have parens but no initializer."); initStyle = CXXNewExpr::CallInit; } else if (Initializer && isa(Initializer)) initStyle = CXXNewExpr::ListInit; else { assert((!Initializer || isa(Initializer) || isa(Initializer)) && "Initializer expression that cannot have been implicitly created."); initStyle = CXXNewExpr::NoInit; } Expr **Inits = &Initializer; unsigned NumInits = Initializer ? 1 : 0; if (ParenListExpr *List = dyn_cast_or_null(Initializer)) { assert(initStyle == CXXNewExpr::CallInit && "paren init for non-call init"); Inits = List->getExprs(); NumInits = List->getNumExprs(); } // C++11 [expr.new]p15: // A new-expression that creates an object of type T initializes that // object as follows: InitializationKind Kind // - If the new-initializer is omitted, the object is default- // initialized (8.5); if no initialization is performed, // the object has indeterminate value = initStyle == CXXNewExpr::NoInit ? InitializationKind::CreateDefault(TypeRange.getBegin()) // - Otherwise, the new-initializer is interpreted according to // the // initialization rules of 8.5 for direct-initialization. : initStyle == CXXNewExpr::ListInit ? InitializationKind::CreateDirectList( TypeRange.getBegin(), Initializer->getBeginLoc(), Initializer->getEndLoc()) : InitializationKind::CreateDirect(TypeRange.getBegin(), DirectInitRange.getBegin(), DirectInitRange.getEnd()); // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for. auto *Deduced = AllocType->getContainedDeducedType(); if (Deduced && isa(Deduced)) { if (ArraySize) return ExprError( Diag(ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(), diag::err_deduced_class_template_compound_type) << /*array*/ 2 << (ArraySize ? (*ArraySize)->getSourceRange() : TypeRange)); InitializedEntity Entity = InitializedEntity::InitializeNew(StartLoc, AllocType); AllocType = DeduceTemplateSpecializationFromInitializer( AllocTypeInfo, Entity, Kind, MultiExprArg(Inits, NumInits)); if (AllocType.isNull()) return ExprError(); } else if (Deduced) { bool Braced = (initStyle == CXXNewExpr::ListInit); if (NumInits == 1) { if (auto p = dyn_cast_or_null(Inits[0])) { Inits = p->getInits(); NumInits = p->getNumInits(); Braced = true; } } if (initStyle == CXXNewExpr::NoInit || NumInits == 0) return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg) << AllocType << TypeRange); if (NumInits > 1) { Expr *FirstBad = Inits[1]; return ExprError(Diag(FirstBad->getBeginLoc(), diag::err_auto_new_ctor_multiple_expressions) << AllocType << TypeRange); } if (Braced && !getLangOpts().CPlusPlus17) Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init) << AllocType << TypeRange; Expr *Deduce = Inits[0]; QualType DeducedType; if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed) return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure) << AllocType << Deduce->getType() << TypeRange << Deduce->getSourceRange()); if (DeducedType.isNull()) return ExprError(); AllocType = DeducedType; } // Per C++0x [expr.new]p5, the type being constructed may be a // typedef of an array type. if (!ArraySize) { if (const ConstantArrayType *Array = Context.getAsConstantArrayType(AllocType)) { ArraySize = IntegerLiteral::Create(Context, Array->getSize(), Context.getSizeType(), TypeRange.getEnd()); AllocType = Array->getElementType(); } } if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange)) return ExprError(); // In ARC, infer 'retaining' for the allocated if (getLangOpts().ObjCAutoRefCount && AllocType.getObjCLifetime() == Qualifiers::OCL_None && AllocType->isObjCLifetimeType()) { AllocType = Context.getLifetimeQualifiedType(AllocType, AllocType->getObjCARCImplicitLifetime()); } QualType ResultType = Context.getPointerType(AllocType); if (ArraySize && *ArraySize && (*ArraySize)->getType()->isNonOverloadPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(*ArraySize); if (result.isInvalid()) return ExprError(); ArraySize = result.get(); } // C++98 5.3.4p6: "The expression in a direct-new-declarator shall have // integral or enumeration type with a non-negative value." // C++11 [expr.new]p6: The expression [...] shall be of integral or unscoped // enumeration type, or a class type for which a single non-explicit // conversion function to integral or unscoped enumeration type exists. // C++1y [expr.new]p6: The expression [...] is implicitly converted to // std::size_t. llvm::Optional KnownArraySize; if (ArraySize && *ArraySize && !(*ArraySize)->isTypeDependent()) { ExprResult ConvertedSize; if (getLangOpts().CPlusPlus14) { assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?"); ConvertedSize = PerformImplicitConversion(*ArraySize, Context.getSizeType(), AA_Converting); if (!ConvertedSize.isInvalid() && (*ArraySize)->getType()->getAs()) // Diagnose the compatibility of this conversion. Diag(StartLoc, diag::warn_cxx98_compat_array_size_conversion) << (*ArraySize)->getType() << 0 << "'size_t'"; } else { class SizeConvertDiagnoser : public ICEConvertDiagnoser { protected: Expr *ArraySize; public: SizeConvertDiagnoser(Expr *ArraySize) : ICEConvertDiagnoser(/*AllowScopedEnumerations*/false, false, false), ArraySize(ArraySize) {} SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_array_size_not_integral) << S.getLangOpts().CPlusPlus11 << T; } SemaDiagnosticBuilder diagnoseIncomplete( Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_array_size_incomplete_type) << T << ArraySize->getSourceRange(); } SemaDiagnosticBuilder diagnoseExplicitConv( Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { return S.Diag(Loc, diag::err_array_size_explicit_conversion) << T << ConvTy; } SemaDiagnosticBuilder noteExplicitConv( Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_array_size_conversion) << ConvTy->isEnumeralType() << ConvTy; } SemaDiagnosticBuilder diagnoseAmbiguous( Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_array_size_ambiguous_conversion) << T; } SemaDiagnosticBuilder noteAmbiguous( Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_array_size_conversion) << ConvTy->isEnumeralType() << ConvTy; } SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { return S.Diag(Loc, S.getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_array_size_conversion : diag::ext_array_size_conversion) << T << ConvTy->isEnumeralType() << ConvTy; } } SizeDiagnoser(*ArraySize); ConvertedSize = PerformContextualImplicitConversion(StartLoc, *ArraySize, SizeDiagnoser); } if (ConvertedSize.isInvalid()) return ExprError(); ArraySize = ConvertedSize.get(); QualType SizeType = (*ArraySize)->getType(); if (!SizeType->isIntegralOrUnscopedEnumerationType()) return ExprError(); // C++98 [expr.new]p7: // The expression in a direct-new-declarator shall have integral type // with a non-negative value. // // Let's see if this is a constant < 0. If so, we reject it out of hand, // per CWG1464. Otherwise, if it's not a constant, we must have an // unparenthesized array type. if (!(*ArraySize)->isValueDependent()) { llvm::APSInt Value; // We've already performed any required implicit conversion to integer or // unscoped enumeration type. // FIXME: Per CWG1464, we are required to check the value prior to // converting to size_t. This will never find a negative array size in // C++14 onwards, because Value is always unsigned here! if ((*ArraySize)->isIntegerConstantExpr(Value, Context)) { if (Value.isSigned() && Value.isNegative()) { return ExprError(Diag((*ArraySize)->getBeginLoc(), diag::err_typecheck_negative_array_size) << (*ArraySize)->getSourceRange()); } if (!AllocType->isDependentType()) { unsigned ActiveSizeBits = ConstantArrayType::getNumAddressingBits(Context, AllocType, Value); if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) return ExprError( Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large) << Value.toString(10) << (*ArraySize)->getSourceRange()); } KnownArraySize = Value.getZExtValue(); } else if (TypeIdParens.isValid()) { // Can't have dynamic array size when the type-id is in parentheses. Diag((*ArraySize)->getBeginLoc(), diag::ext_new_paren_array_nonconst) << (*ArraySize)->getSourceRange() << FixItHint::CreateRemoval(TypeIdParens.getBegin()) << FixItHint::CreateRemoval(TypeIdParens.getEnd()); TypeIdParens = SourceRange(); } } // Note that we do *not* convert the argument in any way. It can // be signed, larger than size_t, whatever. } FunctionDecl *OperatorNew = nullptr; FunctionDecl *OperatorDelete = nullptr; unsigned Alignment = AllocType->isDependentType() ? 0 : Context.getTypeAlign(AllocType); unsigned NewAlignment = Context.getTargetInfo().getNewAlign(); bool PassAlignment = getLangOpts().AlignedAllocation && Alignment > NewAlignment; AllocationFunctionScope Scope = UseGlobal ? AFS_Global : AFS_Both; if (!AllocType->isDependentType() && !Expr::hasAnyTypeDependentArguments(PlacementArgs) && FindAllocationFunctions( StartLoc, SourceRange(PlacementLParen, PlacementRParen), Scope, Scope, AllocType, ArraySize.hasValue(), PassAlignment, PlacementArgs, OperatorNew, OperatorDelete)) return ExprError(); // If this is an array allocation, compute whether the usual array // deallocation function for the type has a size_t parameter. bool UsualArrayDeleteWantsSize = false; if (ArraySize && !AllocType->isDependentType()) UsualArrayDeleteWantsSize = doesUsualArrayDeleteWantSize(*this, StartLoc, AllocType); SmallVector AllPlaceArgs; if (OperatorNew) { const FunctionProtoType *Proto = OperatorNew->getType()->getAs(); VariadicCallType CallType = Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply; // We've already converted the placement args, just fill in any default // arguments. Skip the first parameter because we don't have a corresponding // argument. Skip the second parameter too if we're passing in the // alignment; we've already filled it in. if (GatherArgumentsForCall(PlacementLParen, OperatorNew, Proto, PassAlignment ? 2 : 1, PlacementArgs, AllPlaceArgs, CallType)) return ExprError(); if (!AllPlaceArgs.empty()) PlacementArgs = AllPlaceArgs; // FIXME: This is wrong: PlacementArgs misses out the first (size) argument. DiagnoseSentinelCalls(OperatorNew, PlacementLParen, PlacementArgs); // FIXME: Missing call to CheckFunctionCall or equivalent // Warn if the type is over-aligned and is being allocated by (unaligned) // global operator new. if (PlacementArgs.empty() && !PassAlignment && (OperatorNew->isImplicit() || (OperatorNew->getBeginLoc().isValid() && getSourceManager().isInSystemHeader(OperatorNew->getBeginLoc())))) { if (Alignment > NewAlignment) Diag(StartLoc, diag::warn_overaligned_type) << AllocType << unsigned(Alignment / Context.getCharWidth()) << unsigned(NewAlignment / Context.getCharWidth()); } } // Array 'new' can't have any initializers except empty parentheses. // Initializer lists are also allowed, in C++11. Rely on the parser for the // dialect distinction. if (ArraySize && !isLegalArrayNewInitializer(initStyle, Initializer)) { SourceRange InitRange(Inits[0]->getBeginLoc(), Inits[NumInits - 1]->getEndLoc()); Diag(StartLoc, diag::err_new_array_init_args) << InitRange; return ExprError(); } // If we can perform the initialization, and we've not already done so, // do it now. if (!AllocType->isDependentType() && !Expr::hasAnyTypeDependentArguments( llvm::makeArrayRef(Inits, NumInits))) { // The type we initialize is the complete type, including the array bound. QualType InitType; if (KnownArraySize) InitType = Context.getConstantArrayType( AllocType, llvm::APInt(Context.getTypeSize(Context.getSizeType()), *KnownArraySize), *ArraySize, ArrayType::Normal, 0); else if (ArraySize) InitType = Context.getIncompleteArrayType(AllocType, ArrayType::Normal, 0); else InitType = AllocType; InitializedEntity Entity = InitializedEntity::InitializeNew(StartLoc, InitType); InitializationSequence InitSeq(*this, Entity, Kind, MultiExprArg(Inits, NumInits)); ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, MultiExprArg(Inits, NumInits)); if (FullInit.isInvalid()) return ExprError(); // FullInit is our initializer; strip off CXXBindTemporaryExprs, because // we don't want the initialized object to be destructed. // FIXME: We should not create these in the first place. if (CXXBindTemporaryExpr *Binder = dyn_cast_or_null(FullInit.get())) FullInit = Binder->getSubExpr(); Initializer = FullInit.get(); // FIXME: If we have a KnownArraySize, check that the array bound of the // initializer is no greater than that constant value. if (ArraySize && !*ArraySize) { auto *CAT = Context.getAsConstantArrayType(Initializer->getType()); if (CAT) { // FIXME: Track that the array size was inferred rather than explicitly // specified. ArraySize = IntegerLiteral::Create( Context, CAT->getSize(), Context.getSizeType(), TypeRange.getEnd()); } else { Diag(TypeRange.getEnd(), diag::err_new_array_size_unknown_from_init) << Initializer->getSourceRange(); } } } // Mark the new and delete operators as referenced. if (OperatorNew) { if (DiagnoseUseOfDecl(OperatorNew, StartLoc)) return ExprError(); MarkFunctionReferenced(StartLoc, OperatorNew); } if (OperatorDelete) { if (DiagnoseUseOfDecl(OperatorDelete, StartLoc)) return ExprError(); MarkFunctionReferenced(StartLoc, OperatorDelete); } return CXXNewExpr::Create(Context, UseGlobal, OperatorNew, OperatorDelete, PassAlignment, UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens, ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo, Range, DirectInitRange); } /// Checks that a type is suitable as the allocated type /// in a new-expression. bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc, SourceRange R) { // C++ 5.3.4p1: "[The] type shall be a complete object type, but not an // abstract class type or array thereof. if (AllocType->isFunctionType()) return Diag(Loc, diag::err_bad_new_type) << AllocType << 0 << R; else if (AllocType->isReferenceType()) return Diag(Loc, diag::err_bad_new_type) << AllocType << 1 << R; else if (!AllocType->isDependentType() && RequireCompleteType(Loc, AllocType, diag::err_new_incomplete_type,R)) return true; else if (RequireNonAbstractType(Loc, AllocType, diag::err_allocation_of_abstract_type)) return true; else if (AllocType->isVariablyModifiedType()) return Diag(Loc, diag::err_variably_modified_new_type) << AllocType; else if (AllocType.getAddressSpace() != LangAS::Default && !getLangOpts().OpenCLCPlusPlus) return Diag(Loc, diag::err_address_space_qualified_new) << AllocType.getUnqualifiedType() << AllocType.getQualifiers().getAddressSpaceAttributePrintValue(); else if (getLangOpts().ObjCAutoRefCount) { if (const ArrayType *AT = Context.getAsArrayType(AllocType)) { QualType BaseAllocType = Context.getBaseElementType(AT); if (BaseAllocType.getObjCLifetime() == Qualifiers::OCL_None && BaseAllocType->isObjCLifetimeType()) return Diag(Loc, diag::err_arc_new_array_without_ownership) << BaseAllocType; } } return false; } static bool resolveAllocationOverload( Sema &S, LookupResult &R, SourceRange Range, SmallVectorImpl &Args, bool &PassAlignment, FunctionDecl *&Operator, OverloadCandidateSet *AlignedCandidates, Expr *AlignArg, bool Diagnose) { OverloadCandidateSet Candidates(R.getNameLoc(), OverloadCandidateSet::CSK_Normal); for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end(); Alloc != AllocEnd; ++Alloc) { // Even member operator new/delete are implicitly treated as // static, so don't use AddMemberCandidate. NamedDecl *D = (*Alloc)->getUnderlyingDecl(); if (FunctionTemplateDecl *FnTemplate = dyn_cast(D)) { S.AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(), /*ExplicitTemplateArgs=*/nullptr, Args, Candidates, /*SuppressUserConversions=*/false); continue; } FunctionDecl *Fn = cast(D); S.AddOverloadCandidate(Fn, Alloc.getPair(), Args, Candidates, /*SuppressUserConversions=*/false); } // Do the resolution. OverloadCandidateSet::iterator Best; switch (Candidates.BestViableFunction(S, R.getNameLoc(), Best)) { case OR_Success: { // Got one! FunctionDecl *FnDecl = Best->Function; if (S.CheckAllocationAccess(R.getNameLoc(), Range, R.getNamingClass(), Best->FoundDecl) == Sema::AR_inaccessible) return true; Operator = FnDecl; return false; } case OR_No_Viable_Function: // C++17 [expr.new]p13: // If no matching function is found and the allocated object type has // new-extended alignment, the alignment argument is removed from the // argument list, and overload resolution is performed again. if (PassAlignment) { PassAlignment = false; AlignArg = Args[1]; Args.erase(Args.begin() + 1); return resolveAllocationOverload(S, R, Range, Args, PassAlignment, Operator, &Candidates, AlignArg, Diagnose); } // MSVC will fall back on trying to find a matching global operator new // if operator new[] cannot be found. Also, MSVC will leak by not // generating a call to operator delete or operator delete[], but we // will not replicate that bug. // FIXME: Find out how this interacts with the std::align_val_t fallback // once MSVC implements it. if (R.getLookupName().getCXXOverloadedOperator() == OO_Array_New && S.Context.getLangOpts().MSVCCompat) { R.clear(); R.setLookupName(S.Context.DeclarationNames.getCXXOperatorName(OO_New)); S.LookupQualifiedName(R, S.Context.getTranslationUnitDecl()); // FIXME: This will give bad diagnostics pointing at the wrong functions. return resolveAllocationOverload(S, R, Range, Args, PassAlignment, Operator, /*Candidates=*/nullptr, /*AlignArg=*/nullptr, Diagnose); } if (Diagnose) { PartialDiagnosticAt PD(R.getNameLoc(), S.PDiag(diag::err_ovl_no_viable_function_in_call) << R.getLookupName() << Range); // If we have aligned candidates, only note the align_val_t candidates // from AlignedCandidates and the non-align_val_t candidates from // Candidates. if (AlignedCandidates) { auto IsAligned = [](OverloadCandidate &C) { return C.Function->getNumParams() > 1 && C.Function->getParamDecl(1)->getType()->isAlignValT(); }; auto IsUnaligned = [&](OverloadCandidate &C) { return !IsAligned(C); }; // This was an overaligned allocation, so list the aligned candidates // first. Args.insert(Args.begin() + 1, AlignArg); AlignedCandidates->NoteCandidates(PD, S, OCD_AllCandidates, Args, "", R.getNameLoc(), IsAligned); Args.erase(Args.begin() + 1); Candidates.NoteCandidates(PD, S, OCD_AllCandidates, Args, "", R.getNameLoc(), IsUnaligned); } else { Candidates.NoteCandidates(PD, S, OCD_AllCandidates, Args); } } return true; case OR_Ambiguous: if (Diagnose) { Candidates.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_ambiguous_call) << R.getLookupName() << Range), S, OCD_AmbiguousCandidates, Args); } return true; case OR_Deleted: { if (Diagnose) { Candidates.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_deleted_call) << R.getLookupName() << Range), S, OCD_AllCandidates, Args); } return true; } } llvm_unreachable("Unreachable, bad result from BestViableFunction"); } bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, AllocationFunctionScope NewScope, AllocationFunctionScope DeleteScope, QualType AllocType, bool IsArray, bool &PassAlignment, MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete, bool Diagnose) { // --- Choosing an allocation function --- // C++ 5.3.4p8 - 14 & 18 // 1) If looking in AFS_Global scope for allocation functions, only look in // the global scope. Else, if AFS_Class, only look in the scope of the // allocated class. If AFS_Both, look in both. // 2) If an array size is given, look for operator new[], else look for // operator new. // 3) The first argument is always size_t. Append the arguments from the // placement form. SmallVector AllocArgs; AllocArgs.reserve((PassAlignment ? 2 : 1) + PlaceArgs.size()); // We don't care about the actual value of these arguments. // FIXME: Should the Sema create the expression and embed it in the syntax // tree? Or should the consumer just recalculate the value? // FIXME: Using a dummy value will interact poorly with attribute enable_if. IntegerLiteral Size(Context, llvm::APInt::getNullValue( Context.getTargetInfo().getPointerWidth(0)), Context.getSizeType(), SourceLocation()); AllocArgs.push_back(&Size); QualType AlignValT = Context.VoidTy; if (PassAlignment) { DeclareGlobalNewDelete(); AlignValT = Context.getTypeDeclType(getStdAlignValT()); } CXXScalarValueInitExpr Align(AlignValT, nullptr, SourceLocation()); if (PassAlignment) AllocArgs.push_back(&Align); AllocArgs.insert(AllocArgs.end(), PlaceArgs.begin(), PlaceArgs.end()); // C++ [expr.new]p8: // If the allocated type is a non-array type, the allocation // function's name is operator new and the deallocation function's // name is operator delete. If the allocated type is an array // type, the allocation function's name is operator new[] and the // deallocation function's name is operator delete[]. DeclarationName NewName = Context.DeclarationNames.getCXXOperatorName( IsArray ? OO_Array_New : OO_New); QualType AllocElemType = Context.getBaseElementType(AllocType); // Find the allocation function. { LookupResult R(*this, NewName, StartLoc, LookupOrdinaryName); // C++1z [expr.new]p9: // If the new-expression begins with a unary :: operator, the allocation // function's name is looked up in the global scope. Otherwise, if the // allocated type is a class type T or array thereof, the allocation // function's name is looked up in the scope of T. if (AllocElemType->isRecordType() && NewScope != AFS_Global) LookupQualifiedName(R, AllocElemType->getAsCXXRecordDecl()); // We can see ambiguity here if the allocation function is found in // multiple base classes. if (R.isAmbiguous()) return true; // If this lookup fails to find the name, or if the allocated type is not // a class type, the allocation function's name is looked up in the // global scope. if (R.empty()) { if (NewScope == AFS_Class) return true; LookupQualifiedName(R, Context.getTranslationUnitDecl()); } if (getLangOpts().OpenCLCPlusPlus && R.empty()) { if (PlaceArgs.empty()) { Diag(StartLoc, diag::err_openclcxx_not_supported) << "default new"; } else { Diag(StartLoc, diag::err_openclcxx_placement_new); } return true; } assert(!R.empty() && "implicitly declared allocation functions not found"); assert(!R.isAmbiguous() && "global allocation functions are ambiguous"); // We do our own custom access checks below. R.suppressDiagnostics(); if (resolveAllocationOverload(*this, R, Range, AllocArgs, PassAlignment, OperatorNew, /*Candidates=*/nullptr, /*AlignArg=*/nullptr, Diagnose)) return true; } // We don't need an operator delete if we're running under -fno-exceptions. if (!getLangOpts().Exceptions) { OperatorDelete = nullptr; return false; } // Note, the name of OperatorNew might have been changed from array to // non-array by resolveAllocationOverload. DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName( OperatorNew->getDeclName().getCXXOverloadedOperator() == OO_Array_New ? OO_Array_Delete : OO_Delete); // C++ [expr.new]p19: // // If the new-expression begins with a unary :: operator, the // deallocation function's name is looked up in the global // scope. Otherwise, if the allocated type is a class type T or an // array thereof, the deallocation function's name is looked up in // the scope of T. If this lookup fails to find the name, or if // the allocated type is not a class type or array thereof, the // deallocation function's name is looked up in the global scope. LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName); if (AllocElemType->isRecordType() && DeleteScope != AFS_Global) { auto *RD = cast(AllocElemType->castAs()->getDecl()); LookupQualifiedName(FoundDelete, RD); } if (FoundDelete.isAmbiguous()) return true; // FIXME: clean up expressions? bool FoundGlobalDelete = FoundDelete.empty(); if (FoundDelete.empty()) { if (DeleteScope == AFS_Class) return true; DeclareGlobalNewDelete(); LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl()); } FoundDelete.suppressDiagnostics(); SmallVector, 2> Matches; // Whether we're looking for a placement operator delete is dictated // by whether we selected a placement operator new, not by whether // we had explicit placement arguments. This matters for things like // struct A { void *operator new(size_t, int = 0); ... }; // A *a = new A() // // We don't have any definition for what a "placement allocation function" // is, but we assume it's any allocation function whose // parameter-declaration-clause is anything other than (size_t). // // FIXME: Should (size_t, std::align_val_t) also be considered non-placement? // This affects whether an exception from the constructor of an overaligned // type uses the sized or non-sized form of aligned operator delete. bool isPlacementNew = !PlaceArgs.empty() || OperatorNew->param_size() != 1 || OperatorNew->isVariadic(); if (isPlacementNew) { // C++ [expr.new]p20: // A declaration of a placement deallocation function matches the // declaration of a placement allocation function if it has the // same number of parameters and, after parameter transformations // (8.3.5), all parameter types except the first are // identical. [...] // // To perform this comparison, we compute the function type that // the deallocation function should have, and use that type both // for template argument deduction and for comparison purposes. QualType ExpectedFunctionType; { const FunctionProtoType *Proto = OperatorNew->getType()->getAs(); SmallVector ArgTypes; ArgTypes.push_back(Context.VoidPtrTy); for (unsigned I = 1, N = Proto->getNumParams(); I < N; ++I) ArgTypes.push_back(Proto->getParamType(I)); FunctionProtoType::ExtProtoInfo EPI; // FIXME: This is not part of the standard's rule. EPI.Variadic = Proto->isVariadic(); ExpectedFunctionType = Context.getFunctionType(Context.VoidTy, ArgTypes, EPI); } for (LookupResult::iterator D = FoundDelete.begin(), DEnd = FoundDelete.end(); D != DEnd; ++D) { FunctionDecl *Fn = nullptr; if (FunctionTemplateDecl *FnTmpl = dyn_cast((*D)->getUnderlyingDecl())) { // Perform template argument deduction to try to match the // expected function type. TemplateDeductionInfo Info(StartLoc); if (DeduceTemplateArguments(FnTmpl, nullptr, ExpectedFunctionType, Fn, Info)) continue; } else Fn = cast((*D)->getUnderlyingDecl()); if (Context.hasSameType(adjustCCAndNoReturn(Fn->getType(), ExpectedFunctionType, /*AdjustExcpetionSpec*/true), ExpectedFunctionType)) Matches.push_back(std::make_pair(D.getPair(), Fn)); } if (getLangOpts().CUDA) EraseUnwantedCUDAMatches(dyn_cast(CurContext), Matches); } else { // C++1y [expr.new]p22: // For a non-placement allocation function, the normal deallocation // function lookup is used // // Per [expr.delete]p10, this lookup prefers a member operator delete // without a size_t argument, but prefers a non-member operator delete // with a size_t where possible (which it always is in this case). llvm::SmallVector BestDeallocFns; UsualDeallocFnInfo Selected = resolveDeallocationOverload( *this, FoundDelete, /*WantSize*/ FoundGlobalDelete, /*WantAlign*/ hasNewExtendedAlignment(*this, AllocElemType), &BestDeallocFns); if (Selected) Matches.push_back(std::make_pair(Selected.Found, Selected.FD)); else { // If we failed to select an operator, all remaining functions are viable // but ambiguous. for (auto Fn : BestDeallocFns) Matches.push_back(std::make_pair(Fn.Found, Fn.FD)); } } // C++ [expr.new]p20: // [...] If the lookup finds a single matching deallocation // function, that function will be called; otherwise, no // deallocation function will be called. if (Matches.size() == 1) { OperatorDelete = Matches[0].second; // C++1z [expr.new]p23: // If the lookup finds a usual deallocation function (3.7.4.2) // with a parameter of type std::size_t and that function, considered // as a placement deallocation function, would have been // selected as a match for the allocation function, the program // is ill-formed. if (getLangOpts().CPlusPlus11 && isPlacementNew && isNonPlacementDeallocationFunction(*this, OperatorDelete)) { UsualDeallocFnInfo Info(*this, DeclAccessPair::make(OperatorDelete, AS_public)); // Core issue, per mail to core reflector, 2016-10-09: // If this is a member operator delete, and there is a corresponding // non-sized member operator delete, this isn't /really/ a sized // deallocation function, it just happens to have a size_t parameter. bool IsSizedDelete = Info.HasSizeT; if (IsSizedDelete && !FoundGlobalDelete) { auto NonSizedDelete = resolveDeallocationOverload(*this, FoundDelete, /*WantSize*/false, /*WantAlign*/Info.HasAlignValT); if (NonSizedDelete && !NonSizedDelete.HasSizeT && NonSizedDelete.HasAlignValT == Info.HasAlignValT) IsSizedDelete = false; } if (IsSizedDelete) { SourceRange R = PlaceArgs.empty() ? SourceRange() : SourceRange(PlaceArgs.front()->getBeginLoc(), PlaceArgs.back()->getEndLoc()); Diag(StartLoc, diag::err_placement_new_non_placement_delete) << R; if (!OperatorDelete->isImplicit()) Diag(OperatorDelete->getLocation(), diag::note_previous_decl) << DeleteName; } } CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(), Matches[0].first); } else if (!Matches.empty()) { // We found multiple suitable operators. Per [expr.new]p20, that means we // call no 'operator delete' function, but we should at least warn the user. // FIXME: Suppress this warning if the construction cannot throw. Diag(StartLoc, diag::warn_ambiguous_suitable_delete_function_found) << DeleteName << AllocElemType; for (auto &Match : Matches) Diag(Match.second->getLocation(), diag::note_member_declared_here) << DeleteName; } return false; } /// DeclareGlobalNewDelete - Declare the global forms of operator new and /// delete. These are: /// @code /// // C++03: /// void* operator new(std::size_t) throw(std::bad_alloc); /// void* operator new[](std::size_t) throw(std::bad_alloc); /// void operator delete(void *) throw(); /// void operator delete[](void *) throw(); /// // C++11: /// void* operator new(std::size_t); /// void* operator new[](std::size_t); /// void operator delete(void *) noexcept; /// void operator delete[](void *) noexcept; /// // C++1y: /// void* operator new(std::size_t); /// void* operator new[](std::size_t); /// void operator delete(void *) noexcept; /// void operator delete[](void *) noexcept; /// void operator delete(void *, std::size_t) noexcept; /// void operator delete[](void *, std::size_t) noexcept; /// @endcode /// Note that the placement and nothrow forms of new are *not* implicitly /// declared. Their use requires including \. void Sema::DeclareGlobalNewDelete() { if (GlobalNewDeleteDeclared) return; // The implicitly declared new and delete operators // are not supported in OpenCL. if (getLangOpts().OpenCLCPlusPlus) return; // C++ [basic.std.dynamic]p2: // [...] The following allocation and deallocation functions (18.4) are // implicitly declared in global scope in each translation unit of a // program // // C++03: // void* operator new(std::size_t) throw(std::bad_alloc); // void* operator new[](std::size_t) throw(std::bad_alloc); // void operator delete(void*) throw(); // void operator delete[](void*) throw(); // C++11: // void* operator new(std::size_t); // void* operator new[](std::size_t); // void operator delete(void*) noexcept; // void operator delete[](void*) noexcept; // C++1y: // void* operator new(std::size_t); // void* operator new[](std::size_t); // void operator delete(void*) noexcept; // void operator delete[](void*) noexcept; // void operator delete(void*, std::size_t) noexcept; // void operator delete[](void*, std::size_t) noexcept; // // These implicit declarations introduce only the function names operator // new, operator new[], operator delete, operator delete[]. // // Here, we need to refer to std::bad_alloc, so we will implicitly declare // "std" or "bad_alloc" as necessary to form the exception specification. // However, we do not make these implicit declarations visible to name // lookup. if (!StdBadAlloc && !getLangOpts().CPlusPlus11) { // The "std::bad_alloc" class has not yet been declared, so build it // implicitly. StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class, getOrCreateStdNamespace(), SourceLocation(), SourceLocation(), &PP.getIdentifierTable().get("bad_alloc"), nullptr); getStdBadAlloc()->setImplicit(true); } if (!StdAlignValT && getLangOpts().AlignedAllocation) { // The "std::align_val_t" enum class has not yet been declared, so build it // implicitly. auto *AlignValT = EnumDecl::Create( Context, getOrCreateStdNamespace(), SourceLocation(), SourceLocation(), &PP.getIdentifierTable().get("align_val_t"), nullptr, true, true, true); AlignValT->setIntegerType(Context.getSizeType()); AlignValT->setPromotionType(Context.getSizeType()); AlignValT->setImplicit(true); StdAlignValT = AlignValT; } GlobalNewDeleteDeclared = true; QualType VoidPtr = Context.getPointerType(Context.VoidTy); QualType SizeT = Context.getSizeType(); auto DeclareGlobalAllocationFunctions = [&](OverloadedOperatorKind Kind, QualType Return, QualType Param) { llvm::SmallVector Params; Params.push_back(Param); // Create up to four variants of the function (sized/aligned). bool HasSizedVariant = getLangOpts().SizedDeallocation && (Kind == OO_Delete || Kind == OO_Array_Delete); bool HasAlignedVariant = getLangOpts().AlignedAllocation; int NumSizeVariants = (HasSizedVariant ? 2 : 1); int NumAlignVariants = (HasAlignedVariant ? 2 : 1); for (int Sized = 0; Sized < NumSizeVariants; ++Sized) { if (Sized) Params.push_back(SizeT); for (int Aligned = 0; Aligned < NumAlignVariants; ++Aligned) { if (Aligned) Params.push_back(Context.getTypeDeclType(getStdAlignValT())); DeclareGlobalAllocationFunction( Context.DeclarationNames.getCXXOperatorName(Kind), Return, Params); if (Aligned) Params.pop_back(); } } }; DeclareGlobalAllocationFunctions(OO_New, VoidPtr, SizeT); DeclareGlobalAllocationFunctions(OO_Array_New, VoidPtr, SizeT); DeclareGlobalAllocationFunctions(OO_Delete, Context.VoidTy, VoidPtr); DeclareGlobalAllocationFunctions(OO_Array_Delete, Context.VoidTy, VoidPtr); } /// DeclareGlobalAllocationFunction - Declares a single implicit global /// allocation function if it doesn't already exist. void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, ArrayRef Params) { DeclContext *GlobalCtx = Context.getTranslationUnitDecl(); // Check if this function is already declared. DeclContext::lookup_result R = GlobalCtx->lookup(Name); for (DeclContext::lookup_iterator Alloc = R.begin(), AllocEnd = R.end(); Alloc != AllocEnd; ++Alloc) { // Only look at non-template functions, as it is the predefined, // non-templated allocation function we are trying to declare here. if (FunctionDecl *Func = dyn_cast(*Alloc)) { if (Func->getNumParams() == Params.size()) { llvm::SmallVector FuncParams; for (auto *P : Func->parameters()) FuncParams.push_back( Context.getCanonicalType(P->getType().getUnqualifiedType())); if (llvm::makeArrayRef(FuncParams) == Params) { // Make the function visible to name lookup, even if we found it in // an unimported module. It either is an implicitly-declared global // allocation function, or is suppressing that function. Func->setVisibleDespiteOwningModule(); return; } } } } FunctionProtoType::ExtProtoInfo EPI(Context.getDefaultCallingConvention( /*IsVariadic=*/false, /*IsCXXMethod=*/false, /*IsBuiltin=*/true)); QualType BadAllocType; bool HasBadAllocExceptionSpec = (Name.getCXXOverloadedOperator() == OO_New || Name.getCXXOverloadedOperator() == OO_Array_New); if (HasBadAllocExceptionSpec) { if (!getLangOpts().CPlusPlus11) { BadAllocType = Context.getTypeDeclType(getStdBadAlloc()); assert(StdBadAlloc && "Must have std::bad_alloc declared"); EPI.ExceptionSpec.Type = EST_Dynamic; EPI.ExceptionSpec.Exceptions = llvm::makeArrayRef(BadAllocType); } } else { EPI.ExceptionSpec = getLangOpts().CPlusPlus11 ? EST_BasicNoexcept : EST_DynamicNone; } auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) { QualType FnType = Context.getFunctionType(Return, Params, EPI); FunctionDecl *Alloc = FunctionDecl::Create( Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, FnType, /*TInfo=*/nullptr, SC_None, false, true); Alloc->setImplicit(); // Global allocation functions should always be visible. Alloc->setVisibleDespiteOwningModule(); Alloc->addAttr(VisibilityAttr::CreateImplicit( Context, LangOpts.GlobalAllocationFunctionVisibilityHidden ? VisibilityAttr::Hidden : VisibilityAttr::Default)); llvm::SmallVector ParamDecls; for (QualType T : Params) { ParamDecls.push_back(ParmVarDecl::Create( Context, Alloc, SourceLocation(), SourceLocation(), nullptr, T, /*TInfo=*/nullptr, SC_None, nullptr)); ParamDecls.back()->setImplicit(); } Alloc->setParams(ParamDecls); if (ExtraAttr) Alloc->addAttr(ExtraAttr); Context.getTranslationUnitDecl()->addDecl(Alloc); IdResolver.tryAddTopLevelDecl(Alloc, Name); }; if (!LangOpts.CUDA) CreateAllocationFunctionDecl(nullptr); else { // Host and device get their own declaration so each can be // defined or re-declared independently. CreateAllocationFunctionDecl(CUDAHostAttr::CreateImplicit(Context)); CreateAllocationFunctionDecl(CUDADeviceAttr::CreateImplicit(Context)); } } FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc, bool CanProvideSize, bool Overaligned, DeclarationName Name) { DeclareGlobalNewDelete(); LookupResult FoundDelete(*this, Name, StartLoc, LookupOrdinaryName); LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl()); // FIXME: It's possible for this to result in ambiguity, through a // user-declared variadic operator delete or the enable_if attribute. We // should probably not consider those cases to be usual deallocation // functions. But for now we just make an arbitrary choice in that case. auto Result = resolveDeallocationOverload(*this, FoundDelete, CanProvideSize, Overaligned); assert(Result.FD && "operator delete missing from global scope?"); return Result.FD; } FunctionDecl *Sema::FindDeallocationFunctionForDestructor(SourceLocation Loc, CXXRecordDecl *RD) { DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Delete); FunctionDecl *OperatorDelete = nullptr; if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete)) return nullptr; if (OperatorDelete) return OperatorDelete; // If there's no class-specific operator delete, look up the global // non-array delete. return FindUsualDeallocationFunction( Loc, true, hasNewExtendedAlignment(*this, Context.getRecordType(RD)), Name); } bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl *&Operator, bool Diagnose) { LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName); // Try to find operator delete/operator delete[] in class scope. LookupQualifiedName(Found, RD); if (Found.isAmbiguous()) return true; Found.suppressDiagnostics(); bool Overaligned = hasNewExtendedAlignment(*this, Context.getRecordType(RD)); // C++17 [expr.delete]p10: // If the deallocation functions have class scope, the one without a // parameter of type std::size_t is selected. llvm::SmallVector Matches; resolveDeallocationOverload(*this, Found, /*WantSize*/ false, /*WantAlign*/ Overaligned, &Matches); // If we could find an overload, use it. if (Matches.size() == 1) { Operator = cast(Matches[0].FD); // FIXME: DiagnoseUseOfDecl? if (Operator->isDeleted()) { if (Diagnose) { Diag(StartLoc, diag::err_deleted_function_use); NoteDeletedFunction(Operator); } return true; } if (CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(), Matches[0].Found, Diagnose) == AR_inaccessible) return true; return false; } // We found multiple suitable operators; complain about the ambiguity. // FIXME: The standard doesn't say to do this; it appears that the intent // is that this should never happen. if (!Matches.empty()) { if (Diagnose) { Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found) << Name << RD; for (auto &Match : Matches) Diag(Match.FD->getLocation(), diag::note_member_declared_here) << Name; } return true; } // We did find operator delete/operator delete[] declarations, but // none of them were suitable. if (!Found.empty()) { if (Diagnose) { Diag(StartLoc, diag::err_no_suitable_delete_member_function_found) << Name << RD; for (NamedDecl *D : Found) Diag(D->getUnderlyingDecl()->getLocation(), diag::note_member_declared_here) << Name; } return true; } Operator = nullptr; return false; } namespace { /// Checks whether delete-expression, and new-expression used for /// initializing deletee have the same array form. class MismatchingNewDeleteDetector { public: enum MismatchResult { /// Indicates that there is no mismatch or a mismatch cannot be proven. NoMismatch, /// Indicates that variable is initialized with mismatching form of \a new. VarInitMismatches, /// Indicates that member is initialized with mismatching form of \a new. MemberInitMismatches, /// Indicates that 1 or more constructors' definitions could not been /// analyzed, and they will be checked again at the end of translation unit. AnalyzeLater }; /// \param EndOfTU True, if this is the final analysis at the end of /// translation unit. False, if this is the initial analysis at the point /// delete-expression was encountered. explicit MismatchingNewDeleteDetector(bool EndOfTU) : Field(nullptr), IsArrayForm(false), EndOfTU(EndOfTU), HasUndefinedConstructors(false) {} /// Checks whether pointee of a delete-expression is initialized with /// matching form of new-expression. /// /// If return value is \c VarInitMismatches or \c MemberInitMismatches at the /// point where delete-expression is encountered, then a warning will be /// issued immediately. If return value is \c AnalyzeLater at the point where /// delete-expression is seen, then member will be analyzed at the end of /// translation unit. \c AnalyzeLater is returned iff at least one constructor /// couldn't be analyzed. If at least one constructor initializes the member /// with matching type of new, the return value is \c NoMismatch. MismatchResult analyzeDeleteExpr(const CXXDeleteExpr *DE); /// Analyzes a class member. /// \param Field Class member to analyze. /// \param DeleteWasArrayForm Array form-ness of the delete-expression used /// for deleting the \p Field. MismatchResult analyzeField(FieldDecl *Field, bool DeleteWasArrayForm); FieldDecl *Field; /// List of mismatching new-expressions used for initialization of the pointee llvm::SmallVector NewExprs; /// Indicates whether delete-expression was in array form. bool IsArrayForm; private: const bool EndOfTU; /// Indicates that there is at least one constructor without body. bool HasUndefinedConstructors; /// Returns \c CXXNewExpr from given initialization expression. /// \param E Expression used for initializing pointee in delete-expression. /// E can be a single-element \c InitListExpr consisting of new-expression. const CXXNewExpr *getNewExprFromInitListOrExpr(const Expr *E); /// Returns whether member is initialized with mismatching form of /// \c new either by the member initializer or in-class initialization. /// /// If bodies of all constructors are not visible at the end of translation /// unit or at least one constructor initializes member with the matching /// form of \c new, mismatch cannot be proven, and this function will return /// \c NoMismatch. MismatchResult analyzeMemberExpr(const MemberExpr *ME); /// Returns whether variable is initialized with mismatching form of /// \c new. /// /// If variable is initialized with matching form of \c new or variable is not /// initialized with a \c new expression, this function will return true. /// If variable is initialized with mismatching form of \c new, returns false. /// \param D Variable to analyze. bool hasMatchingVarInit(const DeclRefExpr *D); /// Checks whether the constructor initializes pointee with mismatching /// form of \c new. /// /// Returns true, if member is initialized with matching form of \c new in /// member initializer list. Returns false, if member is initialized with the /// matching form of \c new in this constructor's initializer or given /// constructor isn't defined at the point where delete-expression is seen, or /// member isn't initialized by the constructor. bool hasMatchingNewInCtor(const CXXConstructorDecl *CD); /// Checks whether member is initialized with matching form of /// \c new in member initializer list. bool hasMatchingNewInCtorInit(const CXXCtorInitializer *CI); /// Checks whether member is initialized with mismatching form of \c new by /// in-class initializer. MismatchResult analyzeInClassInitializer(); }; } MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeDeleteExpr(const CXXDeleteExpr *DE) { NewExprs.clear(); assert(DE && "Expected delete-expression"); IsArrayForm = DE->isArrayForm(); const Expr *E = DE->getArgument()->IgnoreParenImpCasts(); if (const MemberExpr *ME = dyn_cast(E)) { return analyzeMemberExpr(ME); } else if (const DeclRefExpr *D = dyn_cast(E)) { if (!hasMatchingVarInit(D)) return VarInitMismatches; } return NoMismatch; } const CXXNewExpr * MismatchingNewDeleteDetector::getNewExprFromInitListOrExpr(const Expr *E) { assert(E != nullptr && "Expected a valid initializer expression"); E = E->IgnoreParenImpCasts(); if (const InitListExpr *ILE = dyn_cast(E)) { if (ILE->getNumInits() == 1) E = dyn_cast(ILE->getInit(0)->IgnoreParenImpCasts()); } return dyn_cast_or_null(E); } bool MismatchingNewDeleteDetector::hasMatchingNewInCtorInit( const CXXCtorInitializer *CI) { const CXXNewExpr *NE = nullptr; if (Field == CI->getMember() && (NE = getNewExprFromInitListOrExpr(CI->getInit()))) { if (NE->isArray() == IsArrayForm) return true; else NewExprs.push_back(NE); } return false; } bool MismatchingNewDeleteDetector::hasMatchingNewInCtor( const CXXConstructorDecl *CD) { if (CD->isImplicit()) return false; const FunctionDecl *Definition = CD; if (!CD->isThisDeclarationADefinition() && !CD->isDefined(Definition)) { HasUndefinedConstructors = true; return EndOfTU; } for (const auto *CI : cast(Definition)->inits()) { if (hasMatchingNewInCtorInit(CI)) return true; } return false; } MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeInClassInitializer() { assert(Field != nullptr && "This should be called only for members"); const Expr *InitExpr = Field->getInClassInitializer(); if (!InitExpr) return EndOfTU ? NoMismatch : AnalyzeLater; if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) { if (NE->isArray() != IsArrayForm) { NewExprs.push_back(NE); return MemberInitMismatches; } } return NoMismatch; } MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeField(FieldDecl *Field, bool DeleteWasArrayForm) { assert(Field != nullptr && "Analysis requires a valid class member."); this->Field = Field; IsArrayForm = DeleteWasArrayForm; const CXXRecordDecl *RD = cast(Field->getParent()); for (const auto *CD : RD->ctors()) { if (hasMatchingNewInCtor(CD)) return NoMismatch; } if (HasUndefinedConstructors) return EndOfTU ? NoMismatch : AnalyzeLater; if (!NewExprs.empty()) return MemberInitMismatches; return Field->hasInClassInitializer() ? analyzeInClassInitializer() : NoMismatch; } MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeMemberExpr(const MemberExpr *ME) { assert(ME != nullptr && "Expected a member expression"); if (FieldDecl *F = dyn_cast(ME->getMemberDecl())) return analyzeField(F, IsArrayForm); return NoMismatch; } bool MismatchingNewDeleteDetector::hasMatchingVarInit(const DeclRefExpr *D) { const CXXNewExpr *NE = nullptr; if (const VarDecl *VD = dyn_cast(D->getDecl())) { if (VD->hasInit() && (NE = getNewExprFromInitListOrExpr(VD->getInit())) && NE->isArray() != IsArrayForm) { NewExprs.push_back(NE); } } return NewExprs.empty(); } static void DiagnoseMismatchedNewDelete(Sema &SemaRef, SourceLocation DeleteLoc, const MismatchingNewDeleteDetector &Detector) { SourceLocation EndOfDelete = SemaRef.getLocForEndOfToken(DeleteLoc); FixItHint H; if (!Detector.IsArrayForm) H = FixItHint::CreateInsertion(EndOfDelete, "[]"); else { SourceLocation RSquare = Lexer::findLocationAfterToken( DeleteLoc, tok::l_square, SemaRef.getSourceManager(), SemaRef.getLangOpts(), true); if (RSquare.isValid()) H = FixItHint::CreateRemoval(SourceRange(EndOfDelete, RSquare)); } SemaRef.Diag(DeleteLoc, diag::warn_mismatched_delete_new) << Detector.IsArrayForm << H; for (const auto *NE : Detector.NewExprs) SemaRef.Diag(NE->getExprLoc(), diag::note_allocated_here) << Detector.IsArrayForm; } void Sema::AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE) { if (Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation())) return; MismatchingNewDeleteDetector Detector(/*EndOfTU=*/false); switch (Detector.analyzeDeleteExpr(DE)) { case MismatchingNewDeleteDetector::VarInitMismatches: case MismatchingNewDeleteDetector::MemberInitMismatches: { DiagnoseMismatchedNewDelete(*this, DE->getBeginLoc(), Detector); break; } case MismatchingNewDeleteDetector::AnalyzeLater: { DeleteExprs[Detector.Field].push_back( std::make_pair(DE->getBeginLoc(), DE->isArrayForm())); break; } case MismatchingNewDeleteDetector::NoMismatch: break; } } void Sema::AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc, bool DeleteWasArrayForm) { MismatchingNewDeleteDetector Detector(/*EndOfTU=*/true); switch (Detector.analyzeField(Field, DeleteWasArrayForm)) { case MismatchingNewDeleteDetector::VarInitMismatches: llvm_unreachable("This analysis should have been done for class members."); case MismatchingNewDeleteDetector::AnalyzeLater: llvm_unreachable("Analysis cannot be postponed any point beyond end of " "translation unit."); case MismatchingNewDeleteDetector::MemberInitMismatches: DiagnoseMismatchedNewDelete(*this, DeleteLoc, Detector); break; case MismatchingNewDeleteDetector::NoMismatch: break; } } /// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in: /// @code ::delete ptr; @endcode /// or /// @code delete [] ptr; @endcode ExprResult Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool ArrayForm, Expr *ExE) { // C++ [expr.delete]p1: // The operand shall have a pointer type, or a class type having a single // non-explicit conversion function to a pointer type. The result has type // void. // // DR599 amends "pointer type" to "pointer to object type" in both cases. ExprResult Ex = ExE; FunctionDecl *OperatorDelete = nullptr; bool ArrayFormAsWritten = ArrayForm; bool UsualArrayDeleteWantsSize = false; if (!Ex.get()->isTypeDependent()) { // Perform lvalue-to-rvalue cast, if needed. Ex = DefaultLvalueConversion(Ex.get()); if (Ex.isInvalid()) return ExprError(); QualType Type = Ex.get()->getType(); class DeleteConverter : public ContextualImplicitConverter { public: DeleteConverter() : ContextualImplicitConverter(false, true) {} bool match(QualType ConvType) override { // FIXME: If we have an operator T* and an operator void*, we must pick // the operator T*. if (const PointerType *ConvPtrType = ConvType->getAs()) if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType()) return true; return false; } SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_delete_operand) << T; } SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_delete_incomplete_class_type) << T; } SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { return S.Diag(Loc, diag::err_delete_explicit_conversion) << T << ConvTy; } SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_delete_conversion) << ConvTy; } SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_ambiguous_delete_operand) << T; } SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_delete_conversion) << ConvTy; } SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { llvm_unreachable("conversion functions are permitted"); } } Converter; Ex = PerformContextualImplicitConversion(StartLoc, Ex.get(), Converter); if (Ex.isInvalid()) return ExprError(); Type = Ex.get()->getType(); if (!Converter.match(Type)) // FIXME: PerformContextualImplicitConversion should return ExprError // itself in this case. return ExprError(); QualType Pointee = Type->castAs()->getPointeeType(); QualType PointeeElem = Context.getBaseElementType(Pointee); if (Pointee.getAddressSpace() != LangAS::Default && !getLangOpts().OpenCLCPlusPlus) return Diag(Ex.get()->getBeginLoc(), diag::err_address_space_qualified_delete) << Pointee.getUnqualifiedType() << Pointee.getQualifiers().getAddressSpaceAttributePrintValue(); CXXRecordDecl *PointeeRD = nullptr; if (Pointee->isVoidType() && !isSFINAEContext()) { // The C++ standard bans deleting a pointer to a non-object type, which // effectively bans deletion of "void*". However, most compilers support // this, so we treat it as a warning unless we're in a SFINAE context. Diag(StartLoc, diag::ext_delete_void_ptr_operand) << Type << Ex.get()->getSourceRange(); } else if (Pointee->isFunctionType() || Pointee->isVoidType()) { return ExprError(Diag(StartLoc, diag::err_delete_operand) << Type << Ex.get()->getSourceRange()); } else if (!Pointee->isDependentType()) { // FIXME: This can result in errors if the definition was imported from a // module but is hidden. if (!RequireCompleteType(StartLoc, Pointee, diag::warn_delete_incomplete, Ex.get())) { if (const RecordType *RT = PointeeElem->getAs()) PointeeRD = cast(RT->getDecl()); } } if (Pointee->isArrayType() && !ArrayForm) { Diag(StartLoc, diag::warn_delete_array_type) << Type << Ex.get()->getSourceRange() << FixItHint::CreateInsertion(getLocForEndOfToken(StartLoc), "[]"); ArrayForm = true; } DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName( ArrayForm ? OO_Array_Delete : OO_Delete); if (PointeeRD) { if (!UseGlobal && FindDeallocationFunction(StartLoc, PointeeRD, DeleteName, OperatorDelete)) return ExprError(); // If we're allocating an array of records, check whether the // usual operator delete[] has a size_t parameter. if (ArrayForm) { // If the user specifically asked to use the global allocator, // we'll need to do the lookup into the class. if (UseGlobal) UsualArrayDeleteWantsSize = doesUsualArrayDeleteWantSize(*this, StartLoc, PointeeElem); // Otherwise, the usual operator delete[] should be the // function we just found. else if (OperatorDelete && isa(OperatorDelete)) UsualArrayDeleteWantsSize = UsualDeallocFnInfo(*this, DeclAccessPair::make(OperatorDelete, AS_public)) .HasSizeT; } if (!PointeeRD->hasIrrelevantDestructor()) if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) { MarkFunctionReferenced(StartLoc, const_cast(Dtor)); if (DiagnoseUseOfDecl(Dtor, StartLoc)) return ExprError(); } CheckVirtualDtorCall(PointeeRD->getDestructor(), StartLoc, /*IsDelete=*/true, /*CallCanBeVirtual=*/true, /*WarnOnNonAbstractTypes=*/!ArrayForm, SourceLocation()); } if (!OperatorDelete) { if (getLangOpts().OpenCLCPlusPlus) { Diag(StartLoc, diag::err_openclcxx_not_supported) << "default delete"; return ExprError(); } bool IsComplete = isCompleteType(StartLoc, Pointee); bool CanProvideSize = IsComplete && (!ArrayForm || UsualArrayDeleteWantsSize || Pointee.isDestructedType()); bool Overaligned = hasNewExtendedAlignment(*this, Pointee); // Look for a global declaration. OperatorDelete = FindUsualDeallocationFunction(StartLoc, CanProvideSize, Overaligned, DeleteName); } MarkFunctionReferenced(StartLoc, OperatorDelete); // Check access and ambiguity of destructor if we're going to call it. // Note that this is required even for a virtual delete. bool IsVirtualDelete = false; if (PointeeRD) { if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) { CheckDestructorAccess(Ex.get()->getExprLoc(), Dtor, PDiag(diag::err_access_dtor) << PointeeElem); IsVirtualDelete = Dtor->isVirtual(); } } DiagnoseUseOfDecl(OperatorDelete, StartLoc); // Convert the operand to the type of the first parameter of operator // delete. This is only necessary if we selected a destroying operator // delete that we are going to call (non-virtually); converting to void* // is trivial and left to AST consumers to handle. QualType ParamType = OperatorDelete->getParamDecl(0)->getType(); if (!IsVirtualDelete && !ParamType->getPointeeType()->isVoidType()) { Qualifiers Qs = Pointee.getQualifiers(); if (Qs.hasCVRQualifiers()) { // Qualifiers are irrelevant to this conversion; we're only looking // for access and ambiguity. Qs.removeCVRQualifiers(); QualType Unqual = Context.getPointerType( Context.getQualifiedType(Pointee.getUnqualifiedType(), Qs)); Ex = ImpCastExprToType(Ex.get(), Unqual, CK_NoOp); } Ex = PerformImplicitConversion(Ex.get(), ParamType, AA_Passing); if (Ex.isInvalid()) return ExprError(); } } CXXDeleteExpr *Result = new (Context) CXXDeleteExpr( Context.VoidTy, UseGlobal, ArrayForm, ArrayFormAsWritten, UsualArrayDeleteWantsSize, OperatorDelete, Ex.get(), StartLoc); AnalyzeDeleteExprMismatch(Result); return Result; } static bool resolveBuiltinNewDeleteOverload(Sema &S, CallExpr *TheCall, bool IsDelete, FunctionDecl *&Operator) { DeclarationName NewName = S.Context.DeclarationNames.getCXXOperatorName( IsDelete ? OO_Delete : OO_New); LookupResult R(S, NewName, TheCall->getBeginLoc(), Sema::LookupOrdinaryName); S.LookupQualifiedName(R, S.Context.getTranslationUnitDecl()); assert(!R.empty() && "implicitly declared allocation functions not found"); assert(!R.isAmbiguous() && "global allocation functions are ambiguous"); // We do our own custom access checks below. R.suppressDiagnostics(); SmallVector Args(TheCall->arg_begin(), TheCall->arg_end()); OverloadCandidateSet Candidates(R.getNameLoc(), OverloadCandidateSet::CSK_Normal); for (LookupResult::iterator FnOvl = R.begin(), FnOvlEnd = R.end(); FnOvl != FnOvlEnd; ++FnOvl) { // Even member operator new/delete are implicitly treated as // static, so don't use AddMemberCandidate. NamedDecl *D = (*FnOvl)->getUnderlyingDecl(); if (FunctionTemplateDecl *FnTemplate = dyn_cast(D)) { S.AddTemplateOverloadCandidate(FnTemplate, FnOvl.getPair(), /*ExplicitTemplateArgs=*/nullptr, Args, Candidates, /*SuppressUserConversions=*/false); continue; } FunctionDecl *Fn = cast(D); S.AddOverloadCandidate(Fn, FnOvl.getPair(), Args, Candidates, /*SuppressUserConversions=*/false); } SourceRange Range = TheCall->getSourceRange(); // Do the resolution. OverloadCandidateSet::iterator Best; switch (Candidates.BestViableFunction(S, R.getNameLoc(), Best)) { case OR_Success: { // Got one! FunctionDecl *FnDecl = Best->Function; assert(R.getNamingClass() == nullptr && "class members should not be considered"); if (!FnDecl->isReplaceableGlobalAllocationFunction()) { S.Diag(R.getNameLoc(), diag::err_builtin_operator_new_delete_not_usual) << (IsDelete ? 1 : 0) << Range; S.Diag(FnDecl->getLocation(), diag::note_non_usual_function_declared_here) << R.getLookupName() << FnDecl->getSourceRange(); return true; } Operator = FnDecl; return false; } case OR_No_Viable_Function: Candidates.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_no_viable_function_in_call) << R.getLookupName() << Range), S, OCD_AllCandidates, Args); return true; case OR_Ambiguous: Candidates.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_ambiguous_call) << R.getLookupName() << Range), S, OCD_AmbiguousCandidates, Args); return true; case OR_Deleted: { Candidates.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_deleted_call) << R.getLookupName() << Range), S, OCD_AllCandidates, Args); return true; } } llvm_unreachable("Unreachable, bad result from BestViableFunction"); } ExprResult Sema::SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult, bool IsDelete) { CallExpr *TheCall = cast(TheCallResult.get()); if (!getLangOpts().CPlusPlus) { Diag(TheCall->getExprLoc(), diag::err_builtin_requires_language) << (IsDelete ? "__builtin_operator_delete" : "__builtin_operator_new") << "C++"; return ExprError(); } // CodeGen assumes it can find the global new and delete to call, // so ensure that they are declared. DeclareGlobalNewDelete(); FunctionDecl *OperatorNewOrDelete = nullptr; if (resolveBuiltinNewDeleteOverload(*this, TheCall, IsDelete, OperatorNewOrDelete)) return ExprError(); assert(OperatorNewOrDelete && "should be found"); DiagnoseUseOfDecl(OperatorNewOrDelete, TheCall->getExprLoc()); MarkFunctionReferenced(TheCall->getExprLoc(), OperatorNewOrDelete); TheCall->setType(OperatorNewOrDelete->getReturnType()); for (unsigned i = 0; i != TheCall->getNumArgs(); ++i) { QualType ParamTy = OperatorNewOrDelete->getParamDecl(i)->getType(); InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, ParamTy, false); ExprResult Arg = PerformCopyInitialization( Entity, TheCall->getArg(i)->getBeginLoc(), TheCall->getArg(i)); if (Arg.isInvalid()) return ExprError(); TheCall->setArg(i, Arg.get()); } auto Callee = dyn_cast(TheCall->getCallee()); assert(Callee && Callee->getCastKind() == CK_BuiltinFnToFnPtr && "Callee expected to be implicit cast to a builtin function pointer"); Callee->setType(OperatorNewOrDelete->getType()); return TheCallResult; } void Sema::CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc, bool IsDelete, bool CallCanBeVirtual, bool WarnOnNonAbstractTypes, SourceLocation DtorLoc) { if (!dtor || dtor->isVirtual() || !CallCanBeVirtual || isUnevaluatedContext()) return; // C++ [expr.delete]p3: // In the first alternative (delete object), if the static type of the // object to be deleted is different from its dynamic type, the static // type shall be a base class of the dynamic type of the object to be // deleted and the static type shall have a virtual destructor or the // behavior is undefined. // const CXXRecordDecl *PointeeRD = dtor->getParent(); // Note: a final class cannot be derived from, no issue there if (!PointeeRD->isPolymorphic() || PointeeRD->hasAttr()) return; // If the superclass is in a system header, there's nothing that can be done. // The `delete` (where we emit the warning) can be in a system header, // what matters for this warning is where the deleted type is defined. if (getSourceManager().isInSystemHeader(PointeeRD->getLocation())) return; QualType ClassType = dtor->getThisType()->getPointeeType(); if (PointeeRD->isAbstract()) { // If the class is abstract, we warn by default, because we're // sure the code has undefined behavior. Diag(Loc, diag::warn_delete_abstract_non_virtual_dtor) << (IsDelete ? 0 : 1) << ClassType; } else if (WarnOnNonAbstractTypes) { // Otherwise, if this is not an array delete, it's a bit suspect, // but not necessarily wrong. Diag(Loc, diag::warn_delete_non_virtual_dtor) << (IsDelete ? 0 : 1) << ClassType; } if (!IsDelete) { std::string TypeStr; ClassType.getAsStringInternal(TypeStr, getPrintingPolicy()); Diag(DtorLoc, diag::note_delete_non_virtual) << FixItHint::CreateInsertion(DtorLoc, TypeStr + "::"); } } Sema::ConditionResult Sema::ActOnConditionVariable(Decl *ConditionVar, SourceLocation StmtLoc, ConditionKind CK) { ExprResult E = CheckConditionVariable(cast(ConditionVar), StmtLoc, CK); if (E.isInvalid()) return ConditionError(); return ConditionResult(*this, ConditionVar, MakeFullExpr(E.get(), StmtLoc), CK == ConditionKind::ConstexprIf); } /// Check the use of the given variable as a C++ condition in an if, /// while, do-while, or switch statement. ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, SourceLocation StmtLoc, ConditionKind CK) { if (ConditionVar->isInvalidDecl()) return ExprError(); QualType T = ConditionVar->getType(); // C++ [stmt.select]p2: // The declarator shall not specify a function or an array. if (T->isFunctionType()) return ExprError(Diag(ConditionVar->getLocation(), diag::err_invalid_use_of_function_type) << ConditionVar->getSourceRange()); else if (T->isArrayType()) return ExprError(Diag(ConditionVar->getLocation(), diag::err_invalid_use_of_array_type) << ConditionVar->getSourceRange()); ExprResult Condition = BuildDeclRefExpr( ConditionVar, ConditionVar->getType().getNonReferenceType(), VK_LValue, ConditionVar->getLocation()); switch (CK) { case ConditionKind::Boolean: return CheckBooleanCondition(StmtLoc, Condition.get()); case ConditionKind::ConstexprIf: return CheckBooleanCondition(StmtLoc, Condition.get(), true); case ConditionKind::Switch: return CheckSwitchCondition(StmtLoc, Condition.get()); } llvm_unreachable("unexpected condition kind"); } /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid. ExprResult Sema::CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr) { // C++ 6.4p4: // The value of a condition that is an initialized declaration in a statement // other than a switch statement is the value of the declared variable // implicitly converted to type bool. If that conversion is ill-formed, the // program is ill-formed. // The value of a condition that is an expression is the value of the // expression, implicitly converted to bool. // // FIXME: Return this value to the caller so they don't need to recompute it. llvm::APSInt Value(/*BitWidth*/1); return (IsConstexpr && !CondExpr->isValueDependent()) ? CheckConvertedConstantExpression(CondExpr, Context.BoolTy, Value, CCEK_ConstexprIf) : PerformContextuallyConvertToBool(CondExpr); } /// Helper function to determine whether this is the (deprecated) C++ /// conversion from a string literal to a pointer to non-const char or /// non-const wchar_t (for narrow and wide string literals, /// respectively). bool Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) { // Look inside the implicit cast, if it exists. if (ImplicitCastExpr *Cast = dyn_cast(From)) From = Cast->getSubExpr(); // A string literal (2.13.4) that is not a wide string literal can // be converted to an rvalue of type "pointer to char"; a wide // string literal can be converted to an rvalue of type "pointer // to wchar_t" (C++ 4.2p2). if (StringLiteral *StrLit = dyn_cast(From->IgnoreParens())) if (const PointerType *ToPtrType = ToType->getAs()) if (const BuiltinType *ToPointeeType = ToPtrType->getPointeeType()->getAs()) { // This conversion is considered only when there is an // explicit appropriate pointer target type (C++ 4.2p2). if (!ToPtrType->getPointeeType().hasQualifiers()) { switch (StrLit->getKind()) { case StringLiteral::UTF8: case StringLiteral::UTF16: case StringLiteral::UTF32: // We don't allow UTF literals to be implicitly converted break; case StringLiteral::Ascii: return (ToPointeeType->getKind() == BuiltinType::Char_U || ToPointeeType->getKind() == BuiltinType::Char_S); case StringLiteral::Wide: return Context.typesAreCompatible(Context.getWideCharType(), QualType(ToPointeeType, 0)); } } } return false; } static ExprResult BuildCXXCastArgument(Sema &S, SourceLocation CastLoc, QualType Ty, CastKind Kind, CXXMethodDecl *Method, DeclAccessPair FoundDecl, bool HadMultipleCandidates, Expr *From) { switch (Kind) { default: llvm_unreachable("Unhandled cast kind!"); case CK_ConstructorConversion: { CXXConstructorDecl *Constructor = cast(Method); SmallVector ConstructorArgs; if (S.RequireNonAbstractType(CastLoc, Ty, diag::err_allocation_of_abstract_type)) return ExprError(); if (S.CompleteConstructorCall(Constructor, From, CastLoc, ConstructorArgs)) return ExprError(); S.CheckConstructorAccess(CastLoc, Constructor, FoundDecl, InitializedEntity::InitializeTemporary(Ty)); if (S.DiagnoseUseOfDecl(Method, CastLoc)) return ExprError(); ExprResult Result = S.BuildCXXConstructExpr( CastLoc, Ty, FoundDecl, cast(Method), ConstructorArgs, HadMultipleCandidates, /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, SourceRange()); if (Result.isInvalid()) return ExprError(); return S.MaybeBindToTemporary(Result.getAs()); } case CK_UserDefinedConversion: { assert(!From->getType()->isPointerType() && "Arg can't have pointer type!"); S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl); if (S.DiagnoseUseOfDecl(Method, CastLoc)) return ExprError(); // Create an implicit call expr that calls it. CXXConversionDecl *Conv = cast(Method); ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Conv, HadMultipleCandidates); if (Result.isInvalid()) return ExprError(); // Record usage of conversion in an implicit cast. Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(), CK_UserDefinedConversion, Result.get(), nullptr, Result.get()->getValueKind()); return S.MaybeBindToTemporary(Result.get()); } } } /// PerformImplicitConversion - Perform an implicit conversion of the /// expression From to the type ToType using the pre-computed implicit /// conversion sequence ICS. Returns the converted /// expression. Action is the kind of conversion we're performing, /// used in the error message. ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK) { // C++ [over.match.oper]p7: [...] operands of class type are converted [...] if (CCK == CCK_ForBuiltinOverloadedOp && !From->getType()->isRecordType()) return From; switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: { ExprResult Res = PerformImplicitConversion(From, ToType, ICS.Standard, Action, CCK); if (Res.isInvalid()) return ExprError(); From = Res.get(); break; } case ImplicitConversionSequence::UserDefinedConversion: { FunctionDecl *FD = ICS.UserDefined.ConversionFunction; CastKind CastKind; QualType BeforeToType; assert(FD && "no conversion function for user-defined conversion seq"); if (const CXXConversionDecl *Conv = dyn_cast(FD)) { CastKind = CK_UserDefinedConversion; // If the user-defined conversion is specified by a conversion function, // the initial standard conversion sequence converts the source type to // the implicit object parameter of the conversion function. BeforeToType = Context.getTagDeclType(Conv->getParent()); } else { const CXXConstructorDecl *Ctor = cast(FD); CastKind = CK_ConstructorConversion; // Do no conversion if dealing with ... for the first conversion. if (!ICS.UserDefined.EllipsisConversion) { // If the user-defined conversion is specified by a constructor, the // initial standard conversion sequence converts the source type to // the type required by the argument of the constructor BeforeToType = Ctor->getParamDecl(0)->getType().getNonReferenceType(); } } // Watch out for ellipsis conversion. if (!ICS.UserDefined.EllipsisConversion) { ExprResult Res = PerformImplicitConversion(From, BeforeToType, ICS.UserDefined.Before, AA_Converting, CCK); if (Res.isInvalid()) return ExprError(); From = Res.get(); } ExprResult CastArg = BuildCXXCastArgument( *this, From->getBeginLoc(), ToType.getNonReferenceType(), CastKind, cast(FD), ICS.UserDefined.FoundConversionFunction, ICS.UserDefined.HadMultipleCandidates, From); if (CastArg.isInvalid()) return ExprError(); From = CastArg.get(); // C++ [over.match.oper]p7: // [...] the second standard conversion sequence of a user-defined // conversion sequence is not applied. if (CCK == CCK_ForBuiltinOverloadedOp) return From; return PerformImplicitConversion(From, ToType, ICS.UserDefined.After, AA_Converting, CCK); } case ImplicitConversionSequence::AmbiguousConversion: ICS.DiagnoseAmbiguousConversion(*this, From->getExprLoc(), PDiag(diag::err_typecheck_ambiguous_condition) << From->getSourceRange()); return ExprError(); case ImplicitConversionSequence::EllipsisConversion: llvm_unreachable("Cannot perform an ellipsis conversion"); case ImplicitConversionSequence::BadConversion: bool Diagnosed = DiagnoseAssignmentResult(Incompatible, From->getExprLoc(), ToType, From->getType(), From, Action); assert(Diagnosed && "failed to diagnose bad conversion"); (void)Diagnosed; return ExprError(); } // Everything went well. return From; } /// PerformImplicitConversion - Perform an implicit conversion of the /// expression From to the type ToType by following the standard /// conversion sequence SCS. Returns the converted /// expression. Flavor is the context in which we're performing this /// conversion, for use in error messages. ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, const StandardConversionSequence& SCS, AssignmentAction Action, CheckedConversionKind CCK) { bool CStyle = (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast); // Overall FIXME: we are recomputing too many types here and doing far too // much extra work. What this means is that we need to keep track of more // information that is computed when we try the implicit conversion initially, // so that we don't need to recompute anything here. QualType FromType = From->getType(); if (SCS.CopyConstructor) { // FIXME: When can ToType be a reference type? assert(!ToType->isReferenceType()); if (SCS.Second == ICK_Derived_To_Base) { SmallVector ConstructorArgs; if (CompleteConstructorCall(cast(SCS.CopyConstructor), From, /*FIXME:ConstructLoc*/SourceLocation(), ConstructorArgs)) return ExprError(); return BuildCXXConstructExpr( /*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.FoundCopyConstructor, SCS.CopyConstructor, ConstructorArgs, /*HadMultipleCandidates*/ false, /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, SourceRange()); } return BuildCXXConstructExpr( /*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.FoundCopyConstructor, SCS.CopyConstructor, From, /*HadMultipleCandidates*/ false, /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, SourceRange()); } // Resolve overloaded function references. if (Context.hasSameType(FromType, Context.OverloadTy)) { DeclAccessPair Found; FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType, true, Found); if (!Fn) return ExprError(); if (DiagnoseUseOfDecl(Fn, From->getBeginLoc())) return ExprError(); From = FixOverloadedFunctionReference(From, Found, Fn); FromType = From->getType(); } // If we're converting to an atomic type, first convert to the corresponding // non-atomic type. QualType ToAtomicType; if (const AtomicType *ToAtomic = ToType->getAs()) { ToAtomicType = ToType; ToType = ToAtomic->getValueType(); } QualType InitialFromType = FromType; // Perform the first implicit conversion. switch (SCS.First) { case ICK_Identity: if (const AtomicType *FromAtomic = FromType->getAs()) { FromType = FromAtomic->getValueType().getUnqualifiedType(); From = ImplicitCastExpr::Create(Context, FromType, CK_AtomicToNonAtomic, From, /*BasePath=*/nullptr, VK_RValue); } break; case ICK_Lvalue_To_Rvalue: { assert(From->getObjectKind() != OK_ObjCProperty); ExprResult FromRes = DefaultLvalueConversion(From); assert(!FromRes.isInvalid() && "Can't perform deduced conversion?!"); From = FromRes.get(); FromType = From->getType(); break; } case ICK_Array_To_Pointer: FromType = Context.getArrayDecayedType(FromType); From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Function_To_Pointer: FromType = Context.getPointerType(FromType); From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; default: llvm_unreachable("Improper first standard conversion"); } // Perform the second implicit conversion switch (SCS.Second) { case ICK_Identity: // C++ [except.spec]p5: // [For] assignment to and initialization of pointers to functions, // pointers to member functions, and references to functions: the // target entity shall allow at least the exceptions allowed by the // source value in the assignment or initialization. switch (Action) { case AA_Assigning: case AA_Initializing: // Note, function argument passing and returning are initialization. case AA_Passing: case AA_Returning: case AA_Sending: case AA_Passing_CFAudited: if (CheckExceptionSpecCompatibility(From, ToType)) return ExprError(); break; case AA_Casting: case AA_Converting: // Casts and implicit conversions are not initialization, so are not // checked for exception specification mismatches. break; } // Nothing else to do. break; case ICK_Integral_Promotion: case ICK_Integral_Conversion: if (ToType->isBooleanType()) { assert(FromType->castAs()->getDecl()->isFixed() && SCS.Second == ICK_Integral_Promotion && "only enums with fixed underlying type can promote to bool"); From = ImpCastExprToType(From, ToType, CK_IntegralToBoolean, VK_RValue, /*BasePath=*/nullptr, CCK).get(); } else { From = ImpCastExprToType(From, ToType, CK_IntegralCast, VK_RValue, /*BasePath=*/nullptr, CCK).get(); } break; case ICK_Floating_Promotion: case ICK_Floating_Conversion: From = ImpCastExprToType(From, ToType, CK_FloatingCast, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Complex_Promotion: case ICK_Complex_Conversion: { QualType FromEl = From->getType()->castAs()->getElementType(); QualType ToEl = ToType->castAs()->getElementType(); CastKind CK; if (FromEl->isRealFloatingType()) { if (ToEl->isRealFloatingType()) CK = CK_FloatingComplexCast; else CK = CK_FloatingComplexToIntegralComplex; } else if (ToEl->isRealFloatingType()) { CK = CK_IntegralComplexToFloatingComplex; } else { CK = CK_IntegralComplexCast; } From = ImpCastExprToType(From, ToType, CK, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; } case ICK_Floating_Integral: if (ToType->isRealFloatingType()) From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_RValue, /*BasePath=*/nullptr, CCK).get(); else From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Compatible_Conversion: - From = ImpCastExprToType(From, ToType, CK_NoOp, - VK_RValue, /*BasePath=*/nullptr, CCK).get(); + From = ImpCastExprToType(From, ToType, CK_NoOp, From->getValueKind(), + /*BasePath=*/nullptr, CCK).get(); break; case ICK_Writeback_Conversion: case ICK_Pointer_Conversion: { if (SCS.IncompatibleObjC && Action != AA_Casting) { // Diagnose incompatible Objective-C conversions if (Action == AA_Initializing || Action == AA_Assigning) Diag(From->getBeginLoc(), diag::ext_typecheck_convert_incompatible_pointer) << ToType << From->getType() << Action << From->getSourceRange() << 0; else Diag(From->getBeginLoc(), diag::ext_typecheck_convert_incompatible_pointer) << From->getType() << ToType << Action << From->getSourceRange() << 0; if (From->getType()->isObjCObjectPointerType() && ToType->isObjCObjectPointerType()) EmitRelatedResultTypeNote(From); } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && !CheckObjCARCUnavailableWeakConversion(ToType, From->getType())) { if (Action == AA_Initializing) Diag(From->getBeginLoc(), diag::err_arc_weak_unavailable_assign); else Diag(From->getBeginLoc(), diag::err_arc_convesion_of_weak_unavailable) << (Action == AA_Casting) << From->getType() << ToType << From->getSourceRange(); } // Defer address space conversion to the third conversion. QualType FromPteeType = From->getType()->getPointeeType(); QualType ToPteeType = ToType->getPointeeType(); QualType NewToType = ToType; if (!FromPteeType.isNull() && !ToPteeType.isNull() && FromPteeType.getAddressSpace() != ToPteeType.getAddressSpace()) { NewToType = Context.removeAddrSpaceQualType(ToPteeType); NewToType = Context.getAddrSpaceQualType(NewToType, FromPteeType.getAddressSpace()); if (ToType->isObjCObjectPointerType()) NewToType = Context.getObjCObjectPointerType(NewToType); else if (ToType->isBlockPointerType()) NewToType = Context.getBlockPointerType(NewToType); else NewToType = Context.getPointerType(NewToType); } CastKind Kind; CXXCastPath BasePath; if (CheckPointerConversion(From, NewToType, Kind, BasePath, CStyle)) return ExprError(); // Make sure we extend blocks if necessary. // FIXME: doing this here is really ugly. if (Kind == CK_BlockPointerToObjCPointerCast) { ExprResult E = From; (void) PrepareCastToObjCObjectPointer(E); From = E.get(); } if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) CheckObjCConversion(SourceRange(), NewToType, From, CCK); From = ImpCastExprToType(From, NewToType, Kind, VK_RValue, &BasePath, CCK) .get(); break; } case ICK_Pointer_Member: { CastKind Kind; CXXCastPath BasePath; if (CheckMemberPointerConversion(From, ToType, Kind, BasePath, CStyle)) return ExprError(); if (CheckExceptionSpecCompatibility(From, ToType)) return ExprError(); // We may not have been able to figure out what this member pointer resolved // to up until this exact point. Attempt to lock-in it's inheritance model. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { (void)isCompleteType(From->getExprLoc(), From->getType()); (void)isCompleteType(From->getExprLoc(), ToType); } From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK) .get(); break; } case ICK_Boolean_Conversion: // Perform half-to-boolean conversion via float. if (From->getType()->isHalfType()) { From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).get(); FromType = Context.FloatTy; } From = ImpCastExprToType(From, Context.BoolTy, ScalarTypeToBooleanCastKind(FromType), VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Derived_To_Base: { CXXCastPath BasePath; if (CheckDerivedToBaseConversion( From->getType(), ToType.getNonReferenceType(), From->getBeginLoc(), From->getSourceRange(), &BasePath, CStyle)) return ExprError(); From = ImpCastExprToType(From, ToType.getNonReferenceType(), CK_DerivedToBase, From->getValueKind(), &BasePath, CCK).get(); break; } case ICK_Vector_Conversion: From = ImpCastExprToType(From, ToType, CK_BitCast, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Vector_Splat: { // Vector splat from any arithmetic type to a vector. Expr *Elem = prepareVectorSplat(ToType, From).get(); From = ImpCastExprToType(Elem, ToType, CK_VectorSplat, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; } case ICK_Complex_Real: // Case 1. x -> _Complex y if (const ComplexType *ToComplex = ToType->getAs()) { QualType ElType = ToComplex->getElementType(); bool isFloatingComplex = ElType->isRealFloatingType(); // x -> y if (Context.hasSameUnqualifiedType(ElType, From->getType())) { // do nothing } else if (From->getType()->isRealFloatingType()) { From = ImpCastExprToType(From, ElType, isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).get(); } else { assert(From->getType()->isIntegerType()); From = ImpCastExprToType(From, ElType, isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).get(); } // y -> _Complex y From = ImpCastExprToType(From, ToType, isFloatingComplex ? CK_FloatingRealToComplex : CK_IntegralRealToComplex).get(); // Case 2. _Complex x -> y } else { const ComplexType *FromComplex = From->getType()->getAs(); assert(FromComplex); QualType ElType = FromComplex->getElementType(); bool isFloatingComplex = ElType->isRealFloatingType(); // _Complex x -> x From = ImpCastExprToType(From, ElType, isFloatingComplex ? CK_FloatingComplexToReal : CK_IntegralComplexToReal, VK_RValue, /*BasePath=*/nullptr, CCK).get(); // x -> y if (Context.hasSameUnqualifiedType(ElType, ToType)) { // do nothing } else if (ToType->isRealFloatingType()) { From = ImpCastExprToType(From, ToType, isFloatingComplex ? CK_FloatingCast : CK_IntegralToFloating, VK_RValue, /*BasePath=*/nullptr, CCK).get(); } else { assert(ToType->isIntegerType()); From = ImpCastExprToType(From, ToType, isFloatingComplex ? CK_FloatingToIntegral : CK_IntegralCast, VK_RValue, /*BasePath=*/nullptr, CCK).get(); } } break; case ICK_Block_Pointer_Conversion: { LangAS AddrSpaceL = ToType->castAs()->getPointeeType().getAddressSpace(); LangAS AddrSpaceR = FromType->castAs()->getPointeeType().getAddressSpace(); assert(Qualifiers::isAddressSpaceSupersetOf(AddrSpaceL, AddrSpaceR) && "Invalid cast"); CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast; From = ImpCastExprToType(From, ToType.getUnqualifiedType(), Kind, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; } case ICK_TransparentUnionConversion: { ExprResult FromRes = From; Sema::AssignConvertType ConvTy = CheckTransparentUnionArgumentConstraints(ToType, FromRes); if (FromRes.isInvalid()) return ExprError(); From = FromRes.get(); assert ((ConvTy == Sema::Compatible) && "Improper transparent union conversion"); (void)ConvTy; break; } case ICK_Zero_Event_Conversion: case ICK_Zero_Queue_Conversion: From = ImpCastExprToType(From, ToType, CK_ZeroToOCLOpaqueType, From->getValueKind()).get(); break; case ICK_Lvalue_To_Rvalue: case ICK_Array_To_Pointer: case ICK_Function_To_Pointer: case ICK_Function_Conversion: case ICK_Qualification: case ICK_Num_Conversion_Kinds: case ICK_C_Only_Conversion: case ICK_Incompatible_Pointer_Conversion: llvm_unreachable("Improper second standard conversion"); } switch (SCS.Third) { case ICK_Identity: // Nothing to do. break; case ICK_Function_Conversion: // If both sides are functions (or pointers/references to them), there could // be incompatible exception declarations. if (CheckExceptionSpecCompatibility(From, ToType)) return ExprError(); From = ImpCastExprToType(From, ToType, CK_NoOp, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Qualification: { - // The qualification keeps the category of the inner expression, unless the - // target type isn't a reference. - ExprValueKind VK = - ToType->isReferenceType() ? From->getValueKind() : VK_RValue; - + ExprValueKind VK = From->getValueKind(); CastKind CK = CK_NoOp; if (ToType->isReferenceType() && ToType->getPointeeType().getAddressSpace() != From->getType().getAddressSpace()) CK = CK_AddressSpaceConversion; if (ToType->isPointerType() && ToType->getPointeeType().getAddressSpace() != From->getType()->getPointeeType().getAddressSpace()) CK = CK_AddressSpaceConversion; From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context), CK, VK, /*BasePath=*/nullptr, CCK) .get(); if (SCS.DeprecatedStringLiteralToCharPtr && !getLangOpts().WritableStrings) { Diag(From->getBeginLoc(), getLangOpts().CPlusPlus11 ? diag::ext_deprecated_string_literal_conversion : diag::warn_deprecated_string_literal_conversion) << ToType.getNonReferenceType(); } break; } default: llvm_unreachable("Improper third standard conversion"); } // If this conversion sequence involved a scalar -> atomic conversion, perform // that conversion now. if (!ToAtomicType.isNull()) { assert(Context.hasSameType( ToAtomicType->castAs()->getValueType(), From->getType())); From = ImpCastExprToType(From, ToAtomicType, CK_NonAtomicToAtomic, VK_RValue, nullptr, CCK).get(); } // If this conversion sequence succeeded and involved implicitly converting a // _Nullable type to a _Nonnull one, complain. if (!isCast(CCK)) diagnoseNullableToNonnullConversion(ToType, InitialFromType, From->getBeginLoc()); return From; } /// Check the completeness of a type in a unary type trait. /// /// If the particular type trait requires a complete type, tries to complete /// it. If completing the type fails, a diagnostic is emitted and false /// returned. If completing the type succeeds or no completion was required, /// returns true. static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, SourceLocation Loc, QualType ArgTy) { // C++0x [meta.unary.prop]p3: // For all of the class templates X declared in this Clause, instantiating // that template with a template argument that is a class template // specialization may result in the implicit instantiation of the template // argument if and only if the semantics of X require that the argument // must be a complete type. // We apply this rule to all the type trait expressions used to implement // these class templates. We also try to follow any GCC documented behavior // in these expressions to ensure portability of standard libraries. switch (UTT) { default: llvm_unreachable("not a UTT"); // is_complete_type somewhat obviously cannot require a complete type. case UTT_IsCompleteType: // Fall-through // These traits are modeled on the type predicates in C++0x // [meta.unary.cat] and [meta.unary.comp]. They are not specified as // requiring a complete type, as whether or not they return true cannot be // impacted by the completeness of the type. case UTT_IsVoid: case UTT_IsIntegral: case UTT_IsFloatingPoint: case UTT_IsArray: case UTT_IsPointer: case UTT_IsLvalueReference: case UTT_IsRvalueReference: case UTT_IsMemberFunctionPointer: case UTT_IsMemberObjectPointer: case UTT_IsEnum: case UTT_IsUnion: case UTT_IsClass: case UTT_IsFunction: case UTT_IsReference: case UTT_IsArithmetic: case UTT_IsFundamental: case UTT_IsObject: case UTT_IsScalar: case UTT_IsCompound: case UTT_IsMemberPointer: // Fall-through // These traits are modeled on type predicates in C++0x [meta.unary.prop] // which requires some of its traits to have the complete type. However, // the completeness of the type cannot impact these traits' semantics, and // so they don't require it. This matches the comments on these traits in // Table 49. case UTT_IsConst: case UTT_IsVolatile: case UTT_IsSigned: case UTT_IsUnsigned: // This type trait always returns false, checking the type is moot. case UTT_IsInterfaceClass: return true; // C++14 [meta.unary.prop]: // If T is a non-union class type, T shall be a complete type. case UTT_IsEmpty: case UTT_IsPolymorphic: case UTT_IsAbstract: if (const auto *RD = ArgTy->getAsCXXRecordDecl()) if (!RD->isUnion()) return !S.RequireCompleteType( Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr); return true; // C++14 [meta.unary.prop]: // If T is a class type, T shall be a complete type. case UTT_IsFinal: case UTT_IsSealed: if (ArgTy->getAsCXXRecordDecl()) return !S.RequireCompleteType( Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr); return true; // C++1z [meta.unary.prop]: // remove_all_extents_t shall be a complete type or cv void. case UTT_IsAggregate: case UTT_IsTrivial: case UTT_IsTriviallyCopyable: case UTT_IsStandardLayout: case UTT_IsPOD: case UTT_IsLiteral: // Per the GCC type traits documentation, T shall be a complete type, cv void, // or an array of unknown bound. But GCC actually imposes the same constraints // as above. case UTT_HasNothrowAssign: case UTT_HasNothrowMoveAssign: case UTT_HasNothrowConstructor: case UTT_HasNothrowCopy: case UTT_HasTrivialAssign: case UTT_HasTrivialMoveAssign: case UTT_HasTrivialDefaultConstructor: case UTT_HasTrivialMoveConstructor: case UTT_HasTrivialCopy: case UTT_HasTrivialDestructor: case UTT_HasVirtualDestructor: ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0); LLVM_FALLTHROUGH; // C++1z [meta.unary.prop]: // T shall be a complete type, cv void, or an array of unknown bound. case UTT_IsDestructible: case UTT_IsNothrowDestructible: case UTT_IsTriviallyDestructible: case UTT_HasUniqueObjectRepresentations: if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType()) return true; return !S.RequireCompleteType( Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr); } } static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op, Sema &Self, SourceLocation KeyLoc, ASTContext &C, bool (CXXRecordDecl::*HasTrivial)() const, bool (CXXRecordDecl::*HasNonTrivial)() const, bool (CXXMethodDecl::*IsDesiredOp)() const) { CXXRecordDecl *RD = cast(RT->getDecl()); if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)()) return true; DeclarationName Name = C.DeclarationNames.getCXXOperatorName(Op); DeclarationNameInfo NameInfo(Name, KeyLoc); LookupResult Res(Self, NameInfo, Sema::LookupOrdinaryName); if (Self.LookupQualifiedName(Res, RD)) { bool FoundOperator = false; Res.suppressDiagnostics(); for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end(); Op != OpEnd; ++Op) { if (isa(*Op)) continue; CXXMethodDecl *Operator = cast(*Op); if((Operator->*IsDesiredOp)()) { FoundOperator = true; const FunctionProtoType *CPT = Operator->getType()->getAs(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); if (!CPT || !CPT->isNothrow()) return false; } } return FoundOperator; } return false; } static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, SourceLocation KeyLoc, QualType T) { assert(!T->isDependentType() && "Cannot evaluate traits of dependent type"); ASTContext &C = Self.Context; switch(UTT) { default: llvm_unreachable("not a UTT"); // Type trait expressions corresponding to the primary type category // predicates in C++0x [meta.unary.cat]. case UTT_IsVoid: return T->isVoidType(); case UTT_IsIntegral: return T->isIntegralType(C); case UTT_IsFloatingPoint: return T->isFloatingType(); case UTT_IsArray: return T->isArrayType(); case UTT_IsPointer: return T->isPointerType(); case UTT_IsLvalueReference: return T->isLValueReferenceType(); case UTT_IsRvalueReference: return T->isRValueReferenceType(); case UTT_IsMemberFunctionPointer: return T->isMemberFunctionPointerType(); case UTT_IsMemberObjectPointer: return T->isMemberDataPointerType(); case UTT_IsEnum: return T->isEnumeralType(); case UTT_IsUnion: return T->isUnionType(); case UTT_IsClass: return T->isClassType() || T->isStructureType() || T->isInterfaceType(); case UTT_IsFunction: return T->isFunctionType(); // Type trait expressions which correspond to the convenient composition // predicates in C++0x [meta.unary.comp]. case UTT_IsReference: return T->isReferenceType(); case UTT_IsArithmetic: return T->isArithmeticType() && !T->isEnumeralType(); case UTT_IsFundamental: return T->isFundamentalType(); case UTT_IsObject: return T->isObjectType(); case UTT_IsScalar: // Note: semantic analysis depends on Objective-C lifetime types to be // considered scalar types. However, such types do not actually behave // like scalar types at run time (since they may require retain/release // operations), so we report them as non-scalar. if (T->isObjCLifetimeType()) { switch (T.getObjCLifetime()) { case Qualifiers::OCL_None: case Qualifiers::OCL_ExplicitNone: return true; case Qualifiers::OCL_Strong: case Qualifiers::OCL_Weak: case Qualifiers::OCL_Autoreleasing: return false; } } return T->isScalarType(); case UTT_IsCompound: return T->isCompoundType(); case UTT_IsMemberPointer: return T->isMemberPointerType(); // Type trait expressions which correspond to the type property predicates // in C++0x [meta.unary.prop]. case UTT_IsConst: return T.isConstQualified(); case UTT_IsVolatile: return T.isVolatileQualified(); case UTT_IsTrivial: return T.isTrivialType(C); case UTT_IsTriviallyCopyable: return T.isTriviallyCopyableType(C); case UTT_IsStandardLayout: return T->isStandardLayoutType(); case UTT_IsPOD: return T.isPODType(C); case UTT_IsLiteral: return T->isLiteralType(C); case UTT_IsEmpty: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return !RD->isUnion() && RD->isEmpty(); return false; case UTT_IsPolymorphic: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return !RD->isUnion() && RD->isPolymorphic(); return false; case UTT_IsAbstract: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return !RD->isUnion() && RD->isAbstract(); return false; case UTT_IsAggregate: // Report vector extensions and complex types as aggregates because they // support aggregate initialization. GCC mirrors this behavior for vectors // but not _Complex. return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() || T->isAnyComplexType(); // __is_interface_class only returns true when CL is invoked in /CLR mode and // even then only when it is used with the 'interface struct ...' syntax // Clang doesn't support /CLR which makes this type trait moot. case UTT_IsInterfaceClass: return false; case UTT_IsFinal: case UTT_IsSealed: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return RD->hasAttr(); return false; case UTT_IsSigned: // Enum types should always return false. // Floating points should always return true. return !T->isEnumeralType() && (T->isFloatingType() || T->isSignedIntegerType()); case UTT_IsUnsigned: return T->isUnsignedIntegerType(); // Type trait expressions which query classes regarding their construction, // destruction, and copying. Rather than being based directly on the // related type predicates in the standard, they are specified by both // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those // specifications. // // 1: http://gcc.gnu/.org/onlinedocs/gcc/Type-Traits.html // 2: http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index // // Note that these builtins do not behave as documented in g++: if a class // has both a trivial and a non-trivial special member of a particular kind, // they return false! For now, we emulate this behavior. // FIXME: This appears to be a g++ bug: more complex cases reveal that it // does not correctly compute triviality in the presence of multiple special // members of the same kind. Revisit this once the g++ bug is fixed. case UTT_HasTrivialDefaultConstructor: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If __is_pod (type) is true then the trait is true, else if type is // a cv class or union type (or array thereof) with a trivial default // constructor ([class.ctor]) then the trait is true, else it is false. if (T.isPODType(C)) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) return RD->hasTrivialDefaultConstructor() && !RD->hasNonTrivialDefaultConstructor(); return false; case UTT_HasTrivialMoveConstructor: // This trait is implemented by MSVC 2012 and needed to parse the // standard library headers. Specifically this is used as the logic // behind std::is_trivially_move_constructible (20.9.4.3). if (T.isPODType(C)) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) return RD->hasTrivialMoveConstructor() && !RD->hasNonTrivialMoveConstructor(); return false; case UTT_HasTrivialCopy: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If __is_pod (type) is true or type is a reference type then // the trait is true, else if type is a cv class or union type // with a trivial copy constructor ([class.copy]) then the trait // is true, else it is false. if (T.isPODType(C) || T->isReferenceType()) return true; if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return RD->hasTrivialCopyConstructor() && !RD->hasNonTrivialCopyConstructor(); return false; case UTT_HasTrivialMoveAssign: // This trait is implemented by MSVC 2012 and needed to parse the // standard library headers. Specifically it is used as the logic // behind std::is_trivially_move_assignable (20.9.4.3) if (T.isPODType(C)) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) return RD->hasTrivialMoveAssignment() && !RD->hasNonTrivialMoveAssignment(); return false; case UTT_HasTrivialAssign: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If type is const qualified or is a reference type then the // trait is false. Otherwise if __is_pod (type) is true then the // trait is true, else if type is a cv class or union type with // a trivial copy assignment ([class.copy]) then the trait is // true, else it is false. // Note: the const and reference restrictions are interesting, // given that const and reference members don't prevent a class // from having a trivial copy assignment operator (but do cause // errors if the copy assignment operator is actually used, q.v. // [class.copy]p12). if (T.isConstQualified()) return false; if (T.isPODType(C)) return true; if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return RD->hasTrivialCopyAssignment() && !RD->hasNonTrivialCopyAssignment(); return false; case UTT_IsDestructible: case UTT_IsTriviallyDestructible: case UTT_IsNothrowDestructible: // C++14 [meta.unary.prop]: // For reference types, is_destructible::value is true. if (T->isReferenceType()) return true; // Objective-C++ ARC: autorelease types don't require destruction. if (T->isObjCLifetimeType() && T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) return true; // C++14 [meta.unary.prop]: // For incomplete types and function types, is_destructible::value is // false. if (T->isIncompleteType() || T->isFunctionType()) return false; // A type that requires destruction (via a non-trivial destructor or ARC // lifetime semantics) is not trivially-destructible. if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType()) return false; // C++14 [meta.unary.prop]: // For object types and given U equal to remove_all_extents_t, if the // expression std::declval().~U() is well-formed when treated as an // unevaluated operand (Clause 5), then is_destructible::value is true if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) { CXXDestructorDecl *Destructor = Self.LookupDestructor(RD); if (!Destructor) return false; // C++14 [dcl.fct.def.delete]p2: // A program that refers to a deleted function implicitly or // explicitly, other than to declare it, is ill-formed. if (Destructor->isDeleted()) return false; if (C.getLangOpts().AccessControl && Destructor->getAccess() != AS_public) return false; if (UTT == UTT_IsNothrowDestructible) { const FunctionProtoType *CPT = Destructor->getType()->getAs(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); if (!CPT || !CPT->isNothrow()) return false; } } return true; case UTT_HasTrivialDestructor: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html // If __is_pod (type) is true or type is a reference type // then the trait is true, else if type is a cv class or union // type (or array thereof) with a trivial destructor // ([class.dtor]) then the trait is true, else it is // false. if (T.isPODType(C) || T->isReferenceType()) return true; // Objective-C++ ARC: autorelease types don't require destruction. if (T->isObjCLifetimeType() && T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) return RD->hasTrivialDestructor(); return false; // TODO: Propagate nothrowness for implicitly declared special members. case UTT_HasNothrowAssign: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If type is const qualified or is a reference type then the // trait is false. Otherwise if __has_trivial_assign (type) // is true then the trait is true, else if type is a cv class // or union type with copy assignment operators that are known // not to throw an exception then the trait is true, else it is // false. if (C.getBaseElementType(T).isConstQualified()) return false; if (T->isReferenceType()) return false; if (T.isPODType(C) || T->isObjCLifetimeType()) return true; if (const RecordType *RT = T->getAs()) return HasNoThrowOperator(RT, OO_Equal, Self, KeyLoc, C, &CXXRecordDecl::hasTrivialCopyAssignment, &CXXRecordDecl::hasNonTrivialCopyAssignment, &CXXMethodDecl::isCopyAssignmentOperator); return false; case UTT_HasNothrowMoveAssign: // This trait is implemented by MSVC 2012 and needed to parse the // standard library headers. Specifically this is used as the logic // behind std::is_nothrow_move_assignable (20.9.4.3). if (T.isPODType(C)) return true; if (const RecordType *RT = C.getBaseElementType(T)->getAs()) return HasNoThrowOperator(RT, OO_Equal, Self, KeyLoc, C, &CXXRecordDecl::hasTrivialMoveAssignment, &CXXRecordDecl::hasNonTrivialMoveAssignment, &CXXMethodDecl::isMoveAssignmentOperator); return false; case UTT_HasNothrowCopy: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If __has_trivial_copy (type) is true then the trait is true, else // if type is a cv class or union type with copy constructors that are // known not to throw an exception then the trait is true, else it is // false. if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType()) return true; if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) { if (RD->hasTrivialCopyConstructor() && !RD->hasNonTrivialCopyConstructor()) return true; bool FoundConstructor = false; unsigned FoundTQs; for (const auto *ND : Self.LookupConstructors(RD)) { // A template constructor is never a copy constructor. // FIXME: However, it may actually be selected at the actual overload // resolution point. if (isa(ND->getUnderlyingDecl())) continue; // UsingDecl itself is not a constructor if (isa(ND)) continue; auto *Constructor = cast(ND->getUnderlyingDecl()); if (Constructor->isCopyConstructor(FoundTQs)) { FoundConstructor = true; const FunctionProtoType *CPT = Constructor->getType()->getAs(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); if (!CPT) return false; // TODO: check whether evaluating default arguments can throw. // For now, we'll be conservative and assume that they can throw. if (!CPT->isNothrow() || CPT->getNumParams() > 1) return false; } } return FoundConstructor; } return false; case UTT_HasNothrowConstructor: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html // If __has_trivial_constructor (type) is true then the trait is // true, else if type is a cv class or union type (or array // thereof) with a default constructor that is known not to // throw an exception then the trait is true, else it is false. if (T.isPODType(C) || T->isObjCLifetimeType()) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) { if (RD->hasTrivialDefaultConstructor() && !RD->hasNonTrivialDefaultConstructor()) return true; bool FoundConstructor = false; for (const auto *ND : Self.LookupConstructors(RD)) { // FIXME: In C++0x, a constructor template can be a default constructor. if (isa(ND->getUnderlyingDecl())) continue; // UsingDecl itself is not a constructor if (isa(ND)) continue; auto *Constructor = cast(ND->getUnderlyingDecl()); if (Constructor->isDefaultConstructor()) { FoundConstructor = true; const FunctionProtoType *CPT = Constructor->getType()->getAs(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); if (!CPT) return false; // FIXME: check whether evaluating default arguments can throw. // For now, we'll be conservative and assume that they can throw. if (!CPT->isNothrow() || CPT->getNumParams() > 0) return false; } } return FoundConstructor; } return false; case UTT_HasVirtualDestructor: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If type is a class type with a virtual destructor ([class.dtor]) // then the trait is true, else it is false. if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD)) return Destructor->isVirtual(); return false; // These type trait expressions are modeled on the specifications for the // Embarcadero C++0x type trait functions: // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index case UTT_IsCompleteType: // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_): // Returns True if and only if T is a complete type at the point of the // function call. return !T->isIncompleteType(); case UTT_HasUniqueObjectRepresentations: return C.hasUniqueObjectRepresentations(T); } } static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT, QualType RhsT, SourceLocation KeyLoc); static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef Args, SourceLocation RParenLoc) { if (Kind <= UTT_Last) return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]->getType()); // Evaluate BTT_ReferenceBindsToTemporary alongside the IsConstructible // traits to avoid duplication. if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary) return EvaluateBinaryTypeTrait(S, Kind, Args[0]->getType(), Args[1]->getType(), RParenLoc); switch (Kind) { case clang::BTT_ReferenceBindsToTemporary: case clang::TT_IsConstructible: case clang::TT_IsNothrowConstructible: case clang::TT_IsTriviallyConstructible: { // C++11 [meta.unary.prop]: // is_trivially_constructible is defined as: // // is_constructible::value is true and the variable // definition for is_constructible, as defined below, is known to call // no operation that is not trivial. // // The predicate condition for a template specialization // is_constructible shall be satisfied if and only if the // following variable definition would be well-formed for some invented // variable t: // // T t(create()...); assert(!Args.empty()); // Precondition: T and all types in the parameter pack Args shall be // complete types, (possibly cv-qualified) void, or arrays of // unknown bound. for (const auto *TSI : Args) { QualType ArgTy = TSI->getType(); if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType()) continue; if (S.RequireCompleteType(KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr)) return false; } // Make sure the first argument is not incomplete nor a function type. QualType T = Args[0]->getType(); if (T->isIncompleteType() || T->isFunctionType()) return false; // Make sure the first argument is not an abstract type. CXXRecordDecl *RD = T->getAsCXXRecordDecl(); if (RD && RD->isAbstract()) return false; SmallVector OpaqueArgExprs; SmallVector ArgExprs; ArgExprs.reserve(Args.size() - 1); for (unsigned I = 1, N = Args.size(); I != N; ++I) { QualType ArgTy = Args[I]->getType(); if (ArgTy->isObjectType() || ArgTy->isFunctionType()) ArgTy = S.Context.getRValueReferenceType(ArgTy); OpaqueArgExprs.push_back( OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(), ArgTy.getNonLValueExprType(S.Context), Expr::getValueKindForType(ArgTy))); } for (Expr &E : OpaqueArgExprs) ArgExprs.push_back(&E); // Perform the initialization in an unevaluated context within a SFINAE // trap at translation unit scope. EnterExpressionEvaluationContext Unevaluated( S, Sema::ExpressionEvaluationContext::Unevaluated); Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); InitializedEntity To(InitializedEntity::InitializeTemporary(Args[0])); InitializationKind InitKind(InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc)); InitializationSequence Init(S, To, InitKind, ArgExprs); if (Init.Failed()) return false; ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs); if (Result.isInvalid() || SFINAE.hasErrorOccurred()) return false; if (Kind == clang::TT_IsConstructible) return true; if (Kind == clang::BTT_ReferenceBindsToTemporary) { if (!T->isReferenceType()) return false; return !Init.isDirectReferenceBinding(); } if (Kind == clang::TT_IsNothrowConstructible) return S.canThrow(Result.get()) == CT_Cannot; if (Kind == clang::TT_IsTriviallyConstructible) { // Under Objective-C ARC and Weak, if the destination has non-trivial // Objective-C lifetime, this is a non-trivial construction. if (T.getNonReferenceType().hasNonTrivialObjCLifetime()) return false; // The initialization succeeded; now make sure there are no non-trivial // calls. return !Result.get()->hasNonTrivialCall(S.Context); } llvm_unreachable("unhandled type trait"); return false; } default: llvm_unreachable("not a TT"); } return false; } ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef Args, SourceLocation RParenLoc) { QualType ResultType = Context.getLogicalOperationType(); if (Kind <= UTT_Last && !CheckUnaryTypeTraitTypeCompleteness( *this, Kind, KWLoc, Args[0]->getType())) return ExprError(); bool Dependent = false; for (unsigned I = 0, N = Args.size(); I != N; ++I) { if (Args[I]->getType()->isDependentType()) { Dependent = true; break; } } bool Result = false; if (!Dependent) Result = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc); return TypeTraitExpr::Create(Context, ResultType, KWLoc, Kind, Args, RParenLoc, Result); } ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef Args, SourceLocation RParenLoc) { SmallVector ConvertedArgs; ConvertedArgs.reserve(Args.size()); for (unsigned I = 0, N = Args.size(); I != N; ++I) { TypeSourceInfo *TInfo; QualType T = GetTypeFromParser(Args[I], &TInfo); if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc); ConvertedArgs.push_back(TInfo); } return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc); } static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT, QualType RhsT, SourceLocation KeyLoc) { assert(!LhsT->isDependentType() && !RhsT->isDependentType() && "Cannot evaluate traits of dependent types"); switch(BTT) { case BTT_IsBaseOf: { // C++0x [meta.rel]p2 // Base is a base class of Derived without regard to cv-qualifiers or // Base and Derived are not unions and name the same class type without // regard to cv-qualifiers. const RecordType *lhsRecord = LhsT->getAs(); const RecordType *rhsRecord = RhsT->getAs(); if (!rhsRecord || !lhsRecord) { const ObjCObjectType *LHSObjTy = LhsT->getAs(); const ObjCObjectType *RHSObjTy = RhsT->getAs(); if (!LHSObjTy || !RHSObjTy) return false; ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface(); ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface(); if (!BaseInterface || !DerivedInterface) return false; if (Self.RequireCompleteType( KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr)) return false; return BaseInterface->isSuperClassOf(DerivedInterface); } assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT) == (lhsRecord == rhsRecord)); // Unions are never base classes, and never have base classes. // It doesn't matter if they are complete or not. See PR#41843 if (lhsRecord && lhsRecord->getDecl()->isUnion()) return false; if (rhsRecord && rhsRecord->getDecl()->isUnion()) return false; if (lhsRecord == rhsRecord) return true; // C++0x [meta.rel]p2: // If Base and Derived are class types and are different types // (ignoring possible cv-qualifiers) then Derived shall be a // complete type. if (Self.RequireCompleteType(KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr)) return false; return cast(rhsRecord->getDecl()) ->isDerivedFrom(cast(lhsRecord->getDecl())); } case BTT_IsSame: return Self.Context.hasSameType(LhsT, RhsT); case BTT_TypeCompatible: { // GCC ignores cv-qualifiers on arrays for this builtin. Qualifiers LhsQuals, RhsQuals; QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals); QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals); return Self.Context.typesAreCompatible(Lhs, Rhs); } case BTT_IsConvertible: case BTT_IsConvertibleTo: { // C++0x [meta.rel]p4: // Given the following function prototype: // // template // typename add_rvalue_reference::type create(); // // the predicate condition for a template specialization // is_convertible shall be satisfied if and only if // the return expression in the following code would be // well-formed, including any implicit conversions to the return // type of the function: // // To test() { // return create(); // } // // Access checking is performed as if in a context unrelated to To and // From. Only the validity of the immediate context of the expression // of the return-statement (including conversions to the return type) // is considered. // // We model the initialization as a copy-initialization of a temporary // of the appropriate type, which for this expression is identical to the // return statement (since NRVO doesn't apply). // Functions aren't allowed to return function or array types. if (RhsT->isFunctionType() || RhsT->isArrayType()) return false; // A return statement in a void function must have void type. if (RhsT->isVoidType()) return LhsT->isVoidType(); // A function definition requires a complete, non-abstract return type. if (!Self.isCompleteType(KeyLoc, RhsT) || Self.isAbstractType(KeyLoc, RhsT)) return false; // Compute the result of add_rvalue_reference. if (LhsT->isObjectType() || LhsT->isFunctionType()) LhsT = Self.Context.getRValueReferenceType(LhsT); // Build a fake source and destination for initialization. InitializedEntity To(InitializedEntity::InitializeTemporary(RhsT)); OpaqueValueExpr From(KeyLoc, LhsT.getNonLValueExprType(Self.Context), Expr::getValueKindForType(LhsT)); Expr *FromPtr = &From; InitializationKind Kind(InitializationKind::CreateCopy(KeyLoc, SourceLocation())); // Perform the initialization in an unevaluated context within a SFINAE // trap at translation unit scope. EnterExpressionEvaluationContext Unevaluated( Self, Sema::ExpressionEvaluationContext::Unevaluated); Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true); Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl()); InitializationSequence Init(Self, To, Kind, FromPtr); if (Init.Failed()) return false; ExprResult Result = Init.Perform(Self, To, Kind, FromPtr); return !Result.isInvalid() && !SFINAE.hasErrorOccurred(); } case BTT_IsAssignable: case BTT_IsNothrowAssignable: case BTT_IsTriviallyAssignable: { // C++11 [meta.unary.prop]p3: // is_trivially_assignable is defined as: // is_assignable::value is true and the assignment, as defined by // is_assignable, is known to call no operation that is not trivial // // is_assignable is defined as: // The expression declval() = declval() is well-formed when // treated as an unevaluated operand (Clause 5). // // For both, T and U shall be complete types, (possibly cv-qualified) // void, or arrays of unknown bound. if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() && Self.RequireCompleteType(KeyLoc, LhsT, diag::err_incomplete_type_used_in_type_trait_expr)) return false; if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() && Self.RequireCompleteType(KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr)) return false; // cv void is never assignable. if (LhsT->isVoidType() || RhsT->isVoidType()) return false; // Build expressions that emulate the effect of declval() and // declval(). if (LhsT->isObjectType() || LhsT->isFunctionType()) LhsT = Self.Context.getRValueReferenceType(LhsT); if (RhsT->isObjectType() || RhsT->isFunctionType()) RhsT = Self.Context.getRValueReferenceType(RhsT); OpaqueValueExpr Lhs(KeyLoc, LhsT.getNonLValueExprType(Self.Context), Expr::getValueKindForType(LhsT)); OpaqueValueExpr Rhs(KeyLoc, RhsT.getNonLValueExprType(Self.Context), Expr::getValueKindForType(RhsT)); // Attempt the assignment in an unevaluated context within a SFINAE // trap at translation unit scope. EnterExpressionEvaluationContext Unevaluated( Self, Sema::ExpressionEvaluationContext::Unevaluated); Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true); Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl()); ExprResult Result = Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs); if (Result.isInvalid()) return false; // Treat the assignment as unused for the purpose of -Wdeprecated-volatile. Self.CheckUnusedVolatileAssignment(Result.get()); if (SFINAE.hasErrorOccurred()) return false; if (BTT == BTT_IsAssignable) return true; if (BTT == BTT_IsNothrowAssignable) return Self.canThrow(Result.get()) == CT_Cannot; if (BTT == BTT_IsTriviallyAssignable) { // Under Objective-C ARC and Weak, if the destination has non-trivial // Objective-C lifetime, this is a non-trivial assignment. if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime()) return false; return !Result.get()->hasNonTrivialCall(Self.Context); } llvm_unreachable("unhandled type trait"); return false; } default: llvm_unreachable("not a BTT"); } llvm_unreachable("Unknown type trait or not implemented"); } ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, ParsedType Ty, Expr* DimExpr, SourceLocation RParen) { TypeSourceInfo *TSInfo; QualType T = GetTypeFromParser(Ty, &TSInfo); if (!TSInfo) TSInfo = Context.getTrivialTypeSourceInfo(T); return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen); } static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT, QualType T, Expr *DimExpr, SourceLocation KeyLoc) { assert(!T->isDependentType() && "Cannot evaluate traits of dependent type"); switch(ATT) { case ATT_ArrayRank: if (T->isArrayType()) { unsigned Dim = 0; while (const ArrayType *AT = Self.Context.getAsArrayType(T)) { ++Dim; T = AT->getElementType(); } return Dim; } return 0; case ATT_ArrayExtent: { llvm::APSInt Value; uint64_t Dim; if (Self.VerifyIntegerConstantExpression(DimExpr, &Value, diag::err_dimension_expr_not_constant_integer, false).isInvalid()) return 0; if (Value.isSigned() && Value.isNegative()) { Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer) << DimExpr->getSourceRange(); return 0; } Dim = Value.getLimitedValue(); if (T->isArrayType()) { unsigned D = 0; bool Matched = false; while (const ArrayType *AT = Self.Context.getAsArrayType(T)) { if (Dim == D) { Matched = true; break; } ++D; T = AT->getElementType(); } if (Matched && T->isArrayType()) { if (const ConstantArrayType *CAT = Self.Context.getAsConstantArrayType(T)) return CAT->getSize().getLimitedValue(); } } return 0; } } llvm_unreachable("Unknown type trait or not implemented"); } ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, TypeSourceInfo *TSInfo, Expr* DimExpr, SourceLocation RParen) { QualType T = TSInfo->getType(); // FIXME: This should likely be tracked as an APInt to remove any host // assumptions about the width of size_t on the target. uint64_t Value = 0; if (!T->isDependentType()) Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc); // While the specification for these traits from the Embarcadero C++ // compiler's documentation says the return type is 'unsigned int', Clang // returns 'size_t'. On Windows, the primary platform for the Embarcadero // compiler, there is no difference. On several other platforms this is an // important distinction. return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr, RParen, Context.getSizeType()); } ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen) { // If error parsing the expression, ignore. if (!Queried) return ExprError(); ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen); return Result; } static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E) { switch (ET) { case ET_IsLValueExpr: return E->isLValue(); case ET_IsRValueExpr: return E->isRValue(); } llvm_unreachable("Expression trait not covered by switch"); } ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen) { if (Queried->isTypeDependent()) { // Delay type-checking for type-dependent expressions. } else if (Queried->getType()->isPlaceholderType()) { ExprResult PE = CheckPlaceholderExpr(Queried); if (PE.isInvalid()) return ExprError(); return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen); } bool Value = EvaluateExpressionTrait(ET, Queried); return new (Context) ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy); } QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, SourceLocation Loc, bool isIndirect) { assert(!LHS.get()->getType()->isPlaceholderType() && !RHS.get()->getType()->isPlaceholderType() && "placeholders should have been weeded out by now"); // The LHS undergoes lvalue conversions if this is ->*, and undergoes the // temporary materialization conversion otherwise. if (isIndirect) LHS = DefaultLvalueConversion(LHS.get()); else if (LHS.get()->isRValue()) LHS = TemporaryMaterializationConversion(LHS.get()); if (LHS.isInvalid()) return QualType(); // The RHS always undergoes lvalue conversions. RHS = DefaultLvalueConversion(RHS.get()); if (RHS.isInvalid()) return QualType(); const char *OpSpelling = isIndirect ? "->*" : ".*"; // C++ 5.5p2 // The binary operator .* [p3: ->*] binds its second operand, which shall // be of type "pointer to member of T" (where T is a completely-defined // class type) [...] QualType RHSType = RHS.get()->getType(); const MemberPointerType *MemPtr = RHSType->getAs(); if (!MemPtr) { Diag(Loc, diag::err_bad_memptr_rhs) << OpSpelling << RHSType << RHS.get()->getSourceRange(); return QualType(); } QualType Class(MemPtr->getClass(), 0); // Note: C++ [expr.mptr.oper]p2-3 says that the class type into which the // member pointer points must be completely-defined. However, there is no // reason for this semantic distinction, and the rule is not enforced by // other compilers. Therefore, we do not check this property, as it is // likely to be considered a defect. // C++ 5.5p2 // [...] to its first operand, which shall be of class T or of a class of // which T is an unambiguous and accessible base class. [p3: a pointer to // such a class] QualType LHSType = LHS.get()->getType(); if (isIndirect) { if (const PointerType *Ptr = LHSType->getAs()) LHSType = Ptr->getPointeeType(); else { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << 1 << LHSType << FixItHint::CreateReplacement(SourceRange(Loc), ".*"); return QualType(); } } if (!Context.hasSameUnqualifiedType(Class, LHSType)) { // If we want to check the hierarchy, we need a complete type. if (RequireCompleteType(Loc, LHSType, diag::err_bad_memptr_lhs, OpSpelling, (int)isIndirect)) { return QualType(); } if (!IsDerivedFrom(Loc, LHSType, Class)) { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << (int)isIndirect << LHS.get()->getType(); return QualType(); } CXXCastPath BasePath; if (CheckDerivedToBaseConversion( LHSType, Class, Loc, SourceRange(LHS.get()->getBeginLoc(), RHS.get()->getEndLoc()), &BasePath)) return QualType(); // Cast LHS to type of use. QualType UseType = Context.getQualifiedType(Class, LHSType.getQualifiers()); if (isIndirect) UseType = Context.getPointerType(UseType); ExprValueKind VK = isIndirect ? VK_RValue : LHS.get()->getValueKind(); LHS = ImpCastExprToType(LHS.get(), UseType, CK_DerivedToBase, VK, &BasePath); } if (isa(RHS.get()->IgnoreParens())) { // Diagnose use of pointer-to-member type which when used as // the functional cast in a pointer-to-member expression. Diag(Loc, diag::err_pointer_to_member_type) << isIndirect; return QualType(); } // C++ 5.5p2 // The result is an object or a function of the type specified by the // second operand. // The cv qualifiers are the union of those in the pointer and the left side, // in accordance with 5.5p5 and 5.2.5. QualType Result = MemPtr->getPointeeType(); Result = Context.getCVRQualifiedType(Result, LHSType.getCVRQualifiers()); // C++0x [expr.mptr.oper]p6: // In a .* expression whose object expression is an rvalue, the program is // ill-formed if the second operand is a pointer to member function with // ref-qualifier &. In a ->* expression or in a .* expression whose object // expression is an lvalue, the program is ill-formed if the second operand // is a pointer to member function with ref-qualifier &&. if (const FunctionProtoType *Proto = Result->getAs()) { switch (Proto->getRefQualifier()) { case RQ_None: // Do nothing break; case RQ_LValue: if (!isIndirect && !LHS.get()->Classify(Context).isLValue()) { // C++2a allows functions with ref-qualifier & if their cv-qualifier-seq // is (exactly) 'const'. if (Proto->isConst() && !Proto->isVolatile()) Diag(Loc, getLangOpts().CPlusPlus2a ? diag::warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue : diag::ext_pointer_to_const_ref_member_on_rvalue); else Diag(Loc, diag::err_pointer_to_member_oper_value_classify) << RHSType << 1 << LHS.get()->getSourceRange(); } break; case RQ_RValue: if (isIndirect || !LHS.get()->Classify(Context).isRValue()) Diag(Loc, diag::err_pointer_to_member_oper_value_classify) << RHSType << 0 << LHS.get()->getSourceRange(); break; } } // C++ [expr.mptr.oper]p6: // The result of a .* expression whose second operand is a pointer // to a data member is of the same value category as its // first operand. The result of a .* expression whose second // operand is a pointer to a member function is a prvalue. The // result of an ->* expression is an lvalue if its second operand // is a pointer to data member and a prvalue otherwise. if (Result->isFunctionType()) { VK = VK_RValue; return Context.BoundMemberTy; } else if (isIndirect) { VK = VK_LValue; } else { VK = LHS.get()->getValueKind(); } return Result; } /// Try to convert a type to another according to C++11 5.16p3. /// /// This is part of the parameter validation for the ? operator. If either /// value operand is a class type, the two operands are attempted to be /// converted to each other. This function does the conversion in one direction. /// It returns true if the program is ill-formed and has already been diagnosed /// as such. static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, SourceLocation QuestionLoc, bool &HaveConversion, QualType &ToType) { HaveConversion = false; ToType = To->getType(); InitializationKind Kind = InitializationKind::CreateCopy(To->getBeginLoc(), SourceLocation()); // C++11 5.16p3 // The process for determining whether an operand expression E1 of type T1 // can be converted to match an operand expression E2 of type T2 is defined // as follows: // -- If E2 is an lvalue: E1 can be converted to match E2 if E1 can be // implicitly converted to type "lvalue reference to T2", subject to the // constraint that in the conversion the reference must bind directly to // an lvalue. // -- If E2 is an xvalue: E1 can be converted to match E2 if E1 can be // implicitly converted to the type "rvalue reference to R2", subject to // the constraint that the reference must bind directly. if (To->isLValue() || To->isXValue()) { QualType T = To->isLValue() ? Self.Context.getLValueReferenceType(ToType) : Self.Context.getRValueReferenceType(ToType); InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); InitializationSequence InitSeq(Self, Entity, Kind, From); if (InitSeq.isDirectReferenceBinding()) { ToType = T; HaveConversion = true; return false; } if (InitSeq.isAmbiguous()) return InitSeq.Diagnose(Self, Entity, Kind, From); } // -- If E2 is an rvalue, or if the conversion above cannot be done: // -- if E1 and E2 have class type, and the underlying class types are // the same or one is a base class of the other: QualType FTy = From->getType(); QualType TTy = To->getType(); const RecordType *FRec = FTy->getAs(); const RecordType *TRec = TTy->getAs(); bool FDerivedFromT = FRec && TRec && FRec != TRec && Self.IsDerivedFrom(QuestionLoc, FTy, TTy); if (FRec && TRec && (FRec == TRec || FDerivedFromT || Self.IsDerivedFrom(QuestionLoc, TTy, FTy))) { // E1 can be converted to match E2 if the class of T2 is the // same type as, or a base class of, the class of T1, and // [cv2 > cv1]. if (FRec == TRec || FDerivedFromT) { if (TTy.isAtLeastAsQualifiedAs(FTy)) { InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy); InitializationSequence InitSeq(Self, Entity, Kind, From); if (InitSeq) { HaveConversion = true; return false; } if (InitSeq.isAmbiguous()) return InitSeq.Diagnose(Self, Entity, Kind, From); } } return false; } // -- Otherwise: E1 can be converted to match E2 if E1 can be // implicitly converted to the type that expression E2 would have // if E2 were converted to an rvalue (or the type it has, if E2 is // an rvalue). // // This actually refers very narrowly to the lvalue-to-rvalue conversion, not // to the array-to-pointer or function-to-pointer conversions. TTy = TTy.getNonLValueExprType(Self.Context); InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy); InitializationSequence InitSeq(Self, Entity, Kind, From); HaveConversion = !InitSeq.Failed(); ToType = TTy; if (InitSeq.isAmbiguous()) return InitSeq.Diagnose(Self, Entity, Kind, From); return false; } /// Try to find a common type for two according to C++0x 5.16p5. /// /// This is part of the parameter validation for the ? operator. If either /// value operand is a class type, overload resolution is used to find a /// conversion to a common type. static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc) { Expr *Args[2] = { LHS.get(), RHS.get() }; OverloadCandidateSet CandidateSet(QuestionLoc, OverloadCandidateSet::CSK_Operator); Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args, CandidateSet); OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(Self, QuestionLoc, Best)) { case OR_Success: { // We found a match. Perform the conversions on the arguments and move on. ExprResult LHSRes = Self.PerformImplicitConversion( LHS.get(), Best->BuiltinParamTypes[0], Best->Conversions[0], Sema::AA_Converting); if (LHSRes.isInvalid()) break; LHS = LHSRes; ExprResult RHSRes = Self.PerformImplicitConversion( RHS.get(), Best->BuiltinParamTypes[1], Best->Conversions[1], Sema::AA_Converting); if (RHSRes.isInvalid()) break; RHS = RHSRes; if (Best->Function) Self.MarkFunctionReferenced(QuestionLoc, Best->Function); return false; } case OR_No_Viable_Function: // Emit a better diagnostic if one of the expressions is a null pointer // constant and the other is a pointer type. In this case, the user most // likely forgot to take the address of the other expression. if (Self.DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc)) return true; Self.Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) << LHS.get()->getType() << RHS.get()->getType() << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return true; case OR_Ambiguous: Self.Diag(QuestionLoc, diag::err_conditional_ambiguous_ovl) << LHS.get()->getType() << RHS.get()->getType() << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); // FIXME: Print the possible common types by printing the return types of // the viable candidates. break; case OR_Deleted: llvm_unreachable("Conditional operator has only built-in overloads"); } return true; } /// Perform an "extended" implicit conversion as returned by /// TryClassUnification. static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) { InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); InitializationKind Kind = InitializationKind::CreateCopy(E.get()->getBeginLoc(), SourceLocation()); Expr *Arg = E.get(); InitializationSequence InitSeq(Self, Entity, Kind, Arg); ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg); if (Result.isInvalid()) return true; E = Result; return false; } // Check the condition operand of ?: to see if it is valid for the GCC // extension. static bool isValidVectorForConditionalCondition(ASTContext &Ctx, QualType CondTy) { if (!CondTy->isVectorType() || CondTy->isExtVectorType()) return false; const QualType EltTy = cast(CondTy.getCanonicalType())->getElementType(); assert(!EltTy->isBooleanType() && !EltTy->isEnumeralType() && "Vectors cant be boolean or enum types"); return EltTy->isIntegralType(Ctx); } QualType Sema::CheckGNUVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc) { LHS = DefaultFunctionArrayLvalueConversion(LHS.get()); RHS = DefaultFunctionArrayLvalueConversion(RHS.get()); QualType CondType = Cond.get()->getType(); const auto *CondVT = CondType->getAs(); QualType CondElementTy = CondVT->getElementType(); unsigned CondElementCount = CondVT->getNumElements(); QualType LHSType = LHS.get()->getType(); const auto *LHSVT = LHSType->getAs(); QualType RHSType = RHS.get()->getType(); const auto *RHSVT = RHSType->getAs(); QualType ResultType; // FIXME: In the future we should define what the Extvector conditional // operator looks like. if (LHSVT && isa(LHSVT)) { Diag(QuestionLoc, diag::err_conditional_vector_operand_type) << /*isExtVector*/ true << LHSType; return {}; } if (RHSVT && isa(RHSVT)) { Diag(QuestionLoc, diag::err_conditional_vector_operand_type) << /*isExtVector*/ true << RHSType; return {}; } if (LHSVT && RHSVT) { // If both are vector types, they must be the same type. if (!Context.hasSameType(LHSType, RHSType)) { Diag(QuestionLoc, diag::err_conditional_vector_mismatched_vectors) << LHSType << RHSType; return {}; } ResultType = LHSType; } else if (LHSVT || RHSVT) { ResultType = CheckVectorOperands( LHS, RHS, QuestionLoc, /*isCompAssign*/ false, /*AllowBothBool*/ true, /*AllowBoolConversions*/ false); if (ResultType.isNull()) return {}; } else { // Both are scalar. QualType ResultElementTy; LHSType = LHSType.getCanonicalType().getUnqualifiedType(); RHSType = RHSType.getCanonicalType().getUnqualifiedType(); if (Context.hasSameType(LHSType, RHSType)) ResultElementTy = LHSType; else ResultElementTy = UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional); if (ResultElementTy->isEnumeralType()) { Diag(QuestionLoc, diag::err_conditional_vector_operand_type) << /*isExtVector*/ false << ResultElementTy; return {}; } ResultType = Context.getVectorType( ResultElementTy, CondType->getAs()->getNumElements(), VectorType::GenericVector); LHS = ImpCastExprToType(LHS.get(), ResultType, CK_VectorSplat); RHS = ImpCastExprToType(RHS.get(), ResultType, CK_VectorSplat); } assert(!ResultType.isNull() && ResultType->isVectorType() && "Result should have been a vector type"); QualType ResultElementTy = ResultType->getAs()->getElementType(); unsigned ResultElementCount = ResultType->getAs()->getNumElements(); if (ResultElementCount != CondElementCount) { Diag(QuestionLoc, diag::err_conditional_vector_size) << CondType << ResultType; return {}; } if (Context.getTypeSize(ResultElementTy) != Context.getTypeSize(CondElementTy)) { Diag(QuestionLoc, diag::err_conditional_vector_element_size) << CondType << ResultType; return {}; } return ResultType; } /// Check the operands of ?: under C++ semantics. /// /// See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y /// extension. In this case, LHS == Cond. (But they're not aliases.) /// /// This function also implements GCC's vector extension for conditionals. /// GCC's vector extension permits the use of a?b:c where the type of /// a is that of a integer vector with the same number of elements and /// size as the vectors of b and c. If one of either b or c is a scalar /// it is implicitly converted to match the type of the vector. /// Otherwise the expression is ill-formed. If both b and c are scalars, /// then b and c are checked and converted to the type of a if possible. /// Unlike the OpenCL ?: operator, the expression is evaluated as /// (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]). QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc) { // FIXME: Handle C99's complex types, block pointers and Obj-C++ interface // pointers. // Assume r-value. VK = VK_RValue; OK = OK_Ordinary; bool IsVectorConditional = isValidVectorForConditionalCondition(Context, Cond.get()->getType()); // C++11 [expr.cond]p1 // The first expression is contextually converted to bool. if (!Cond.get()->isTypeDependent()) { ExprResult CondRes = IsVectorConditional ? DefaultFunctionArrayLvalueConversion(Cond.get()) : CheckCXXBooleanCondition(Cond.get()); if (CondRes.isInvalid()) return QualType(); Cond = CondRes; } else { // To implement C++, the first expression typically doesn't alter the result // type of the conditional, however the GCC compatible vector extension // changes the result type to be that of the conditional. Since we cannot // know if this is a vector extension here, delay the conversion of the // LHS/RHS below until later. return Context.DependentTy; } // Either of the arguments dependent? if (LHS.get()->isTypeDependent() || RHS.get()->isTypeDependent()) return Context.DependentTy; // C++11 [expr.cond]p2 // If either the second or the third operand has type (cv) void, ... QualType LTy = LHS.get()->getType(); QualType RTy = RHS.get()->getType(); bool LVoid = LTy->isVoidType(); bool RVoid = RTy->isVoidType(); if (LVoid || RVoid) { // ... one of the following shall hold: // -- The second or the third operand (but not both) is a (possibly // parenthesized) throw-expression; the result is of the type // and value category of the other. bool LThrow = isa(LHS.get()->IgnoreParenImpCasts()); bool RThrow = isa(RHS.get()->IgnoreParenImpCasts()); // Void expressions aren't legal in the vector-conditional expressions. if (IsVectorConditional) { SourceRange DiagLoc = LVoid ? LHS.get()->getSourceRange() : RHS.get()->getSourceRange(); bool IsThrow = LVoid ? LThrow : RThrow; Diag(DiagLoc.getBegin(), diag::err_conditional_vector_has_void) << DiagLoc << IsThrow; return QualType(); } if (LThrow != RThrow) { Expr *NonThrow = LThrow ? RHS.get() : LHS.get(); VK = NonThrow->getValueKind(); // DR (no number yet): the result is a bit-field if the // non-throw-expression operand is a bit-field. OK = NonThrow->getObjectKind(); return NonThrow->getType(); } // -- Both the second and third operands have type void; the result is of // type void and is a prvalue. if (LVoid && RVoid) return Context.VoidTy; // Neither holds, error. Diag(QuestionLoc, diag::err_conditional_void_nonvoid) << (LVoid ? RTy : LTy) << (LVoid ? 0 : 1) << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); } // Neither is void. if (IsVectorConditional) return CheckGNUVectorConditionalTypes(Cond, LHS, RHS, QuestionLoc); // C++11 [expr.cond]p3 // Otherwise, if the second and third operand have different types, and // either has (cv) class type [...] an attempt is made to convert each of // those operands to the type of the other. if (!Context.hasSameType(LTy, RTy) && (LTy->isRecordType() || RTy->isRecordType())) { // These return true if a single direction is already ambiguous. QualType L2RType, R2LType; bool HaveL2R, HaveR2L; if (TryClassUnification(*this, LHS.get(), RHS.get(), QuestionLoc, HaveL2R, L2RType)) return QualType(); if (TryClassUnification(*this, RHS.get(), LHS.get(), QuestionLoc, HaveR2L, R2LType)) return QualType(); // If both can be converted, [...] the program is ill-formed. if (HaveL2R && HaveR2L) { Diag(QuestionLoc, diag::err_conditional_ambiguous) << LTy << RTy << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); } // If exactly one conversion is possible, that conversion is applied to // the chosen operand and the converted operands are used in place of the // original operands for the remainder of this section. if (HaveL2R) { if (ConvertForConditional(*this, LHS, L2RType) || LHS.isInvalid()) return QualType(); LTy = LHS.get()->getType(); } else if (HaveR2L) { if (ConvertForConditional(*this, RHS, R2LType) || RHS.isInvalid()) return QualType(); RTy = RHS.get()->getType(); } } // C++11 [expr.cond]p3 // if both are glvalues of the same value category and the same type except // for cv-qualification, an attempt is made to convert each of those // operands to the type of the other. // FIXME: // Resolving a defect in P0012R1: we extend this to cover all cases where // one of the operands is reference-compatible with the other, in order // to support conditionals between functions differing in noexcept. This // will similarly cover difference in array bounds after P0388R4. // FIXME: If LTy and RTy have a composite pointer type, should we convert to // that instead? ExprValueKind LVK = LHS.get()->getValueKind(); ExprValueKind RVK = RHS.get()->getValueKind(); if (!Context.hasSameType(LTy, RTy) && LVK == RVK && LVK != VK_RValue) { // DerivedToBase was already handled by the class-specific case above. // FIXME: Should we allow ObjC conversions here? const ReferenceConversions AllowedConversions = ReferenceConversions::Qualification | ReferenceConversions::NestedQualification | ReferenceConversions::Function; ReferenceConversions RefConv; if (CompareReferenceRelationship(QuestionLoc, LTy, RTy, &RefConv) == Ref_Compatible && !(RefConv & ~AllowedConversions) && // [...] subject to the constraint that the reference must bind // directly [...] !RHS.get()->refersToBitField() && !RHS.get()->refersToVectorElement()) { RHS = ImpCastExprToType(RHS.get(), LTy, CK_NoOp, RVK); RTy = RHS.get()->getType(); } else if (CompareReferenceRelationship(QuestionLoc, RTy, LTy, &RefConv) == Ref_Compatible && !(RefConv & ~AllowedConversions) && !LHS.get()->refersToBitField() && !LHS.get()->refersToVectorElement()) { LHS = ImpCastExprToType(LHS.get(), RTy, CK_NoOp, LVK); LTy = LHS.get()->getType(); } } // C++11 [expr.cond]p4 // If the second and third operands are glvalues of the same value // category and have the same type, the result is of that type and // value category and it is a bit-field if the second or the third // operand is a bit-field, or if both are bit-fields. // We only extend this to bitfields, not to the crazy other kinds of // l-values. bool Same = Context.hasSameType(LTy, RTy); if (Same && LVK == RVK && LVK != VK_RValue && LHS.get()->isOrdinaryOrBitFieldObject() && RHS.get()->isOrdinaryOrBitFieldObject()) { VK = LHS.get()->getValueKind(); if (LHS.get()->getObjectKind() == OK_BitField || RHS.get()->getObjectKind() == OK_BitField) OK = OK_BitField; // If we have function pointer types, unify them anyway to unify their // exception specifications, if any. if (LTy->isFunctionPointerType() || LTy->isMemberFunctionPointerType()) { Qualifiers Qs = LTy.getQualifiers(); LTy = FindCompositePointerType(QuestionLoc, LHS, RHS, /*ConvertArgs*/false); LTy = Context.getQualifiedType(LTy, Qs); assert(!LTy.isNull() && "failed to find composite pointer type for " "canonically equivalent function ptr types"); assert(Context.hasSameType(LTy, RTy) && "bad composite pointer type"); } return LTy; } // C++11 [expr.cond]p5 // Otherwise, the result is a prvalue. If the second and third operands // do not have the same type, and either has (cv) class type, ... if (!Same && (LTy->isRecordType() || RTy->isRecordType())) { // ... overload resolution is used to determine the conversions (if any) // to be applied to the operands. If the overload resolution fails, the // program is ill-formed. if (FindConditionalOverload(*this, LHS, RHS, QuestionLoc)) return QualType(); } // C++11 [expr.cond]p6 // Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard // conversions are performed on the second and third operands. LHS = DefaultFunctionArrayLvalueConversion(LHS.get()); RHS = DefaultFunctionArrayLvalueConversion(RHS.get()); if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); LTy = LHS.get()->getType(); RTy = RHS.get()->getType(); // After those conversions, one of the following shall hold: // -- The second and third operands have the same type; the result // is of that type. If the operands have class type, the result // is a prvalue temporary of the result type, which is // copy-initialized from either the second operand or the third // operand depending on the value of the first operand. if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) { if (LTy->isRecordType()) { // The operands have class type. Make a temporary copy. InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy); ExprResult LHSCopy = PerformCopyInitialization(Entity, SourceLocation(), LHS); if (LHSCopy.isInvalid()) return QualType(); ExprResult RHSCopy = PerformCopyInitialization(Entity, SourceLocation(), RHS); if (RHSCopy.isInvalid()) return QualType(); LHS = LHSCopy; RHS = RHSCopy; } // If we have function pointer types, unify them anyway to unify their // exception specifications, if any. if (LTy->isFunctionPointerType() || LTy->isMemberFunctionPointerType()) { LTy = FindCompositePointerType(QuestionLoc, LHS, RHS); assert(!LTy.isNull() && "failed to find composite pointer type for " "canonically equivalent function ptr types"); } return LTy; } // Extension: conditional operator involving vector types. if (LTy->isVectorType() || RTy->isVectorType()) return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false, /*AllowBothBool*/true, /*AllowBoolConversions*/false); // -- The second and third operands have arithmetic or enumeration type; // the usual arithmetic conversions are performed to bring them to a // common type, and the result is of that type. if (LTy->isArithmeticType() && RTy->isArithmeticType()) { QualType ResTy = UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional); if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); if (ResTy.isNull()) { Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) << LTy << RTy << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); } LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy)); RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy)); return ResTy; } // -- The second and third operands have pointer type, or one has pointer // type and the other is a null pointer constant, or both are null // pointer constants, at least one of which is non-integral; pointer // conversions and qualification conversions are performed to bring them // to their composite pointer type. The result is of the composite // pointer type. // -- The second and third operands have pointer to member type, or one has // pointer to member type and the other is a null pointer constant; // pointer to member conversions and qualification conversions are // performed to bring them to a common type, whose cv-qualification // shall match the cv-qualification of either the second or the third // operand. The result is of the common type. QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS); if (!Composite.isNull()) return Composite; // Similarly, attempt to find composite type of two objective-c pointers. Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc); if (!Composite.isNull()) return Composite; // Check if we are using a null with a non-pointer type. if (DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc)) return QualType(); Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) << LHS.get()->getType() << RHS.get()->getType() << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); } static FunctionProtoType::ExceptionSpecInfo mergeExceptionSpecs(Sema &S, FunctionProtoType::ExceptionSpecInfo ESI1, FunctionProtoType::ExceptionSpecInfo ESI2, SmallVectorImpl &ExceptionTypeStorage) { ExceptionSpecificationType EST1 = ESI1.Type; ExceptionSpecificationType EST2 = ESI2.Type; // If either of them can throw anything, that is the result. if (EST1 == EST_None) return ESI1; if (EST2 == EST_None) return ESI2; if (EST1 == EST_MSAny) return ESI1; if (EST2 == EST_MSAny) return ESI2; if (EST1 == EST_NoexceptFalse) return ESI1; if (EST2 == EST_NoexceptFalse) return ESI2; // If either of them is non-throwing, the result is the other. if (EST1 == EST_NoThrow) return ESI2; if (EST2 == EST_NoThrow) return ESI1; if (EST1 == EST_DynamicNone) return ESI2; if (EST2 == EST_DynamicNone) return ESI1; if (EST1 == EST_BasicNoexcept) return ESI2; if (EST2 == EST_BasicNoexcept) return ESI1; if (EST1 == EST_NoexceptTrue) return ESI2; if (EST2 == EST_NoexceptTrue) return ESI1; // If we're left with value-dependent computed noexcept expressions, we're // stuck. Before C++17, we can just drop the exception specification entirely, // since it's not actually part of the canonical type. And this should never // happen in C++17, because it would mean we were computing the composite // pointer type of dependent types, which should never happen. if (EST1 == EST_DependentNoexcept || EST2 == EST_DependentNoexcept) { assert(!S.getLangOpts().CPlusPlus17 && "computing composite pointer type of dependent types"); return FunctionProtoType::ExceptionSpecInfo(); } // Switch over the possibilities so that people adding new values know to // update this function. switch (EST1) { case EST_None: case EST_DynamicNone: case EST_MSAny: case EST_BasicNoexcept: case EST_DependentNoexcept: case EST_NoexceptFalse: case EST_NoexceptTrue: case EST_NoThrow: llvm_unreachable("handled above"); case EST_Dynamic: { // This is the fun case: both exception specifications are dynamic. Form // the union of the two lists. assert(EST2 == EST_Dynamic && "other cases should already be handled"); llvm::SmallPtrSet Found; for (auto &Exceptions : {ESI1.Exceptions, ESI2.Exceptions}) for (QualType E : Exceptions) if (Found.insert(S.Context.getCanonicalType(E)).second) ExceptionTypeStorage.push_back(E); FunctionProtoType::ExceptionSpecInfo Result(EST_Dynamic); Result.Exceptions = ExceptionTypeStorage; return Result; } case EST_Unevaluated: case EST_Uninstantiated: case EST_Unparsed: llvm_unreachable("shouldn't see unresolved exception specifications here"); } llvm_unreachable("invalid ExceptionSpecificationType"); } /// Find a merged pointer type and convert the two expressions to it. /// /// This finds the composite pointer type for \p E1 and \p E2 according to /// C++2a [expr.type]p3. It converts both expressions to this type and returns /// it. It does not emit diagnostics (FIXME: that's not true if \p ConvertArgs /// is \c true). /// /// \param Loc The location of the operator requiring these two expressions to /// be converted to the composite pointer type. /// /// \param ConvertArgs If \c false, do not convert E1 and E2 to the target type. QualType Sema::FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2, bool ConvertArgs) { assert(getLangOpts().CPlusPlus && "This function assumes C++"); // C++1z [expr]p14: // The composite pointer type of two operands p1 and p2 having types T1 // and T2 QualType T1 = E1->getType(), T2 = E2->getType(); // where at least one is a pointer or pointer to member type or // std::nullptr_t is: bool T1IsPointerLike = T1->isAnyPointerType() || T1->isMemberPointerType() || T1->isNullPtrType(); bool T2IsPointerLike = T2->isAnyPointerType() || T2->isMemberPointerType() || T2->isNullPtrType(); if (!T1IsPointerLike && !T2IsPointerLike) return QualType(); // - if both p1 and p2 are null pointer constants, std::nullptr_t; // This can't actually happen, following the standard, but we also use this // to implement the end of [expr.conv], which hits this case. // // - if either p1 or p2 is a null pointer constant, T2 or T1, respectively; if (T1IsPointerLike && E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { if (ConvertArgs) E2 = ImpCastExprToType(E2, T1, T1->isMemberPointerType() ? CK_NullToMemberPointer : CK_NullToPointer).get(); return T1; } if (T2IsPointerLike && E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { if (ConvertArgs) E1 = ImpCastExprToType(E1, T2, T2->isMemberPointerType() ? CK_NullToMemberPointer : CK_NullToPointer).get(); return T2; } // Now both have to be pointers or member pointers. if (!T1IsPointerLike || !T2IsPointerLike) return QualType(); assert(!T1->isNullPtrType() && !T2->isNullPtrType() && "nullptr_t should be a null pointer constant"); struct Step { enum Kind { Pointer, ObjCPointer, MemberPointer, Array } K; // Qualifiers to apply under the step kind. Qualifiers Quals; /// The class for a pointer-to-member; a constant array type with a bound /// (if any) for an array. const Type *ClassOrBound; Step(Kind K, const Type *ClassOrBound = nullptr) : K(K), Quals(), ClassOrBound(ClassOrBound) {} QualType rebuild(ASTContext &Ctx, QualType T) const { T = Ctx.getQualifiedType(T, Quals); switch (K) { case Pointer: return Ctx.getPointerType(T); case MemberPointer: return Ctx.getMemberPointerType(T, ClassOrBound); case ObjCPointer: return Ctx.getObjCObjectPointerType(T); case Array: if (auto *CAT = cast_or_null(ClassOrBound)) return Ctx.getConstantArrayType(T, CAT->getSize(), nullptr, ArrayType::Normal, 0); else return Ctx.getIncompleteArrayType(T, ArrayType::Normal, 0); } llvm_unreachable("unknown step kind"); } }; SmallVector Steps; // - if T1 is "pointer to cv1 C1" and T2 is "pointer to cv2 C2", where C1 // is reference-related to C2 or C2 is reference-related to C1 (8.6.3), // the cv-combined type of T1 and T2 or the cv-combined type of T2 and T1, // respectively; // - if T1 is "pointer to member of C1 of type cv1 U1" and T2 is "pointer // to member of C2 of type cv2 U2" for some non-function type U, where // C1 is reference-related to C2 or C2 is reference-related to C1, the // cv-combined type of T2 and T1 or the cv-combined type of T1 and T2, // respectively; // - if T1 and T2 are similar types (4.5), the cv-combined type of T1 and // T2; // // Dismantle T1 and T2 to simultaneously determine whether they are similar // and to prepare to form the cv-combined type if so. QualType Composite1 = T1; QualType Composite2 = T2; unsigned NeedConstBefore = 0; while (true) { assert(!Composite1.isNull() && !Composite2.isNull()); Qualifiers Q1, Q2; Composite1 = Context.getUnqualifiedArrayType(Composite1, Q1); Composite2 = Context.getUnqualifiedArrayType(Composite2, Q2); // Top-level qualifiers are ignored. Merge at all lower levels. if (!Steps.empty()) { // Find the qualifier union: (approximately) the unique minimal set of // qualifiers that is compatible with both types. Qualifiers Quals = Qualifiers::fromCVRUMask(Q1.getCVRUQualifiers() | Q2.getCVRUQualifiers()); // Under one level of pointer or pointer-to-member, we can change to an // unambiguous compatible address space. if (Q1.getAddressSpace() == Q2.getAddressSpace()) { Quals.setAddressSpace(Q1.getAddressSpace()); } else if (Steps.size() == 1) { bool MaybeQ1 = Q1.isAddressSpaceSupersetOf(Q2); bool MaybeQ2 = Q2.isAddressSpaceSupersetOf(Q1); if (MaybeQ1 == MaybeQ2) return QualType(); // No unique best address space. Quals.setAddressSpace(MaybeQ1 ? Q1.getAddressSpace() : Q2.getAddressSpace()); } else { return QualType(); } // FIXME: In C, we merge __strong and none to __strong at the top level. if (Q1.getObjCGCAttr() == Q2.getObjCGCAttr()) Quals.setObjCGCAttr(Q1.getObjCGCAttr()); else return QualType(); // Mismatched lifetime qualifiers never compatibly include each other. if (Q1.getObjCLifetime() == Q2.getObjCLifetime()) Quals.setObjCLifetime(Q1.getObjCLifetime()); else return QualType(); Steps.back().Quals = Quals; if (Q1 != Quals || Q2 != Quals) NeedConstBefore = Steps.size() - 1; } // FIXME: Can we unify the following with UnwrapSimilarTypes? const PointerType *Ptr1, *Ptr2; if ((Ptr1 = Composite1->getAs()) && (Ptr2 = Composite2->getAs())) { Composite1 = Ptr1->getPointeeType(); Composite2 = Ptr2->getPointeeType(); Steps.emplace_back(Step::Pointer); continue; } const ObjCObjectPointerType *ObjPtr1, *ObjPtr2; if ((ObjPtr1 = Composite1->getAs()) && (ObjPtr2 = Composite2->getAs())) { Composite1 = ObjPtr1->getPointeeType(); Composite2 = ObjPtr2->getPointeeType(); Steps.emplace_back(Step::ObjCPointer); continue; } const MemberPointerType *MemPtr1, *MemPtr2; if ((MemPtr1 = Composite1->getAs()) && (MemPtr2 = Composite2->getAs())) { Composite1 = MemPtr1->getPointeeType(); Composite2 = MemPtr2->getPointeeType(); // At the top level, we can perform a base-to-derived pointer-to-member // conversion: // // - [...] where C1 is reference-related to C2 or C2 is // reference-related to C1 // // (Note that the only kinds of reference-relatedness in scope here are // "same type or derived from".) At any other level, the class must // exactly match. const Type *Class = nullptr; QualType Cls1(MemPtr1->getClass(), 0); QualType Cls2(MemPtr2->getClass(), 0); if (Context.hasSameType(Cls1, Cls2)) Class = MemPtr1->getClass(); else if (Steps.empty()) Class = IsDerivedFrom(Loc, Cls1, Cls2) ? MemPtr1->getClass() : IsDerivedFrom(Loc, Cls2, Cls1) ? MemPtr2->getClass() : nullptr; if (!Class) return QualType(); Steps.emplace_back(Step::MemberPointer, Class); continue; } // Special case: at the top level, we can decompose an Objective-C pointer // and a 'cv void *'. Unify the qualifiers. if (Steps.empty() && ((Composite1->isVoidPointerType() && Composite2->isObjCObjectPointerType()) || (Composite1->isObjCObjectPointerType() && Composite2->isVoidPointerType()))) { Composite1 = Composite1->getPointeeType(); Composite2 = Composite2->getPointeeType(); Steps.emplace_back(Step::Pointer); continue; } // FIXME: arrays // FIXME: block pointer types? // Cannot unwrap any more types. break; } // - if T1 or T2 is "pointer to noexcept function" and the other type is // "pointer to function", where the function types are otherwise the same, // "pointer to function"; // - if T1 or T2 is "pointer to member of C1 of type function", the other // type is "pointer to member of C2 of type noexcept function", and C1 // is reference-related to C2 or C2 is reference-related to C1, where // the function types are otherwise the same, "pointer to member of C2 of // type function" or "pointer to member of C1 of type function", // respectively; // // We also support 'noreturn' here, so as a Clang extension we generalize the // above to: // // - [Clang] If T1 and T2 are both of type "pointer to function" or // "pointer to member function" and the pointee types can be unified // by a function pointer conversion, that conversion is applied // before checking the following rules. // // We've already unwrapped down to the function types, and we want to merge // rather than just convert, so do this ourselves rather than calling // IsFunctionConversion. // // FIXME: In order to match the standard wording as closely as possible, we // currently only do this under a single level of pointers. Ideally, we would // allow this in general, and set NeedConstBefore to the relevant depth on // the side(s) where we changed anything. If we permit that, we should also // consider this conversion when determining type similarity and model it as // a qualification conversion. if (Steps.size() == 1) { if (auto *FPT1 = Composite1->getAs()) { if (auto *FPT2 = Composite2->getAs()) { FunctionProtoType::ExtProtoInfo EPI1 = FPT1->getExtProtoInfo(); FunctionProtoType::ExtProtoInfo EPI2 = FPT2->getExtProtoInfo(); // The result is noreturn if both operands are. bool Noreturn = EPI1.ExtInfo.getNoReturn() && EPI2.ExtInfo.getNoReturn(); EPI1.ExtInfo = EPI1.ExtInfo.withNoReturn(Noreturn); EPI2.ExtInfo = EPI2.ExtInfo.withNoReturn(Noreturn); // The result is nothrow if both operands are. SmallVector ExceptionTypeStorage; EPI1.ExceptionSpec = EPI2.ExceptionSpec = mergeExceptionSpecs(*this, EPI1.ExceptionSpec, EPI2.ExceptionSpec, ExceptionTypeStorage); Composite1 = Context.getFunctionType(FPT1->getReturnType(), FPT1->getParamTypes(), EPI1); Composite2 = Context.getFunctionType(FPT2->getReturnType(), FPT2->getParamTypes(), EPI2); } } } // There are some more conversions we can perform under exactly one pointer. if (Steps.size() == 1 && Steps.front().K == Step::Pointer && !Context.hasSameType(Composite1, Composite2)) { // - if T1 or T2 is "pointer to cv1 void" and the other type is // "pointer to cv2 T", where T is an object type or void, // "pointer to cv12 void", where cv12 is the union of cv1 and cv2; if (Composite1->isVoidType() && Composite2->isObjectType()) Composite2 = Composite1; else if (Composite2->isVoidType() && Composite1->isObjectType()) Composite1 = Composite2; // - if T1 is "pointer to cv1 C1" and T2 is "pointer to cv2 C2", where C1 // is reference-related to C2 or C2 is reference-related to C1 (8.6.3), // the cv-combined type of T1 and T2 or the cv-combined type of T2 and // T1, respectively; // // The "similar type" handling covers all of this except for the "T1 is a // base class of T2" case in the definition of reference-related. else if (IsDerivedFrom(Loc, Composite1, Composite2)) Composite1 = Composite2; else if (IsDerivedFrom(Loc, Composite2, Composite1)) Composite2 = Composite1; } // At this point, either the inner types are the same or we have failed to // find a composite pointer type. if (!Context.hasSameType(Composite1, Composite2)) return QualType(); // Per C++ [conv.qual]p3, add 'const' to every level before the last // differing qualifier. for (unsigned I = 0; I != NeedConstBefore; ++I) Steps[I].Quals.addConst(); // Rebuild the composite type. QualType Composite = Composite1; for (auto &S : llvm::reverse(Steps)) Composite = S.rebuild(Context, Composite); if (ConvertArgs) { // Convert the expressions to the composite pointer type. InitializedEntity Entity = InitializedEntity::InitializeTemporary(Composite); InitializationKind Kind = InitializationKind::CreateCopy(Loc, SourceLocation()); InitializationSequence E1ToC(*this, Entity, Kind, E1); if (!E1ToC) return QualType(); InitializationSequence E2ToC(*this, Entity, Kind, E2); if (!E2ToC) return QualType(); // FIXME: Let the caller know if these fail to avoid duplicate diagnostics. ExprResult E1Result = E1ToC.Perform(*this, Entity, Kind, E1); if (E1Result.isInvalid()) return QualType(); E1 = E1Result.get(); ExprResult E2Result = E2ToC.Perform(*this, Entity, Kind, E2); if (E2Result.isInvalid()) return QualType(); E2 = E2Result.get(); } return Composite; } ExprResult Sema::MaybeBindToTemporary(Expr *E) { if (!E) return ExprError(); assert(!isa(E) && "Double-bound temporary?"); // If the result is a glvalue, we shouldn't bind it. if (!E->isRValue()) return E; // In ARC, calls that return a retainable type can return retained, // in which case we have to insert a consuming cast. if (getLangOpts().ObjCAutoRefCount && E->getType()->isObjCRetainableType()) { bool ReturnsRetained; // For actual calls, we compute this by examining the type of the // called value. if (CallExpr *Call = dyn_cast(E)) { Expr *Callee = Call->getCallee()->IgnoreParens(); QualType T = Callee->getType(); if (T == Context.BoundMemberTy) { // Handle pointer-to-members. if (BinaryOperator *BinOp = dyn_cast(Callee)) T = BinOp->getRHS()->getType(); else if (MemberExpr *Mem = dyn_cast(Callee)) T = Mem->getMemberDecl()->getType(); } if (const PointerType *Ptr = T->getAs()) T = Ptr->getPointeeType(); else if (const BlockPointerType *Ptr = T->getAs()) T = Ptr->getPointeeType(); else if (const MemberPointerType *MemPtr = T->getAs()) T = MemPtr->getPointeeType(); const FunctionType *FTy = T->getAs(); assert(FTy && "call to value not of function type?"); ReturnsRetained = FTy->getExtInfo().getProducesResult(); // ActOnStmtExpr arranges things so that StmtExprs of retainable // type always produce a +1 object. } else if (isa(E)) { ReturnsRetained = true; // We hit this case with the lambda conversion-to-block optimization; // we don't want any extra casts here. } else if (isa(E) && isa(cast(E)->getSubExpr())) { return E; // For message sends and property references, we try to find an // actual method. FIXME: we should infer retention by selector in // cases where we don't have an actual method. } else { ObjCMethodDecl *D = nullptr; if (ObjCMessageExpr *Send = dyn_cast(E)) { D = Send->getMethodDecl(); } else if (ObjCBoxedExpr *BoxedExpr = dyn_cast(E)) { D = BoxedExpr->getBoxingMethod(); } else if (ObjCArrayLiteral *ArrayLit = dyn_cast(E)) { // Don't do reclaims if we're using the zero-element array // constant. if (ArrayLit->getNumElements() == 0 && Context.getLangOpts().ObjCRuntime.hasEmptyCollections()) return E; D = ArrayLit->getArrayWithObjectsMethod(); } else if (ObjCDictionaryLiteral *DictLit = dyn_cast(E)) { // Don't do reclaims if we're using the zero-element dictionary // constant. if (DictLit->getNumElements() == 0 && Context.getLangOpts().ObjCRuntime.hasEmptyCollections()) return E; D = DictLit->getDictWithObjectsMethod(); } ReturnsRetained = (D && D->hasAttr()); // Don't do reclaims on performSelector calls; despite their // return type, the invoked method doesn't necessarily actually // return an object. if (!ReturnsRetained && D && D->getMethodFamily() == OMF_performSelector) return E; } // Don't reclaim an object of Class type. if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType()) return E; Cleanup.setExprNeedsCleanups(true); CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject : CK_ARCReclaimReturnedObject); return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr, VK_RValue); } if (!getLangOpts().CPlusPlus) return E; // Search for the base element type (cf. ASTContext::getBaseElementType) with // a fast path for the common case that the type is directly a RecordType. const Type *T = Context.getCanonicalType(E->getType().getTypePtr()); const RecordType *RT = nullptr; while (!RT) { switch (T->getTypeClass()) { case Type::Record: RT = cast(T); break; case Type::ConstantArray: case Type::IncompleteArray: case Type::VariableArray: case Type::DependentSizedArray: T = cast(T)->getElementType().getTypePtr(); break; default: return E; } } // That should be enough to guarantee that this type is complete, if we're // not processing a decltype expression. CXXRecordDecl *RD = cast(RT->getDecl()); if (RD->isInvalidDecl() || RD->isDependentContext()) return E; bool IsDecltype = ExprEvalContexts.back().ExprContext == ExpressionEvaluationContextRecord::EK_Decltype; CXXDestructorDecl *Destructor = IsDecltype ? nullptr : LookupDestructor(RD); if (Destructor) { MarkFunctionReferenced(E->getExprLoc(), Destructor); CheckDestructorAccess(E->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_temp) << E->getType()); if (DiagnoseUseOfDecl(Destructor, E->getExprLoc())) return ExprError(); // If destructor is trivial, we can avoid the extra copy. if (Destructor->isTrivial()) return E; // We need a cleanup, but we don't need to remember the temporary. Cleanup.setExprNeedsCleanups(true); } CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor); CXXBindTemporaryExpr *Bind = CXXBindTemporaryExpr::Create(Context, Temp, E); if (IsDecltype) ExprEvalContexts.back().DelayedDecltypeBinds.push_back(Bind); return Bind; } ExprResult Sema::MaybeCreateExprWithCleanups(ExprResult SubExpr) { if (SubExpr.isInvalid()) return ExprError(); return MaybeCreateExprWithCleanups(SubExpr.get()); } Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) { assert(SubExpr && "subexpression can't be null!"); CleanupVarDeclMarking(); unsigned FirstCleanup = ExprEvalContexts.back().NumCleanupObjects; assert(ExprCleanupObjects.size() >= FirstCleanup); assert(Cleanup.exprNeedsCleanups() || ExprCleanupObjects.size() == FirstCleanup); if (!Cleanup.exprNeedsCleanups()) return SubExpr; auto Cleanups = llvm::makeArrayRef(ExprCleanupObjects.begin() + FirstCleanup, ExprCleanupObjects.size() - FirstCleanup); auto *E = ExprWithCleanups::Create( Context, SubExpr, Cleanup.cleanupsHaveSideEffects(), Cleanups); DiscardCleanupsInEvaluationContext(); return E; } Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) { assert(SubStmt && "sub-statement can't be null!"); CleanupVarDeclMarking(); if (!Cleanup.exprNeedsCleanups()) return SubStmt; // FIXME: In order to attach the temporaries, wrap the statement into // a StmtExpr; currently this is only used for asm statements. // This is hacky, either create a new CXXStmtWithTemporaries statement or // a new AsmStmtWithTemporaries. CompoundStmt *CompStmt = CompoundStmt::Create( Context, SubStmt, SourceLocation(), SourceLocation()); Expr *E = new (Context) StmtExpr(CompStmt, Context.VoidTy, SourceLocation(), SourceLocation(), /*FIXME TemplateDepth=*/0); return MaybeCreateExprWithCleanups(E); } /// Process the expression contained within a decltype. For such expressions, /// certain semantic checks on temporaries are delayed until this point, and /// are omitted for the 'topmost' call in the decltype expression. If the /// topmost call bound a temporary, strip that temporary off the expression. ExprResult Sema::ActOnDecltypeExpression(Expr *E) { assert(ExprEvalContexts.back().ExprContext == ExpressionEvaluationContextRecord::EK_Decltype && "not in a decltype expression"); ExprResult Result = CheckPlaceholderExpr(E); if (Result.isInvalid()) return ExprError(); E = Result.get(); // C++11 [expr.call]p11: // If a function call is a prvalue of object type, // -- if the function call is either // -- the operand of a decltype-specifier, or // -- the right operand of a comma operator that is the operand of a // decltype-specifier, // a temporary object is not introduced for the prvalue. // Recursively rebuild ParenExprs and comma expressions to strip out the // outermost CXXBindTemporaryExpr, if any. if (ParenExpr *PE = dyn_cast(E)) { ExprResult SubExpr = ActOnDecltypeExpression(PE->getSubExpr()); if (SubExpr.isInvalid()) return ExprError(); if (SubExpr.get() == PE->getSubExpr()) return E; return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.get()); } if (BinaryOperator *BO = dyn_cast(E)) { if (BO->getOpcode() == BO_Comma) { ExprResult RHS = ActOnDecltypeExpression(BO->getRHS()); if (RHS.isInvalid()) return ExprError(); if (RHS.get() == BO->getRHS()) return E; return new (Context) BinaryOperator( BO->getLHS(), RHS.get(), BO_Comma, BO->getType(), BO->getValueKind(), BO->getObjectKind(), BO->getOperatorLoc(), BO->getFPFeatures()); } } CXXBindTemporaryExpr *TopBind = dyn_cast(E); CallExpr *TopCall = TopBind ? dyn_cast(TopBind->getSubExpr()) : nullptr; if (TopCall) E = TopCall; else TopBind = nullptr; // Disable the special decltype handling now. ExprEvalContexts.back().ExprContext = ExpressionEvaluationContextRecord::EK_Other; Result = CheckUnevaluatedOperand(E); if (Result.isInvalid()) return ExprError(); E = Result.get(); // In MS mode, don't perform any extra checking of call return types within a // decltype expression. if (getLangOpts().MSVCCompat) return E; // Perform the semantic checks we delayed until this point. for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeCalls.size(); I != N; ++I) { CallExpr *Call = ExprEvalContexts.back().DelayedDecltypeCalls[I]; if (Call == TopCall) continue; if (CheckCallReturnType(Call->getCallReturnType(Context), Call->getBeginLoc(), Call, Call->getDirectCallee())) return ExprError(); } // Now all relevant types are complete, check the destructors are accessible // and non-deleted, and annotate them on the temporaries. for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeBinds.size(); I != N; ++I) { CXXBindTemporaryExpr *Bind = ExprEvalContexts.back().DelayedDecltypeBinds[I]; if (Bind == TopBind) continue; CXXTemporary *Temp = Bind->getTemporary(); CXXRecordDecl *RD = Bind->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl(); CXXDestructorDecl *Destructor = LookupDestructor(RD); Temp->setDestructor(Destructor); MarkFunctionReferenced(Bind->getExprLoc(), Destructor); CheckDestructorAccess(Bind->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_temp) << Bind->getType()); if (DiagnoseUseOfDecl(Destructor, Bind->getExprLoc())) return ExprError(); // We need a cleanup, but we don't need to remember the temporary. Cleanup.setExprNeedsCleanups(true); } // Possibly strip off the top CXXBindTemporaryExpr. return E; } /// Note a set of 'operator->' functions that were used for a member access. static void noteOperatorArrows(Sema &S, ArrayRef OperatorArrows) { unsigned SkipStart = OperatorArrows.size(), SkipCount = 0; // FIXME: Make this configurable? unsigned Limit = 9; if (OperatorArrows.size() > Limit) { // Produce Limit-1 normal notes and one 'skipping' note. SkipStart = (Limit - 1) / 2 + (Limit - 1) % 2; SkipCount = OperatorArrows.size() - (Limit - 1); } for (unsigned I = 0; I < OperatorArrows.size(); /**/) { if (I == SkipStart) { S.Diag(OperatorArrows[I]->getLocation(), diag::note_operator_arrows_suppressed) << SkipCount; I += SkipCount; } else { S.Diag(OperatorArrows[I]->getLocation(), diag::note_operator_arrow_here) << OperatorArrows[I]->getCallResultType(); ++I; } } } ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, ParsedType &ObjectType, bool &MayBePseudoDestructor) { // Since this might be a postfix expression, get rid of ParenListExprs. ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base); if (Result.isInvalid()) return ExprError(); Base = Result.get(); Result = CheckPlaceholderExpr(Base); if (Result.isInvalid()) return ExprError(); Base = Result.get(); QualType BaseType = Base->getType(); MayBePseudoDestructor = false; if (BaseType->isDependentType()) { // If we have a pointer to a dependent type and are using the -> operator, // the object type is the type that the pointer points to. We might still // have enough information about that type to do something useful. if (OpKind == tok::arrow) if (const PointerType *Ptr = BaseType->getAs()) BaseType = Ptr->getPointeeType(); ObjectType = ParsedType::make(BaseType); MayBePseudoDestructor = true; return Base; } // C++ [over.match.oper]p8: // [...] When operator->returns, the operator-> is applied to the value // returned, with the original second operand. if (OpKind == tok::arrow) { QualType StartingType = BaseType; bool NoArrowOperatorFound = false; bool FirstIteration = true; FunctionDecl *CurFD = dyn_cast(CurContext); // The set of types we've considered so far. llvm::SmallPtrSet CTypes; SmallVector OperatorArrows; CTypes.insert(Context.getCanonicalType(BaseType)); while (BaseType->isRecordType()) { if (OperatorArrows.size() >= getLangOpts().ArrowDepth) { Diag(OpLoc, diag::err_operator_arrow_depth_exceeded) << StartingType << getLangOpts().ArrowDepth << Base->getSourceRange(); noteOperatorArrows(*this, OperatorArrows); Diag(OpLoc, diag::note_operator_arrow_depth) << getLangOpts().ArrowDepth; return ExprError(); } Result = BuildOverloadedArrowExpr( S, Base, OpLoc, // When in a template specialization and on the first loop iteration, // potentially give the default diagnostic (with the fixit in a // separate note) instead of having the error reported back to here // and giving a diagnostic with a fixit attached to the error itself. (FirstIteration && CurFD && CurFD->isFunctionTemplateSpecialization()) ? nullptr : &NoArrowOperatorFound); if (Result.isInvalid()) { if (NoArrowOperatorFound) { if (FirstIteration) { Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) << BaseType << 1 << Base->getSourceRange() << FixItHint::CreateReplacement(OpLoc, "."); OpKind = tok::period; break; } Diag(OpLoc, diag::err_typecheck_member_reference_arrow) << BaseType << Base->getSourceRange(); CallExpr *CE = dyn_cast(Base); if (Decl *CD = (CE ? CE->getCalleeDecl() : nullptr)) { Diag(CD->getBeginLoc(), diag::note_member_reference_arrow_from_operator_arrow); } } return ExprError(); } Base = Result.get(); if (CXXOperatorCallExpr *OpCall = dyn_cast(Base)) OperatorArrows.push_back(OpCall->getDirectCallee()); BaseType = Base->getType(); CanQualType CBaseType = Context.getCanonicalType(BaseType); if (!CTypes.insert(CBaseType).second) { Diag(OpLoc, diag::err_operator_arrow_circular) << StartingType; noteOperatorArrows(*this, OperatorArrows); return ExprError(); } FirstIteration = false; } if (OpKind == tok::arrow) { if (BaseType->isPointerType()) BaseType = BaseType->getPointeeType(); else if (auto *AT = Context.getAsArrayType(BaseType)) BaseType = AT->getElementType(); } } // Objective-C properties allow "." access on Objective-C pointer types, // so adjust the base type to the object type itself. if (BaseType->isObjCObjectPointerType()) BaseType = BaseType->getPointeeType(); // C++ [basic.lookup.classref]p2: // [...] If the type of the object expression is of pointer to scalar // type, the unqualified-id is looked up in the context of the complete // postfix-expression. // // This also indicates that we could be parsing a pseudo-destructor-name. // Note that Objective-C class and object types can be pseudo-destructor // expressions or normal member (ivar or property) access expressions, and // it's legal for the type to be incomplete if this is a pseudo-destructor // call. We'll do more incomplete-type checks later in the lookup process, // so just skip this check for ObjC types. if (!BaseType->isRecordType()) { ObjectType = ParsedType::make(BaseType); MayBePseudoDestructor = true; return Base; } // The object type must be complete (or dependent), or // C++11 [expr.prim.general]p3: // Unlike the object expression in other contexts, *this is not required to // be of complete type for purposes of class member access (5.2.5) outside // the member function body. if (!BaseType->isDependentType() && !isThisOutsideMemberFunctionBody(BaseType) && RequireCompleteType(OpLoc, BaseType, diag::err_incomplete_member_access)) return ExprError(); // C++ [basic.lookup.classref]p2: // If the id-expression in a class member access (5.2.5) is an // unqualified-id, and the type of the object expression is of a class // type C (or of pointer to a class type C), the unqualified-id is looked // up in the scope of class C. [...] ObjectType = ParsedType::make(BaseType); return Base; } static bool CheckArrow(Sema& S, QualType& ObjectType, Expr *&Base, tok::TokenKind& OpKind, SourceLocation OpLoc) { if (Base->hasPlaceholderType()) { ExprResult result = S.CheckPlaceholderExpr(Base); if (result.isInvalid()) return true; Base = result.get(); } ObjectType = Base->getType(); // C++ [expr.pseudo]p2: // The left-hand side of the dot operator shall be of scalar type. The // left-hand side of the arrow operator shall be of pointer to scalar type. // This scalar type is the object type. // Note that this is rather different from the normal handling for the // arrow operator. if (OpKind == tok::arrow) { if (const PointerType *Ptr = ObjectType->getAs()) { ObjectType = Ptr->getPointeeType(); } else if (!Base->isTypeDependent()) { // The user wrote "p->" when they probably meant "p."; fix it. S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) << ObjectType << true << FixItHint::CreateReplacement(OpLoc, "."); if (S.isSFINAEContext()) return true; OpKind = tok::period; } } return false; } /// Check if it's ok to try and recover dot pseudo destructor calls on /// pointer objects. static bool canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema &SemaRef, QualType DestructedType) { // If this is a record type, check if its destructor is callable. if (auto *RD = DestructedType->getAsCXXRecordDecl()) { if (RD->hasDefinition()) if (CXXDestructorDecl *D = SemaRef.LookupDestructor(RD)) return SemaRef.CanUseDecl(D, /*TreatUnavailableAsInvalid=*/false); return false; } // Otherwise, check if it's a type for which it's valid to use a pseudo-dtor. return DestructedType->isDependentType() || DestructedType->isScalarType() || DestructedType->isVectorType(); } ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, const CXXScopeSpec &SS, TypeSourceInfo *ScopeTypeInfo, SourceLocation CCLoc, SourceLocation TildeLoc, PseudoDestructorTypeStorage Destructed) { TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo(); QualType ObjectType; if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc)) return ExprError(); if (!ObjectType->isDependentType() && !ObjectType->isScalarType() && !ObjectType->isVectorType()) { if (getLangOpts().MSVCCompat && ObjectType->isVoidType()) Diag(OpLoc, diag::ext_pseudo_dtor_on_void) << Base->getSourceRange(); else { Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar) << ObjectType << Base->getSourceRange(); return ExprError(); } } // C++ [expr.pseudo]p2: // [...] The cv-unqualified versions of the object type and of the type // designated by the pseudo-destructor-name shall be the same type. if (DestructedTypeInfo) { QualType DestructedType = DestructedTypeInfo->getType(); SourceLocation DestructedTypeStart = DestructedTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(); if (!DestructedType->isDependentType() && !ObjectType->isDependentType()) { if (!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) { // Detect dot pseudo destructor calls on pointer objects, e.g.: // Foo *foo; // foo.~Foo(); if (OpKind == tok::period && ObjectType->isPointerType() && Context.hasSameUnqualifiedType(DestructedType, ObjectType->getPointeeType())) { auto Diagnostic = Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) << ObjectType << /*IsArrow=*/0 << Base->getSourceRange(); // Issue a fixit only when the destructor is valid. if (canRecoverDotPseudoDestructorCallsOnPointerObjects( *this, DestructedType)) Diagnostic << FixItHint::CreateReplacement(OpLoc, "->"); // Recover by setting the object type to the destructed type and the // operator to '->'. ObjectType = DestructedType; OpKind = tok::arrow; } else { Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch) << ObjectType << DestructedType << Base->getSourceRange() << DestructedTypeInfo->getTypeLoc().getLocalSourceRange(); // Recover by setting the destructed type to the object type. DestructedType = ObjectType; DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart); Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo); } } else if (DestructedType.getObjCLifetime() != ObjectType.getObjCLifetime()) { if (DestructedType.getObjCLifetime() == Qualifiers::OCL_None) { // Okay: just pretend that the user provided the correctly-qualified // type. } else { Diag(DestructedTypeStart, diag::err_arc_pseudo_dtor_inconstant_quals) << ObjectType << DestructedType << Base->getSourceRange() << DestructedTypeInfo->getTypeLoc().getLocalSourceRange(); } // Recover by setting the destructed type to the object type. DestructedType = ObjectType; DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart); Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo); } } } // C++ [expr.pseudo]p2: // [...] Furthermore, the two type-names in a pseudo-destructor-name of the // form // // ::[opt] nested-name-specifier[opt] type-name :: ~ type-name // // shall designate the same scalar type. if (ScopeTypeInfo) { QualType ScopeType = ScopeTypeInfo->getType(); if (!ScopeType->isDependentType() && !ObjectType->isDependentType() && !Context.hasSameUnqualifiedType(ScopeType, ObjectType)) { Diag(ScopeTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(), diag::err_pseudo_dtor_type_mismatch) << ObjectType << ScopeType << Base->getSourceRange() << ScopeTypeInfo->getTypeLoc().getLocalSourceRange(); ScopeType = QualType(); ScopeTypeInfo = nullptr; } } Expr *Result = new (Context) CXXPseudoDestructorExpr(Context, Base, OpKind == tok::arrow, OpLoc, SS.getWithLocInContext(Context), ScopeTypeInfo, CCLoc, TildeLoc, Destructed); return Result; } ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, UnqualifiedId &FirstTypeName, SourceLocation CCLoc, SourceLocation TildeLoc, UnqualifiedId &SecondTypeName) { assert((FirstTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId || FirstTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) && "Invalid first type name in pseudo-destructor"); assert((SecondTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId || SecondTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) && "Invalid second type name in pseudo-destructor"); QualType ObjectType; if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc)) return ExprError(); // Compute the object type that we should use for name lookup purposes. Only // record types and dependent types matter. ParsedType ObjectTypePtrForLookup; if (!SS.isSet()) { if (ObjectType->isRecordType()) ObjectTypePtrForLookup = ParsedType::make(ObjectType); else if (ObjectType->isDependentType()) ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy); } // Convert the name of the type being destructed (following the ~) into a // type (with source-location information). QualType DestructedType; TypeSourceInfo *DestructedTypeInfo = nullptr; PseudoDestructorTypeStorage Destructed; if (SecondTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) { ParsedType T = getTypeName(*SecondTypeName.Identifier, SecondTypeName.StartLocation, S, &SS, true, false, ObjectTypePtrForLookup, /*IsCtorOrDtorName*/true); if (!T && ((SS.isSet() && !computeDeclContext(SS, false)) || (!SS.isSet() && ObjectType->isDependentType()))) { // The name of the type being destroyed is a dependent name, and we // couldn't find anything useful in scope. Just store the identifier and // it's location, and we'll perform (qualified) name lookup again at // template instantiation time. Destructed = PseudoDestructorTypeStorage(SecondTypeName.Identifier, SecondTypeName.StartLocation); } else if (!T) { Diag(SecondTypeName.StartLocation, diag::err_pseudo_dtor_destructor_non_type) << SecondTypeName.Identifier << ObjectType; if (isSFINAEContext()) return ExprError(); // Recover by assuming we had the right type all along. DestructedType = ObjectType; } else DestructedType = GetTypeFromParser(T, &DestructedTypeInfo); } else { // Resolve the template-id to a type. TemplateIdAnnotation *TemplateId = SecondTypeName.TemplateId; ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), TemplateId->NumArgs); TypeResult T = ActOnTemplateIdType(S, SS, TemplateId->TemplateKWLoc, TemplateId->Template, TemplateId->Name, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc, /*IsCtorOrDtorName*/true); if (T.isInvalid() || !T.get()) { // Recover by assuming we had the right type all along. DestructedType = ObjectType; } else DestructedType = GetTypeFromParser(T.get(), &DestructedTypeInfo); } // If we've performed some kind of recovery, (re-)build the type source // information. if (!DestructedType.isNull()) { if (!DestructedTypeInfo) DestructedTypeInfo = Context.getTrivialTypeSourceInfo(DestructedType, SecondTypeName.StartLocation); Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo); } // Convert the name of the scope type (the type prior to '::') into a type. TypeSourceInfo *ScopeTypeInfo = nullptr; QualType ScopeType; if (FirstTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId || FirstTypeName.Identifier) { if (FirstTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) { ParsedType T = getTypeName(*FirstTypeName.Identifier, FirstTypeName.StartLocation, S, &SS, true, false, ObjectTypePtrForLookup, /*IsCtorOrDtorName*/true); if (!T) { Diag(FirstTypeName.StartLocation, diag::err_pseudo_dtor_destructor_non_type) << FirstTypeName.Identifier << ObjectType; if (isSFINAEContext()) return ExprError(); // Just drop this type. It's unnecessary anyway. ScopeType = QualType(); } else ScopeType = GetTypeFromParser(T, &ScopeTypeInfo); } else { // Resolve the template-id to a type. TemplateIdAnnotation *TemplateId = FirstTypeName.TemplateId; ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), TemplateId->NumArgs); TypeResult T = ActOnTemplateIdType(S, SS, TemplateId->TemplateKWLoc, TemplateId->Template, TemplateId->Name, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc, /*IsCtorOrDtorName*/true); if (T.isInvalid() || !T.get()) { // Recover by dropping this type. ScopeType = QualType(); } else ScopeType = GetTypeFromParser(T.get(), &ScopeTypeInfo); } } if (!ScopeType.isNull() && !ScopeTypeInfo) ScopeTypeInfo = Context.getTrivialTypeSourceInfo(ScopeType, FirstTypeName.StartLocation); return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, SS, ScopeTypeInfo, CCLoc, TildeLoc, Destructed); } ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, SourceLocation TildeLoc, const DeclSpec& DS) { QualType ObjectType; if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc)) return ExprError(); QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc(), false); TypeLocBuilder TLB; DecltypeTypeLoc DecltypeTL = TLB.push(T); DecltypeTL.setNameLoc(DS.getTypeSpecTypeLoc()); TypeSourceInfo *DestructedTypeInfo = TLB.getTypeSourceInfo(Context, T); PseudoDestructorTypeStorage Destructed(DestructedTypeInfo); return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, CXXScopeSpec(), nullptr, SourceLocation(), TildeLoc, Destructed); } ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, CXXConversionDecl *Method, bool HadMultipleCandidates) { // Convert the expression to match the conversion function's implicit object // parameter. ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/nullptr, FoundDecl, Method); if (Exp.isInvalid()) return true; if (Method->getParent()->isLambda() && Method->getConversionType()->isBlockPointerType()) { // This is a lambda conversion to block pointer; check if the argument // was a LambdaExpr. Expr *SubE = E; CastExpr *CE = dyn_cast(SubE); if (CE && CE->getCastKind() == CK_NoOp) SubE = CE->getSubExpr(); SubE = SubE->IgnoreParens(); if (CXXBindTemporaryExpr *BE = dyn_cast(SubE)) SubE = BE->getSubExpr(); if (isa(SubE)) { // For the conversion to block pointer on a lambda expression, we // construct a special BlockLiteral instead; this doesn't really make // a difference in ARC, but outside of ARC the resulting block literal // follows the normal lifetime rules for block literals instead of being // autoreleased. DiagnosticErrorTrap Trap(Diags); PushExpressionEvaluationContext( ExpressionEvaluationContext::PotentiallyEvaluated); ExprResult BlockExp = BuildBlockForLambdaConversion( Exp.get()->getExprLoc(), Exp.get()->getExprLoc(), Method, Exp.get()); PopExpressionEvaluationContext(); if (BlockExp.isInvalid()) Diag(Exp.get()->getExprLoc(), diag::note_lambda_to_block_conv); return BlockExp; } } MemberExpr *ME = BuildMemberExpr(Exp.get(), /*IsArrow=*/false, SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), Method, DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()), HadMultipleCandidates, DeclarationNameInfo(), Context.BoundMemberTy, VK_RValue, OK_Ordinary); QualType ResultType = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultType); ResultType = ResultType.getNonLValueExprType(Context); CXXMemberCallExpr *CE = CXXMemberCallExpr::Create( Context, ME, /*Args=*/{}, ResultType, VK, Exp.get()->getEndLoc()); if (CheckFunctionCall(Method, CE, Method->getType()->castAs())) return ExprError(); return CE; } ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, SourceLocation RParen) { // If the operand is an unresolved lookup expression, the expression is ill- // formed per [over.over]p1, because overloaded function names cannot be used // without arguments except in explicit contexts. ExprResult R = CheckPlaceholderExpr(Operand); if (R.isInvalid()) return R; R = CheckUnevaluatedOperand(R.get()); if (R.isInvalid()) return ExprError(); Operand = R.get(); if (!inTemplateInstantiation() && Operand->HasSideEffects(Context, false)) { // The expression operand for noexcept is in an unevaluated expression // context, so side effects could result in unintended consequences. Diag(Operand->getExprLoc(), diag::warn_side_effects_unevaluated_context); } CanThrowResult CanThrow = canThrow(Operand); return new (Context) CXXNoexceptExpr(Context.BoolTy, Operand, CanThrow, KeyLoc, RParen); } ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation, Expr *Operand, SourceLocation RParen) { return BuildCXXNoexceptExpr(KeyLoc, Operand, RParen); } static bool IsSpecialDiscardedValue(Expr *E) { // In C++11, discarded-value expressions of a certain form are special, // according to [expr]p10: // The lvalue-to-rvalue conversion (4.1) is applied only if the // expression is an lvalue of volatile-qualified type and it has // one of the following forms: E = E->IgnoreParens(); // - id-expression (5.1.1), if (isa(E)) return true; // - subscripting (5.2.1), if (isa(E)) return true; // - class member access (5.2.5), if (isa(E)) return true; // - indirection (5.3.1), if (UnaryOperator *UO = dyn_cast(E)) if (UO->getOpcode() == UO_Deref) return true; if (BinaryOperator *BO = dyn_cast(E)) { // - pointer-to-member operation (5.5), if (BO->isPtrMemOp()) return true; // - comma expression (5.18) where the right operand is one of the above. if (BO->getOpcode() == BO_Comma) return IsSpecialDiscardedValue(BO->getRHS()); } // - conditional expression (5.16) where both the second and the third // operands are one of the above, or if (ConditionalOperator *CO = dyn_cast(E)) return IsSpecialDiscardedValue(CO->getTrueExpr()) && IsSpecialDiscardedValue(CO->getFalseExpr()); // The related edge case of "*x ?: *x". if (BinaryConditionalOperator *BCO = dyn_cast(E)) { if (OpaqueValueExpr *OVE = dyn_cast(BCO->getTrueExpr())) return IsSpecialDiscardedValue(OVE->getSourceExpr()) && IsSpecialDiscardedValue(BCO->getFalseExpr()); } // Objective-C++ extensions to the rule. if (isa(E) || isa(E)) return true; return false; } /// Perform the conversions required for an expression used in a /// context that ignores the result. ExprResult Sema::IgnoredValueConversions(Expr *E) { if (E->hasPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(E); if (result.isInvalid()) return E; E = result.get(); } // C99 6.3.2.1: // [Except in specific positions,] an lvalue that does not have // array type is converted to the value stored in the // designated object (and is no longer an lvalue). if (E->isRValue()) { // In C, function designators (i.e. expressions of function type) // are r-values, but we still want to do function-to-pointer decay // on them. This is both technically correct and convenient for // some clients. if (!getLangOpts().CPlusPlus && E->getType()->isFunctionType()) return DefaultFunctionArrayConversion(E); return E; } if (getLangOpts().CPlusPlus) { // The C++11 standard defines the notion of a discarded-value expression; // normally, we don't need to do anything to handle it, but if it is a // volatile lvalue with a special form, we perform an lvalue-to-rvalue // conversion. if (getLangOpts().CPlusPlus11 && E->isGLValue() && E->getType().isVolatileQualified()) { if (IsSpecialDiscardedValue(E)) { ExprResult Res = DefaultLvalueConversion(E); if (Res.isInvalid()) return E; E = Res.get(); } else { // Per C++2a [expr.ass]p5, a volatile assignment is not deprecated if // it occurs as a discarded-value expression. CheckUnusedVolatileAssignment(E); } } // C++1z: // If the expression is a prvalue after this optional conversion, the // temporary materialization conversion is applied. // // We skip this step: IR generation is able to synthesize the storage for // itself in the aggregate case, and adding the extra node to the AST is // just clutter. // FIXME: We don't emit lifetime markers for the temporaries due to this. // FIXME: Do any other AST consumers care about this? return E; } // GCC seems to also exclude expressions of incomplete enum type. if (const EnumType *T = E->getType()->getAs()) { if (!T->getDecl()->isComplete()) { // FIXME: stupid workaround for a codegen bug! E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get(); return E; } } ExprResult Res = DefaultFunctionArrayLvalueConversion(E); if (Res.isInvalid()) return E; E = Res.get(); if (!E->getType()->isVoidType()) RequireCompleteType(E->getExprLoc(), E->getType(), diag::err_incomplete_type); return E; } ExprResult Sema::CheckUnevaluatedOperand(Expr *E) { // Per C++2a [expr.ass]p5, a volatile assignment is not deprecated if // it occurs as an unevaluated operand. CheckUnusedVolatileAssignment(E); return E; } // If we can unambiguously determine whether Var can never be used // in a constant expression, return true. // - if the variable and its initializer are non-dependent, then // we can unambiguously check if the variable is a constant expression. // - if the initializer is not value dependent - we can determine whether // it can be used to initialize a constant expression. If Init can not // be used to initialize a constant expression we conclude that Var can // never be a constant expression. // - FXIME: if the initializer is dependent, we can still do some analysis and // identify certain cases unambiguously as non-const by using a Visitor: // - such as those that involve odr-use of a ParmVarDecl, involve a new // delete, lambda-expr, dynamic-cast, reinterpret-cast etc... static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var, ASTContext &Context) { if (isa(Var)) return true; const VarDecl *DefVD = nullptr; // If there is no initializer - this can not be a constant expression. if (!Var->getAnyInitializer(DefVD)) return true; assert(DefVD); if (DefVD->isWeak()) return false; EvaluatedStmt *Eval = DefVD->ensureEvaluatedStmt(); Expr *Init = cast(Eval->Value); if (Var->getType()->isDependentType() || Init->isValueDependent()) { // FIXME: Teach the constant evaluator to deal with the non-dependent parts // of value-dependent expressions, and use it here to determine whether the // initializer is a potential constant expression. return false; } return !Var->isUsableInConstantExpressions(Context); } /// Check if the current lambda has any potential captures /// that must be captured by any of its enclosing lambdas that are ready to /// capture. If there is a lambda that can capture a nested /// potential-capture, go ahead and do so. Also, check to see if any /// variables are uncaptureable or do not involve an odr-use so do not /// need to be captured. static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures( Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S) { assert(!S.isUnevaluatedContext()); assert(S.CurContext->isDependentContext()); #ifndef NDEBUG DeclContext *DC = S.CurContext; while (DC && isa(DC)) DC = DC->getParent(); assert( CurrentLSI->CallOperator == DC && "The current call operator must be synchronized with Sema's CurContext"); #endif // NDEBUG const bool IsFullExprInstantiationDependent = FE->isInstantiationDependent(); // All the potentially captureable variables in the current nested // lambda (within a generic outer lambda), must be captured by an // outer lambda that is enclosed within a non-dependent context. CurrentLSI->visitPotentialCaptures([&] (VarDecl *Var, Expr *VarExpr) { // If the variable is clearly identified as non-odr-used and the full // expression is not instantiation dependent, only then do we not // need to check enclosing lambda's for speculative captures. // For e.g.: // Even though 'x' is not odr-used, it should be captured. // int test() { // const int x = 10; // auto L = [=](auto a) { // (void) +x + a; // }; // } if (CurrentLSI->isVariableExprMarkedAsNonODRUsed(VarExpr) && !IsFullExprInstantiationDependent) return; // If we have a capture-capable lambda for the variable, go ahead and // capture the variable in that lambda (and all its enclosing lambdas). if (const Optional Index = getStackIndexOfNearestEnclosingCaptureCapableLambda( S.FunctionScopes, Var, S)) S.MarkCaptureUsedInEnclosingContext(Var, VarExpr->getExprLoc(), Index.getValue()); const bool IsVarNeverAConstantExpression = VariableCanNeverBeAConstantExpression(Var, S.Context); if (!IsFullExprInstantiationDependent || IsVarNeverAConstantExpression) { // This full expression is not instantiation dependent or the variable // can not be used in a constant expression - which means // this variable must be odr-used here, so diagnose a // capture violation early, if the variable is un-captureable. // This is purely for diagnosing errors early. Otherwise, this // error would get diagnosed when the lambda becomes capture ready. QualType CaptureType, DeclRefType; SourceLocation ExprLoc = VarExpr->getExprLoc(); if (S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit, /*EllipsisLoc*/ SourceLocation(), /*BuildAndDiagnose*/false, CaptureType, DeclRefType, nullptr)) { // We will never be able to capture this variable, and we need // to be able to in any and all instantiations, so diagnose it. S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit, /*EllipsisLoc*/ SourceLocation(), /*BuildAndDiagnose*/true, CaptureType, DeclRefType, nullptr); } } }); // Check if 'this' needs to be captured. if (CurrentLSI->hasPotentialThisCapture()) { // If we have a capture-capable lambda for 'this', go ahead and capture // 'this' in that lambda (and all its enclosing lambdas). if (const Optional Index = getStackIndexOfNearestEnclosingCaptureCapableLambda( S.FunctionScopes, /*0 is 'this'*/ nullptr, S)) { const unsigned FunctionScopeIndexOfCapturableLambda = Index.getValue(); S.CheckCXXThisCapture(CurrentLSI->PotentialThisCaptureLocation, /*Explicit*/ false, /*BuildAndDiagnose*/ true, &FunctionScopeIndexOfCapturableLambda); } } // Reset all the potential captures at the end of each full-expression. CurrentLSI->clearPotentialCaptures(); } static ExprResult attemptRecovery(Sema &SemaRef, const TypoCorrectionConsumer &Consumer, const TypoCorrection &TC) { LookupResult R(SemaRef, Consumer.getLookupResult().getLookupNameInfo(), Consumer.getLookupResult().getLookupKind()); const CXXScopeSpec *SS = Consumer.getSS(); CXXScopeSpec NewSS; // Use an approprate CXXScopeSpec for building the expr. if (auto *NNS = TC.getCorrectionSpecifier()) NewSS.MakeTrivial(SemaRef.Context, NNS, TC.getCorrectionRange()); else if (SS && !TC.WillReplaceSpecifier()) NewSS = *SS; if (auto *ND = TC.getFoundDecl()) { R.setLookupName(ND->getDeclName()); R.addDecl(ND); if (ND->isCXXClassMember()) { // Figure out the correct naming class to add to the LookupResult. CXXRecordDecl *Record = nullptr; if (auto *NNS = TC.getCorrectionSpecifier()) Record = NNS->getAsType()->getAsCXXRecordDecl(); if (!Record) Record = dyn_cast(ND->getDeclContext()->getRedeclContext()); if (Record) R.setNamingClass(Record); // Detect and handle the case where the decl might be an implicit // member. bool MightBeImplicitMember; if (!Consumer.isAddressOfOperand()) MightBeImplicitMember = true; else if (!NewSS.isEmpty()) MightBeImplicitMember = false; else if (R.isOverloadedResult()) MightBeImplicitMember = false; else if (R.isUnresolvableResult()) MightBeImplicitMember = true; else MightBeImplicitMember = isa(ND) || isa(ND) || isa(ND); if (MightBeImplicitMember) return SemaRef.BuildPossibleImplicitMemberExpr( NewSS, /*TemplateKWLoc*/ SourceLocation(), R, /*TemplateArgs*/ nullptr, /*S*/ nullptr); } else if (auto *Ivar = dyn_cast(ND)) { return SemaRef.LookupInObjCMethod(R, Consumer.getScope(), Ivar->getIdentifier()); } } return SemaRef.BuildDeclarationNameExpr(NewSS, R, /*NeedsADL*/ false, /*AcceptInvalidDecl*/ true); } namespace { class FindTypoExprs : public RecursiveASTVisitor { llvm::SmallSetVector &TypoExprs; public: explicit FindTypoExprs(llvm::SmallSetVector &TypoExprs) : TypoExprs(TypoExprs) {} bool VisitTypoExpr(TypoExpr *TE) { TypoExprs.insert(TE); return true; } }; class TransformTypos : public TreeTransform { typedef TreeTransform BaseTransform; VarDecl *InitDecl; // A decl to avoid as a correction because it is in the // process of being initialized. llvm::function_ref ExprFilter; llvm::SmallSetVector TypoExprs, AmbiguousTypoExprs; llvm::SmallDenseMap TransformCache; llvm::SmallDenseMap OverloadResolution; /// Emit diagnostics for all of the TypoExprs encountered. /// /// If the TypoExprs were successfully corrected, then the diagnostics should /// suggest the corrections. Otherwise the diagnostics will not suggest /// anything (having been passed an empty TypoCorrection). /// /// If we've failed to correct due to ambiguous corrections, we need to /// be sure to pass empty corrections and replacements. Otherwise it's /// possible that the Consumer has a TypoCorrection that failed to ambiguity /// and we don't want to report those diagnostics. void EmitAllDiagnostics(bool IsAmbiguous) { for (TypoExpr *TE : TypoExprs) { auto &State = SemaRef.getTypoExprState(TE); if (State.DiagHandler) { TypoCorrection TC = IsAmbiguous ? TypoCorrection() : State.Consumer->getCurrentCorrection(); ExprResult Replacement = IsAmbiguous ? ExprError() : TransformCache[TE]; // Extract the NamedDecl from the transformed TypoExpr and add it to the // TypoCorrection, replacing the existing decls. This ensures the right // NamedDecl is used in diagnostics e.g. in the case where overload // resolution was used to select one from several possible decls that // had been stored in the TypoCorrection. if (auto *ND = getDeclFromExpr( Replacement.isInvalid() ? nullptr : Replacement.get())) TC.setCorrectionDecl(ND); State.DiagHandler(TC); } SemaRef.clearDelayedTypo(TE); } } /// If corrections for the first TypoExpr have been exhausted for a /// given combination of the other TypoExprs, retry those corrections against /// the next combination of substitutions for the other TypoExprs by advancing /// to the next potential correction of the second TypoExpr. For the second /// and subsequent TypoExprs, if its stream of corrections has been exhausted, /// the stream is reset and the next TypoExpr's stream is advanced by one (a /// TypoExpr's correction stream is advanced by removing the TypoExpr from the /// TransformCache). Returns true if there is still any untried combinations /// of corrections. bool CheckAndAdvanceTypoExprCorrectionStreams() { for (auto TE : TypoExprs) { auto &State = SemaRef.getTypoExprState(TE); TransformCache.erase(TE); if (!State.Consumer->finished()) return true; State.Consumer->resetCorrectionStream(); } return false; } NamedDecl *getDeclFromExpr(Expr *E) { if (auto *OE = dyn_cast_or_null(E)) E = OverloadResolution[OE]; if (!E) return nullptr; if (auto *DRE = dyn_cast(E)) return DRE->getFoundDecl(); if (auto *ME = dyn_cast(E)) return ME->getFoundDecl(); // FIXME: Add any other expr types that could be be seen by the delayed typo // correction TreeTransform for which the corresponding TypoCorrection could // contain multiple decls. return nullptr; } ExprResult TryTransform(Expr *E) { Sema::SFINAETrap Trap(SemaRef); ExprResult Res = TransformExpr(E); if (Trap.hasErrorOccurred() || Res.isInvalid()) return ExprError(); return ExprFilter(Res.get()); } // Since correcting typos may intoduce new TypoExprs, this function // checks for new TypoExprs and recurses if it finds any. Note that it will // only succeed if it is able to correct all typos in the given expression. ExprResult CheckForRecursiveTypos(ExprResult Res, bool &IsAmbiguous) { if (Res.isInvalid()) { return Res; } // Check to see if any new TypoExprs were created. If so, we need to recurse // to check their validity. Expr *FixedExpr = Res.get(); auto SavedTypoExprs = std::move(TypoExprs); auto SavedAmbiguousTypoExprs = std::move(AmbiguousTypoExprs); TypoExprs.clear(); AmbiguousTypoExprs.clear(); FindTypoExprs(TypoExprs).TraverseStmt(FixedExpr); if (!TypoExprs.empty()) { // Recurse to handle newly created TypoExprs. If we're not able to // handle them, discard these TypoExprs. ExprResult RecurResult = RecursiveTransformLoop(FixedExpr, IsAmbiguous); if (RecurResult.isInvalid()) { Res = ExprError(); // Recursive corrections didn't work, wipe them away and don't add // them to the TypoExprs set. Remove them from Sema's TypoExpr list // since we don't want to clear them twice. Note: it's possible the // TypoExprs were created recursively and thus won't be in our // Sema's TypoExprs - they were created in our `RecursiveTransformLoop`. auto &SemaTypoExprs = SemaRef.TypoExprs; for (auto TE : TypoExprs) { TransformCache.erase(TE); SemaRef.clearDelayedTypo(TE); auto SI = find(SemaTypoExprs, TE); if (SI != SemaTypoExprs.end()) { SemaTypoExprs.erase(SI); } } } else { // TypoExpr is valid: add newly created TypoExprs since we were // able to correct them. Res = RecurResult; SavedTypoExprs.set_union(TypoExprs); } } TypoExprs = std::move(SavedTypoExprs); AmbiguousTypoExprs = std::move(SavedAmbiguousTypoExprs); return Res; } // Try to transform the given expression, looping through the correction // candidates with `CheckAndAdvanceTypoExprCorrectionStreams`. // // If valid ambiguous typo corrections are seen, `IsAmbiguous` is set to // true and this method immediately will return an `ExprError`. ExprResult RecursiveTransformLoop(Expr *E, bool &IsAmbiguous) { ExprResult Res; auto SavedTypoExprs = std::move(SemaRef.TypoExprs); SemaRef.TypoExprs.clear(); while (true) { Res = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous); // Recursion encountered an ambiguous correction. This means that our // correction itself is ambiguous, so stop now. if (IsAmbiguous) break; // If the transform is still valid after checking for any new typos, // it's good to go. if (!Res.isInvalid()) break; // The transform was invalid, see if we have any TypoExprs with untried // correction candidates. if (!CheckAndAdvanceTypoExprCorrectionStreams()) break; } // If we found a valid result, double check to make sure it's not ambiguous. if (!IsAmbiguous && !Res.isInvalid() && !AmbiguousTypoExprs.empty()) { auto SavedTransformCache = llvm::SmallDenseMap(TransformCache); // Ensure none of the TypoExprs have multiple typo correction candidates // with the same edit length that pass all the checks and filters. while (!AmbiguousTypoExprs.empty()) { auto TE = AmbiguousTypoExprs.back(); // TryTransform itself can create new Typos, adding them to the TypoExpr map // and invalidating our TypoExprState, so always fetch it instead of storing. SemaRef.getTypoExprState(TE).Consumer->saveCurrentPosition(); TypoCorrection TC = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection(); TypoCorrection Next; do { // Fetch the next correction by erasing the typo from the cache and calling // `TryTransform` which will iterate through corrections in // `TransformTypoExpr`. TransformCache.erase(TE); ExprResult AmbigRes = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous); if (!AmbigRes.isInvalid() || IsAmbiguous) { SemaRef.getTypoExprState(TE).Consumer->resetCorrectionStream(); SavedTransformCache.erase(TE); Res = ExprError(); IsAmbiguous = true; break; } } while ((Next = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection()) && Next.getEditDistance(false) == TC.getEditDistance(false)); if (IsAmbiguous) break; AmbiguousTypoExprs.remove(TE); SemaRef.getTypoExprState(TE).Consumer->restoreSavedPosition(); } TransformCache = std::move(SavedTransformCache); } // Wipe away any newly created TypoExprs that we don't know about. Since we // clear any invalid TypoExprs in `CheckForRecursiveTypos`, this is only // possible if a `TypoExpr` is created during a transformation but then // fails before we can discover it. auto &SemaTypoExprs = SemaRef.TypoExprs; for (auto Iterator = SemaTypoExprs.begin(); Iterator != SemaTypoExprs.end();) { auto TE = *Iterator; auto FI = find(TypoExprs, TE); if (FI != TypoExprs.end()) { Iterator++; continue; } SemaRef.clearDelayedTypo(TE); Iterator = SemaTypoExprs.erase(Iterator); } SemaRef.TypoExprs = std::move(SavedTypoExprs); return Res; } public: TransformTypos(Sema &SemaRef, VarDecl *InitDecl, llvm::function_ref Filter) : BaseTransform(SemaRef), InitDecl(InitDecl), ExprFilter(Filter) {} ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig = nullptr) { auto Result = BaseTransform::RebuildCallExpr(Callee, LParenLoc, Args, RParenLoc, ExecConfig); if (auto *OE = dyn_cast(Callee)) { if (Result.isUsable()) { Expr *ResultCall = Result.get(); if (auto *BE = dyn_cast(ResultCall)) ResultCall = BE->getSubExpr(); if (auto *CE = dyn_cast(ResultCall)) OverloadResolution[OE] = CE->getCallee(); } } return Result; } ExprResult TransformLambdaExpr(LambdaExpr *E) { return Owned(E); } ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); } ExprResult Transform(Expr *E) { bool IsAmbiguous = false; ExprResult Res = RecursiveTransformLoop(E, IsAmbiguous); if (!Res.isUsable()) FindTypoExprs(TypoExprs).TraverseStmt(E); EmitAllDiagnostics(IsAmbiguous); return Res; } ExprResult TransformTypoExpr(TypoExpr *E) { // If the TypoExpr hasn't been seen before, record it. Otherwise, return the // cached transformation result if there is one and the TypoExpr isn't the // first one that was encountered. auto &CacheEntry = TransformCache[E]; if (!TypoExprs.insert(E) && !CacheEntry.isUnset()) { return CacheEntry; } auto &State = SemaRef.getTypoExprState(E); assert(State.Consumer && "Cannot transform a cleared TypoExpr"); // For the first TypoExpr and an uncached TypoExpr, find the next likely // typo correction and return it. while (TypoCorrection TC = State.Consumer->getNextCorrection()) { if (InitDecl && TC.getFoundDecl() == InitDecl) continue; // FIXME: If we would typo-correct to an invalid declaration, it's // probably best to just suppress all errors from this typo correction. ExprResult NE = State.RecoveryHandler ? State.RecoveryHandler(SemaRef, E, TC) : attemptRecovery(SemaRef, *State.Consumer, TC); if (!NE.isInvalid()) { // Check whether there may be a second viable correction with the same // edit distance; if so, remember this TypoExpr may have an ambiguous // correction so it can be more thoroughly vetted later. TypoCorrection Next; if ((Next = State.Consumer->peekNextCorrection()) && Next.getEditDistance(false) == TC.getEditDistance(false)) { AmbiguousTypoExprs.insert(E); } else { AmbiguousTypoExprs.remove(E); } assert(!NE.isUnset() && "Typo was transformed into a valid-but-null ExprResult"); return CacheEntry = NE; } } return CacheEntry = ExprError(); } }; } ExprResult Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl, llvm::function_ref Filter) { // If the current evaluation context indicates there are uncorrected typos // and the current expression isn't guaranteed to not have typos, try to // resolve any TypoExpr nodes that might be in the expression. if (E && !ExprEvalContexts.empty() && ExprEvalContexts.back().NumTypos && (E->isTypeDependent() || E->isValueDependent() || E->isInstantiationDependent())) { auto TyposResolved = DelayedTypos.size(); auto Result = TransformTypos(*this, InitDecl, Filter).Transform(E); TyposResolved -= DelayedTypos.size(); if (Result.isInvalid() || Result.get() != E) { ExprEvalContexts.back().NumTypos -= TyposResolved; return Result; } assert(TyposResolved == 0 && "Corrected typo but got same Expr back?"); } return E; } ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, bool DiscardedValue, bool IsConstexpr) { ExprResult FullExpr = FE; if (!FullExpr.get()) return ExprError(); if (DiagnoseUnexpandedParameterPack(FullExpr.get())) return ExprError(); if (DiscardedValue) { // Top-level expressions default to 'id' when we're in a debugger. if (getLangOpts().DebuggerCastResultToId && FullExpr.get()->getType() == Context.UnknownAnyTy) { FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType()); if (FullExpr.isInvalid()) return ExprError(); } FullExpr = CheckPlaceholderExpr(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); FullExpr = IgnoredValueConversions(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); DiagnoseUnusedExprResult(FullExpr.get()); } FullExpr = CorrectDelayedTyposInExpr(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); CheckCompletedExpr(FullExpr.get(), CC, IsConstexpr); // At the end of this full expression (which could be a deeply nested // lambda), if there is a potential capture within the nested lambda, // have the outer capture-able lambda try and capture it. // Consider the following code: // void f(int, int); // void f(const int&, double); // void foo() { // const int x = 10, y = 20; // auto L = [=](auto a) { // auto M = [=](auto b) { // f(x, b); <-- requires x to be captured by L and M // f(y, a); <-- requires y to be captured by L, but not all Ms // }; // }; // } // FIXME: Also consider what happens for something like this that involves // the gnu-extension statement-expressions or even lambda-init-captures: // void f() { // const int n = 0; // auto L = [&](auto a) { // +n + ({ 0; a; }); // }; // } // // Here, we see +n, and then the full-expression 0; ends, so we don't // capture n (and instead remove it from our list of potential captures), // and then the full-expression +n + ({ 0; }); ends, but it's too late // for us to see that we need to capture n after all. LambdaScopeInfo *const CurrentLSI = getCurLambda(/*IgnoreCapturedRegions=*/true); // FIXME: PR 17877 showed that getCurLambda() can return a valid pointer // even if CurContext is not a lambda call operator. Refer to that Bug Report // for an example of the code that might cause this asynchrony. // By ensuring we are in the context of a lambda's call operator // we can fix the bug (we only need to check whether we need to capture // if we are within a lambda's body); but per the comments in that // PR, a proper fix would entail : // "Alternative suggestion: // - Add to Sema an integer holding the smallest (outermost) scope // index that we are *lexically* within, and save/restore/set to // FunctionScopes.size() in InstantiatingTemplate's // constructor/destructor. // - Teach the handful of places that iterate over FunctionScopes to // stop at the outermost enclosing lexical scope." DeclContext *DC = CurContext; while (DC && isa(DC)) DC = DC->getParent(); const bool IsInLambdaDeclContext = isLambdaCallOperator(DC); if (IsInLambdaDeclContext && CurrentLSI && CurrentLSI->hasPotentialCaptures() && !FullExpr.isInvalid()) CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(FE, CurrentLSI, *this); return MaybeCreateExprWithCleanups(FullExpr); } StmtResult Sema::ActOnFinishFullStmt(Stmt *FullStmt) { if (!FullStmt) return StmtError(); return MaybeCreateStmtWithCleanups(FullStmt); } Sema::IfExistsResult Sema::CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS, const DeclarationNameInfo &TargetNameInfo) { DeclarationName TargetName = TargetNameInfo.getName(); if (!TargetName) return IER_DoesNotExist; // If the name itself is dependent, then the result is dependent. if (TargetName.isDependentName()) return IER_Dependent; // Do the redeclaration lookup in the current scope. LookupResult R(*this, TargetNameInfo, Sema::LookupAnyName, Sema::NotForRedeclaration); LookupParsedName(R, S, &SS); R.suppressDiagnostics(); switch (R.getResultKind()) { case LookupResult::Found: case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: case LookupResult::Ambiguous: return IER_Exists; case LookupResult::NotFound: return IER_DoesNotExist; case LookupResult::NotFoundInCurrentInstantiation: return IER_Dependent; } llvm_unreachable("Invalid LookupResult Kind!"); } Sema::IfExistsResult Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc, bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name) { DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name); // Check for an unexpanded parameter pack. auto UPPC = IsIfExists ? UPPC_IfExists : UPPC_IfNotExists; if (DiagnoseUnexpandedParameterPack(SS, UPPC) || DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC)) return IER_Error; return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo); } concepts::Requirement *Sema::ActOnSimpleRequirement(Expr *E) { return BuildExprRequirement(E, /*IsSimple=*/true, /*NoexceptLoc=*/SourceLocation(), /*ReturnTypeRequirement=*/{}); } concepts::Requirement * Sema::ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc, IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId) { assert(((!TypeName && TemplateId) || (TypeName && !TemplateId)) && "Exactly one of TypeName and TemplateId must be specified."); TypeSourceInfo *TSI = nullptr; if (TypeName) { QualType T = CheckTypenameType(ETK_Typename, TypenameKWLoc, SS.getWithLocInContext(Context), *TypeName, NameLoc, &TSI, /*DeducedTypeContext=*/false); if (T.isNull()) return nullptr; } else { ASTTemplateArgsPtr ArgsPtr(TemplateId->getTemplateArgs(), TemplateId->NumArgs); TypeResult T = ActOnTypenameType(CurScope, TypenameKWLoc, SS, TemplateId->TemplateKWLoc, TemplateId->Template, TemplateId->Name, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, ArgsPtr, TemplateId->RAngleLoc); if (T.isInvalid()) return nullptr; if (GetTypeFromParser(T.get(), &TSI).isNull()) return nullptr; } return BuildTypeRequirement(TSI); } concepts::Requirement * Sema::ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc) { return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc, /*ReturnTypeRequirement=*/{}); } concepts::Requirement * Sema::ActOnCompoundRequirement( Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS, TemplateIdAnnotation *TypeConstraint, unsigned Depth) { // C++2a [expr.prim.req.compound] p1.3.3 // [..] the expression is deduced against an invented function template // F [...] F is a void function template with a single type template // parameter T declared with the constrained-parameter. Form a new // cv-qualifier-seq cv by taking the union of const and volatile specifiers // around the constrained-parameter. F has a single parameter whose // type-specifier is cv T followed by the abstract-declarator. [...] // // The cv part is done in the calling function - we get the concept with // arguments and the abstract declarator with the correct CV qualification and // have to synthesize T and the single parameter of F. auto &II = Context.Idents.get("expr-type"); auto *TParam = TemplateTypeParmDecl::Create(Context, CurContext, SourceLocation(), SourceLocation(), Depth, /*Index=*/0, &II, /*Typename=*/true, /*ParameterPack=*/false, /*HasTypeConstraint=*/true); if (ActOnTypeConstraint(SS, TypeConstraint, TParam, /*EllpsisLoc=*/SourceLocation())) // Just produce a requirement with no type requirements. return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc, {}); auto *TPL = TemplateParameterList::Create(Context, SourceLocation(), SourceLocation(), ArrayRef(TParam), SourceLocation(), /*RequiresClause=*/nullptr); return BuildExprRequirement( E, /*IsSimple=*/false, NoexceptLoc, concepts::ExprRequirement::ReturnTypeRequirement(TPL)); } concepts::ExprRequirement * Sema::BuildExprRequirement( Expr *E, bool IsSimple, SourceLocation NoexceptLoc, concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) { auto Status = concepts::ExprRequirement::SS_Satisfied; ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr; if (E->isInstantiationDependent() || ReturnTypeRequirement.isDependent()) Status = concepts::ExprRequirement::SS_Dependent; else if (NoexceptLoc.isValid() && canThrow(E) == CanThrowResult::CT_Can) Status = concepts::ExprRequirement::SS_NoexceptNotMet; else if (ReturnTypeRequirement.isSubstitutionFailure()) Status = concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure; else if (ReturnTypeRequirement.isTypeConstraint()) { // C++2a [expr.prim.req]p1.3.3 // The immediately-declared constraint ([temp]) of decltype((E)) shall // be satisfied. TemplateParameterList *TPL = ReturnTypeRequirement.getTypeConstraintTemplateParameterList(); QualType MatchedType = BuildDecltypeType(E, E->getBeginLoc()).getCanonicalType(); llvm::SmallVector Args; Args.push_back(TemplateArgument(MatchedType)); TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args); MultiLevelTemplateArgumentList MLTAL(TAL); for (unsigned I = 0; I < TPL->getDepth(); ++I) MLTAL.addOuterRetainedLevel(); Expr *IDC = cast(TPL->getParam(0))->getTypeConstraint() ->getImmediatelyDeclaredConstraint(); ExprResult Constraint = SubstExpr(IDC, MLTAL); assert(!Constraint.isInvalid() && "Substitution cannot fail as it is simply putting a type template " "argument into a concept specialization expression's parameter."); SubstitutedConstraintExpr = cast(Constraint.get()); if (!SubstitutedConstraintExpr->isSatisfied()) Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied; } return new (Context) concepts::ExprRequirement(E, IsSimple, NoexceptLoc, ReturnTypeRequirement, Status, SubstitutedConstraintExpr); } concepts::ExprRequirement * Sema::BuildExprRequirement( concepts::Requirement::SubstitutionDiagnostic *ExprSubstitutionDiagnostic, bool IsSimple, SourceLocation NoexceptLoc, concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) { return new (Context) concepts::ExprRequirement(ExprSubstitutionDiagnostic, IsSimple, NoexceptLoc, ReturnTypeRequirement); } concepts::TypeRequirement * Sema::BuildTypeRequirement(TypeSourceInfo *Type) { return new (Context) concepts::TypeRequirement(Type); } concepts::TypeRequirement * Sema::BuildTypeRequirement( concepts::Requirement::SubstitutionDiagnostic *SubstDiag) { return new (Context) concepts::TypeRequirement(SubstDiag); } concepts::Requirement *Sema::ActOnNestedRequirement(Expr *Constraint) { return BuildNestedRequirement(Constraint); } concepts::NestedRequirement * Sema::BuildNestedRequirement(Expr *Constraint) { ConstraintSatisfaction Satisfaction; if (!Constraint->isInstantiationDependent() && CheckConstraintSatisfaction(nullptr, {Constraint}, /*TemplateArgs=*/{}, Constraint->getSourceRange(), Satisfaction)) return nullptr; return new (Context) concepts::NestedRequirement(Context, Constraint, Satisfaction); } concepts::NestedRequirement * Sema::BuildNestedRequirement( concepts::Requirement::SubstitutionDiagnostic *SubstDiag) { return new (Context) concepts::NestedRequirement(SubstDiag); } RequiresExprBodyDecl * Sema::ActOnStartRequiresExpr(SourceLocation RequiresKWLoc, ArrayRef LocalParameters, Scope *BodyScope) { assert(BodyScope); RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(Context, CurContext, RequiresKWLoc); PushDeclContext(BodyScope, Body); for (ParmVarDecl *Param : LocalParameters) { if (Param->hasDefaultArg()) // C++2a [expr.prim.req] p4 // [...] A local parameter of a requires-expression shall not have a // default argument. [...] Diag(Param->getDefaultArgRange().getBegin(), diag::err_requires_expr_local_parameter_default_argument); // Ignore default argument and move on Param->setDeclContext(Body); // If this has an identifier, add it to the scope stack. if (Param->getIdentifier()) { CheckShadow(BodyScope, Param); PushOnScopeChains(Param, BodyScope); } } return Body; } void Sema::ActOnFinishRequiresExpr() { assert(CurContext && "DeclContext imbalance!"); CurContext = CurContext->getLexicalParent(); assert(CurContext && "Popped translation unit!"); } ExprResult Sema::ActOnRequiresExpr(SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, ArrayRef LocalParameters, ArrayRef Requirements, SourceLocation ClosingBraceLoc) { return RequiresExpr::Create(Context, RequiresKWLoc, Body, LocalParameters, Requirements, ClosingBraceLoc); } Index: stable/11/contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp =================================================================== --- stable/11/contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp (revision 363091) +++ stable/11/contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp (revision 363092) @@ -1,14779 +1,14779 @@ //===--- SemaOverload.cpp - C++ Overloading -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file provides Sema routines for C++ overloading. // //===----------------------------------------------------------------------===// #include "clang/Sema/Overload.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/TypeOrdering.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include #include using namespace clang; using namespace sema; static bool functionHasPassObjectSizeParams(const FunctionDecl *FD) { return llvm::any_of(FD->parameters(), [](const ParmVarDecl *P) { return P->hasAttr(); }); } /// A convenience routine for creating a decayed reference to a function. static ExprResult CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl, const Expr *Base, bool HadMultipleCandidates, SourceLocation Loc = SourceLocation(), const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){ if (S.DiagnoseUseOfDecl(FoundDecl, Loc)) return ExprError(); // If FoundDecl is different from Fn (such as if one is a template // and the other a specialization), make sure DiagnoseUseOfDecl is // called on both. // FIXME: This would be more comprehensively addressed by modifying // DiagnoseUseOfDecl to accept both the FoundDecl and the decl // being used. if (FoundDecl != Fn && S.DiagnoseUseOfDecl(Fn, Loc)) return ExprError(); DeclRefExpr *DRE = new (S.Context) DeclRefExpr(S.Context, Fn, false, Fn->getType(), VK_LValue, Loc, LocInfo); if (HadMultipleCandidates) DRE->setHadMultipleCandidates(true); S.MarkDeclRefReferenced(DRE, Base); if (auto *FPT = DRE->getType()->getAs()) { if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) { S.ResolveExceptionSpec(Loc, FPT); DRE->setType(Fn->getType()); } } return S.ImpCastExprToType(DRE, S.Context.getPointerType(DRE->getType()), CK_FunctionToPointerDecay); } static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle, bool AllowObjCWritebackConversion); static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From, QualType &ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle); static OverloadingResult IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, UserDefinedConversionSequence& User, OverloadCandidateSet& Conversions, bool AllowExplicit, bool AllowObjCConversionOnExplicit); static ImplicitConversionSequence::CompareKind CompareStandardConversionSequences(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2); static ImplicitConversionSequence::CompareKind CompareQualificationConversions(Sema &S, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2); static ImplicitConversionSequence::CompareKind CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2); /// GetConversionRank - Retrieve the implicit conversion rank /// corresponding to the given implicit conversion kind. ImplicitConversionRank clang::GetConversionRank(ImplicitConversionKind Kind) { static const ImplicitConversionRank Rank[(int)ICK_Num_Conversion_Kinds] = { ICR_Exact_Match, ICR_Exact_Match, ICR_Exact_Match, ICR_Exact_Match, ICR_Exact_Match, ICR_Exact_Match, ICR_Promotion, ICR_Promotion, ICR_Promotion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_OCL_Scalar_Widening, ICR_Complex_Real_Conversion, ICR_Conversion, ICR_Conversion, ICR_Writeback_Conversion, ICR_Exact_Match, // NOTE(gbiv): This may not be completely right -- // it was omitted by the patch that added // ICK_Zero_Event_Conversion ICR_C_Conversion, ICR_C_Conversion_Extension }; return Rank[(int)Kind]; } /// GetImplicitConversionName - Return the name of this kind of /// implicit conversion. static const char* GetImplicitConversionName(ImplicitConversionKind Kind) { static const char* const Name[(int)ICK_Num_Conversion_Kinds] = { "No conversion", "Lvalue-to-rvalue", "Array-to-pointer", "Function-to-pointer", "Function pointer conversion", "Qualification", "Integral promotion", "Floating point promotion", "Complex promotion", "Integral conversion", "Floating conversion", "Complex conversion", "Floating-integral conversion", "Pointer conversion", "Pointer-to-member conversion", "Boolean conversion", "Compatible-types conversion", "Derived-to-base conversion", "Vector conversion", "Vector splat", "Complex-real conversion", "Block Pointer conversion", "Transparent Union Conversion", "Writeback conversion", "OpenCL Zero Event Conversion", "C specific type conversion", "Incompatible pointer conversion" }; return Name[Kind]; } /// StandardConversionSequence - Set the standard conversion /// sequence to the identity conversion. void StandardConversionSequence::setAsIdentityConversion() { First = ICK_Identity; Second = ICK_Identity; Third = ICK_Identity; DeprecatedStringLiteralToCharPtr = false; QualificationIncludesObjCLifetime = false; ReferenceBinding = false; DirectBinding = false; IsLvalueReference = true; BindsToFunctionLvalue = false; BindsToRvalue = false; BindsImplicitObjectArgumentWithoutRefQualifier = false; ObjCLifetimeConversionBinding = false; CopyConstructor = nullptr; } /// getRank - Retrieve the rank of this standard conversion sequence /// (C++ 13.3.3.1.1p3). The rank is the largest rank of each of the /// implicit conversions. ImplicitConversionRank StandardConversionSequence::getRank() const { ImplicitConversionRank Rank = ICR_Exact_Match; if (GetConversionRank(First) > Rank) Rank = GetConversionRank(First); if (GetConversionRank(Second) > Rank) Rank = GetConversionRank(Second); if (GetConversionRank(Third) > Rank) Rank = GetConversionRank(Third); return Rank; } /// isPointerConversionToBool - Determines whether this conversion is /// a conversion of a pointer or pointer-to-member to bool. This is /// used as part of the ranking of standard conversion sequences /// (C++ 13.3.3.2p4). bool StandardConversionSequence::isPointerConversionToBool() const { // Note that FromType has not necessarily been transformed by the // array-to-pointer or function-to-pointer implicit conversions, so // check for their presence as well as checking whether FromType is // a pointer. if (getToType(1)->isBooleanType() && (getFromType()->isPointerType() || getFromType()->isMemberPointerType() || getFromType()->isObjCObjectPointerType() || getFromType()->isBlockPointerType() || getFromType()->isNullPtrType() || First == ICK_Array_To_Pointer || First == ICK_Function_To_Pointer)) return true; return false; } /// isPointerConversionToVoidPointer - Determines whether this /// conversion is a conversion of a pointer to a void pointer. This is /// used as part of the ranking of standard conversion sequences (C++ /// 13.3.3.2p4). bool StandardConversionSequence:: isPointerConversionToVoidPointer(ASTContext& Context) const { QualType FromType = getFromType(); QualType ToType = getToType(1); // Note that FromType has not necessarily been transformed by the // array-to-pointer implicit conversion, so check for its presence // and redo the conversion to get a pointer. if (First == ICK_Array_To_Pointer) FromType = Context.getArrayDecayedType(FromType); if (Second == ICK_Pointer_Conversion && FromType->isAnyPointerType()) if (const PointerType* ToPtrType = ToType->getAs()) return ToPtrType->getPointeeType()->isVoidType(); return false; } /// Skip any implicit casts which could be either part of a narrowing conversion /// or after one in an implicit conversion. static const Expr *IgnoreNarrowingConversion(ASTContext &Ctx, const Expr *Converted) { // We can have cleanups wrapping the converted expression; these need to be // preserved so that destructors run if necessary. if (auto *EWC = dyn_cast(Converted)) { Expr *Inner = const_cast(IgnoreNarrowingConversion(Ctx, EWC->getSubExpr())); return ExprWithCleanups::Create(Ctx, Inner, EWC->cleanupsHaveSideEffects(), EWC->getObjects()); } while (auto *ICE = dyn_cast(Converted)) { switch (ICE->getCastKind()) { case CK_NoOp: case CK_IntegralCast: case CK_IntegralToBoolean: case CK_IntegralToFloating: case CK_BooleanToSignedIntegral: case CK_FloatingToIntegral: case CK_FloatingToBoolean: case CK_FloatingCast: Converted = ICE->getSubExpr(); continue; default: return Converted; } } return Converted; } /// Check if this standard conversion sequence represents a narrowing /// conversion, according to C++11 [dcl.init.list]p7. /// /// \param Ctx The AST context. /// \param Converted The result of applying this standard conversion sequence. /// \param ConstantValue If this is an NK_Constant_Narrowing conversion, the /// value of the expression prior to the narrowing conversion. /// \param ConstantType If this is an NK_Constant_Narrowing conversion, the /// type of the expression prior to the narrowing conversion. /// \param IgnoreFloatToIntegralConversion If true type-narrowing conversions /// from floating point types to integral types should be ignored. NarrowingKind StandardConversionSequence::getNarrowingKind( ASTContext &Ctx, const Expr *Converted, APValue &ConstantValue, QualType &ConstantType, bool IgnoreFloatToIntegralConversion) const { assert(Ctx.getLangOpts().CPlusPlus && "narrowing check outside C++"); // C++11 [dcl.init.list]p7: // A narrowing conversion is an implicit conversion ... QualType FromType = getToType(0); QualType ToType = getToType(1); // A conversion to an enumeration type is narrowing if the conversion to // the underlying type is narrowing. This only arises for expressions of // the form 'Enum{init}'. if (auto *ET = ToType->getAs()) ToType = ET->getDecl()->getIntegerType(); switch (Second) { // 'bool' is an integral type; dispatch to the right place to handle it. case ICK_Boolean_Conversion: if (FromType->isRealFloatingType()) goto FloatingIntegralConversion; if (FromType->isIntegralOrUnscopedEnumerationType()) goto IntegralConversion; // Boolean conversions can be from pointers and pointers to members // [conv.bool], and those aren't considered narrowing conversions. return NK_Not_Narrowing; // -- from a floating-point type to an integer type, or // // -- from an integer type or unscoped enumeration type to a floating-point // type, except where the source is a constant expression and the actual // value after conversion will fit into the target type and will produce // the original value when converted back to the original type, or case ICK_Floating_Integral: FloatingIntegralConversion: if (FromType->isRealFloatingType() && ToType->isIntegralType(Ctx)) { return NK_Type_Narrowing; } else if (FromType->isIntegralOrUnscopedEnumerationType() && ToType->isRealFloatingType()) { if (IgnoreFloatToIntegralConversion) return NK_Not_Narrowing; llvm::APSInt IntConstantValue; const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted); assert(Initializer && "Unknown conversion expression"); // If it's value-dependent, we can't tell whether it's narrowing. if (Initializer->isValueDependent()) return NK_Dependent_Narrowing; if (Initializer->isIntegerConstantExpr(IntConstantValue, Ctx)) { // Convert the integer to the floating type. llvm::APFloat Result(Ctx.getFloatTypeSemantics(ToType)); Result.convertFromAPInt(IntConstantValue, IntConstantValue.isSigned(), llvm::APFloat::rmNearestTiesToEven); // And back. llvm::APSInt ConvertedValue = IntConstantValue; bool ignored; Result.convertToInteger(ConvertedValue, llvm::APFloat::rmTowardZero, &ignored); // If the resulting value is different, this was a narrowing conversion. if (IntConstantValue != ConvertedValue) { ConstantValue = APValue(IntConstantValue); ConstantType = Initializer->getType(); return NK_Constant_Narrowing; } } else { // Variables are always narrowings. return NK_Variable_Narrowing; } } return NK_Not_Narrowing; // -- from long double to double or float, or from double to float, except // where the source is a constant expression and the actual value after // conversion is within the range of values that can be represented (even // if it cannot be represented exactly), or case ICK_Floating_Conversion: if (FromType->isRealFloatingType() && ToType->isRealFloatingType() && Ctx.getFloatingTypeOrder(FromType, ToType) == 1) { // FromType is larger than ToType. const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted); // If it's value-dependent, we can't tell whether it's narrowing. if (Initializer->isValueDependent()) return NK_Dependent_Narrowing; if (Initializer->isCXX11ConstantExpr(Ctx, &ConstantValue)) { // Constant! assert(ConstantValue.isFloat()); llvm::APFloat FloatVal = ConstantValue.getFloat(); // Convert the source value into the target type. bool ignored; llvm::APFloat::opStatus ConvertStatus = FloatVal.convert( Ctx.getFloatTypeSemantics(ToType), llvm::APFloat::rmNearestTiesToEven, &ignored); // If there was no overflow, the source value is within the range of // values that can be represented. if (ConvertStatus & llvm::APFloat::opOverflow) { ConstantType = Initializer->getType(); return NK_Constant_Narrowing; } } else { return NK_Variable_Narrowing; } } return NK_Not_Narrowing; // -- from an integer type or unscoped enumeration type to an integer type // that cannot represent all the values of the original type, except where // the source is a constant expression and the actual value after // conversion will fit into the target type and will produce the original // value when converted back to the original type. case ICK_Integral_Conversion: IntegralConversion: { assert(FromType->isIntegralOrUnscopedEnumerationType()); assert(ToType->isIntegralOrUnscopedEnumerationType()); const bool FromSigned = FromType->isSignedIntegerOrEnumerationType(); const unsigned FromWidth = Ctx.getIntWidth(FromType); const bool ToSigned = ToType->isSignedIntegerOrEnumerationType(); const unsigned ToWidth = Ctx.getIntWidth(ToType); if (FromWidth > ToWidth || (FromWidth == ToWidth && FromSigned != ToSigned) || (FromSigned && !ToSigned)) { // Not all values of FromType can be represented in ToType. llvm::APSInt InitializerValue; const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted); // If it's value-dependent, we can't tell whether it's narrowing. if (Initializer->isValueDependent()) return NK_Dependent_Narrowing; if (!Initializer->isIntegerConstantExpr(InitializerValue, Ctx)) { // Such conversions on variables are always narrowing. return NK_Variable_Narrowing; } bool Narrowing = false; if (FromWidth < ToWidth) { // Negative -> unsigned is narrowing. Otherwise, more bits is never // narrowing. if (InitializerValue.isSigned() && InitializerValue.isNegative()) Narrowing = true; } else { // Add a bit to the InitializerValue so we don't have to worry about // signed vs. unsigned comparisons. InitializerValue = InitializerValue.extend( InitializerValue.getBitWidth() + 1); // Convert the initializer to and from the target width and signed-ness. llvm::APSInt ConvertedValue = InitializerValue; ConvertedValue = ConvertedValue.trunc(ToWidth); ConvertedValue.setIsSigned(ToSigned); ConvertedValue = ConvertedValue.extend(InitializerValue.getBitWidth()); ConvertedValue.setIsSigned(InitializerValue.isSigned()); // If the result is different, this was a narrowing conversion. if (ConvertedValue != InitializerValue) Narrowing = true; } if (Narrowing) { ConstantType = Initializer->getType(); ConstantValue = APValue(InitializerValue); return NK_Constant_Narrowing; } } return NK_Not_Narrowing; } default: // Other kinds of conversions are not narrowings. return NK_Not_Narrowing; } } /// dump - Print this standard conversion sequence to standard /// error. Useful for debugging overloading issues. LLVM_DUMP_METHOD void StandardConversionSequence::dump() const { raw_ostream &OS = llvm::errs(); bool PrintedSomething = false; if (First != ICK_Identity) { OS << GetImplicitConversionName(First); PrintedSomething = true; } if (Second != ICK_Identity) { if (PrintedSomething) { OS << " -> "; } OS << GetImplicitConversionName(Second); if (CopyConstructor) { OS << " (by copy constructor)"; } else if (DirectBinding) { OS << " (direct reference binding)"; } else if (ReferenceBinding) { OS << " (reference binding)"; } PrintedSomething = true; } if (Third != ICK_Identity) { if (PrintedSomething) { OS << " -> "; } OS << GetImplicitConversionName(Third); PrintedSomething = true; } if (!PrintedSomething) { OS << "No conversions required"; } } /// dump - Print this user-defined conversion sequence to standard /// error. Useful for debugging overloading issues. void UserDefinedConversionSequence::dump() const { raw_ostream &OS = llvm::errs(); if (Before.First || Before.Second || Before.Third) { Before.dump(); OS << " -> "; } if (ConversionFunction) OS << '\'' << *ConversionFunction << '\''; else OS << "aggregate initialization"; if (After.First || After.Second || After.Third) { OS << " -> "; After.dump(); } } /// dump - Print this implicit conversion sequence to standard /// error. Useful for debugging overloading issues. void ImplicitConversionSequence::dump() const { raw_ostream &OS = llvm::errs(); if (isStdInitializerListElement()) OS << "Worst std::initializer_list element conversion: "; switch (ConversionKind) { case StandardConversion: OS << "Standard conversion: "; Standard.dump(); break; case UserDefinedConversion: OS << "User-defined conversion: "; UserDefined.dump(); break; case EllipsisConversion: OS << "Ellipsis conversion"; break; case AmbiguousConversion: OS << "Ambiguous conversion"; break; case BadConversion: OS << "Bad conversion"; break; } OS << "\n"; } void AmbiguousConversionSequence::construct() { new (&conversions()) ConversionSet(); } void AmbiguousConversionSequence::destruct() { conversions().~ConversionSet(); } void AmbiguousConversionSequence::copyFrom(const AmbiguousConversionSequence &O) { FromTypePtr = O.FromTypePtr; ToTypePtr = O.ToTypePtr; new (&conversions()) ConversionSet(O.conversions()); } namespace { // Structure used by DeductionFailureInfo to store // template argument information. struct DFIArguments { TemplateArgument FirstArg; TemplateArgument SecondArg; }; // Structure used by DeductionFailureInfo to store // template parameter and template argument information. struct DFIParamWithArguments : DFIArguments { TemplateParameter Param; }; // Structure used by DeductionFailureInfo to store template argument // information and the index of the problematic call argument. struct DFIDeducedMismatchArgs : DFIArguments { TemplateArgumentList *TemplateArgs; unsigned CallArgIndex; }; // Structure used by DeductionFailureInfo to store information about // unsatisfied constraints. struct CNSInfo { TemplateArgumentList *TemplateArgs; ConstraintSatisfaction Satisfaction; }; } /// Convert from Sema's representation of template deduction information /// to the form used in overload-candidate information. DeductionFailureInfo clang::MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK, TemplateDeductionInfo &Info) { DeductionFailureInfo Result; Result.Result = static_cast(TDK); Result.HasDiagnostic = false; switch (TDK) { case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_MiscellaneousDeductionFailure: case Sema::TDK_CUDATargetMismatch: Result.Data = nullptr; break; case Sema::TDK_Incomplete: case Sema::TDK_InvalidExplicitArguments: Result.Data = Info.Param.getOpaqueValue(); break; case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: { // FIXME: Should allocate from normal heap so that we can free this later. auto *Saved = new (Context) DFIDeducedMismatchArgs; Saved->FirstArg = Info.FirstArg; Saved->SecondArg = Info.SecondArg; Saved->TemplateArgs = Info.take(); Saved->CallArgIndex = Info.CallArgIndex; Result.Data = Saved; break; } case Sema::TDK_NonDeducedMismatch: { // FIXME: Should allocate from normal heap so that we can free this later. DFIArguments *Saved = new (Context) DFIArguments; Saved->FirstArg = Info.FirstArg; Saved->SecondArg = Info.SecondArg; Result.Data = Saved; break; } case Sema::TDK_IncompletePack: // FIXME: It's slightly wasteful to allocate two TemplateArguments for this. case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: { // FIXME: Should allocate from normal heap so that we can free this later. DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments; Saved->Param = Info.Param; Saved->FirstArg = Info.FirstArg; Saved->SecondArg = Info.SecondArg; Result.Data = Saved; break; } case Sema::TDK_SubstitutionFailure: Result.Data = Info.take(); if (Info.hasSFINAEDiagnostic()) { PartialDiagnosticAt *Diag = new (Result.Diagnostic) PartialDiagnosticAt( SourceLocation(), PartialDiagnostic::NullDiagnostic()); Info.takeSFINAEDiagnostic(*Diag); Result.HasDiagnostic = true; } break; case Sema::TDK_ConstraintsNotSatisfied: { CNSInfo *Saved = new (Context) CNSInfo; Saved->TemplateArgs = Info.take(); Saved->Satisfaction = Info.AssociatedConstraintsSatisfaction; Result.Data = Saved; break; } case Sema::TDK_Success: case Sema::TDK_NonDependentConversionFailure: llvm_unreachable("not a deduction failure"); } return Result; } void DeductionFailureInfo::Destroy() { switch (static_cast(Result)) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_Incomplete: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_CUDATargetMismatch: case Sema::TDK_NonDependentConversionFailure: break; case Sema::TDK_IncompletePack: case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: // FIXME: Destroy the data? Data = nullptr; break; case Sema::TDK_SubstitutionFailure: // FIXME: Destroy the template argument list? Data = nullptr; if (PartialDiagnosticAt *Diag = getSFINAEDiagnostic()) { Diag->~PartialDiagnosticAt(); HasDiagnostic = false; } break; case Sema::TDK_ConstraintsNotSatisfied: // FIXME: Destroy the template argument list? Data = nullptr; if (PartialDiagnosticAt *Diag = getSFINAEDiagnostic()) { Diag->~PartialDiagnosticAt(); HasDiagnostic = false; } break; // Unhandled case Sema::TDK_MiscellaneousDeductionFailure: break; } } PartialDiagnosticAt *DeductionFailureInfo::getSFINAEDiagnostic() { if (HasDiagnostic) return static_cast(static_cast(Diagnostic)); return nullptr; } TemplateParameter DeductionFailureInfo::getTemplateParameter() { switch (static_cast(Result)) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_SubstitutionFailure: case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_CUDATargetMismatch: case Sema::TDK_NonDependentConversionFailure: case Sema::TDK_ConstraintsNotSatisfied: return TemplateParameter(); case Sema::TDK_Incomplete: case Sema::TDK_InvalidExplicitArguments: return TemplateParameter::getFromOpaqueValue(Data); case Sema::TDK_IncompletePack: case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: return static_cast(Data)->Param; // Unhandled case Sema::TDK_MiscellaneousDeductionFailure: break; } return TemplateParameter(); } TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { switch (static_cast(Result)) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_Incomplete: case Sema::TDK_IncompletePack: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_CUDATargetMismatch: case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: return static_cast(Data)->TemplateArgs; case Sema::TDK_SubstitutionFailure: return static_cast(Data); case Sema::TDK_ConstraintsNotSatisfied: return static_cast(Data)->TemplateArgs; // Unhandled case Sema::TDK_MiscellaneousDeductionFailure: break; } return nullptr; } const TemplateArgument *DeductionFailureInfo::getFirstArg() { switch (static_cast(Result)) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_Incomplete: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_SubstitutionFailure: case Sema::TDK_CUDATargetMismatch: case Sema::TDK_NonDependentConversionFailure: case Sema::TDK_ConstraintsNotSatisfied: return nullptr; case Sema::TDK_IncompletePack: case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: return &static_cast(Data)->FirstArg; // Unhandled case Sema::TDK_MiscellaneousDeductionFailure: break; } return nullptr; } const TemplateArgument *DeductionFailureInfo::getSecondArg() { switch (static_cast(Result)) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_Incomplete: case Sema::TDK_IncompletePack: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_SubstitutionFailure: case Sema::TDK_CUDATargetMismatch: case Sema::TDK_NonDependentConversionFailure: case Sema::TDK_ConstraintsNotSatisfied: return nullptr; case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: return &static_cast(Data)->SecondArg; // Unhandled case Sema::TDK_MiscellaneousDeductionFailure: break; } return nullptr; } llvm::Optional DeductionFailureInfo::getCallArgIndex() { switch (static_cast(Result)) { case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: return static_cast(Data)->CallArgIndex; default: return llvm::None; } } bool OverloadCandidateSet::OperatorRewriteInfo::shouldAddReversed( OverloadedOperatorKind Op) { if (!AllowRewrittenCandidates) return false; return Op == OO_EqualEqual || Op == OO_Spaceship; } bool OverloadCandidateSet::OperatorRewriteInfo::shouldAddReversed( ASTContext &Ctx, const FunctionDecl *FD) { if (!shouldAddReversed(FD->getDeclName().getCXXOverloadedOperator())) return false; // Don't bother adding a reversed candidate that can never be a better // match than the non-reversed version. return FD->getNumParams() != 2 || !Ctx.hasSameUnqualifiedType(FD->getParamDecl(0)->getType(), FD->getParamDecl(1)->getType()) || FD->hasAttr(); } void OverloadCandidateSet::destroyCandidates() { for (iterator i = begin(), e = end(); i != e; ++i) { for (auto &C : i->Conversions) C.~ImplicitConversionSequence(); if (!i->Viable && i->FailureKind == ovl_fail_bad_deduction) i->DeductionFailure.Destroy(); } } void OverloadCandidateSet::clear(CandidateSetKind CSK) { destroyCandidates(); SlabAllocator.Reset(); NumInlineBytesUsed = 0; Candidates.clear(); Functions.clear(); Kind = CSK; } namespace { class UnbridgedCastsSet { struct Entry { Expr **Addr; Expr *Saved; }; SmallVector Entries; public: void save(Sema &S, Expr *&E) { assert(E->hasPlaceholderType(BuiltinType::ARCUnbridgedCast)); Entry entry = { &E, E }; Entries.push_back(entry); E = S.stripARCUnbridgedCast(E); } void restore() { for (SmallVectorImpl::iterator i = Entries.begin(), e = Entries.end(); i != e; ++i) *i->Addr = i->Saved; } }; } /// checkPlaceholderForOverload - Do any interesting placeholder-like /// preprocessing on the given expression. /// /// \param unbridgedCasts a collection to which to add unbridged casts; /// without this, they will be immediately diagnosed as errors /// /// Return true on unrecoverable error. static bool checkPlaceholderForOverload(Sema &S, Expr *&E, UnbridgedCastsSet *unbridgedCasts = nullptr) { if (const BuiltinType *placeholder = E->getType()->getAsPlaceholderType()) { // We can't handle overloaded expressions here because overload // resolution might reasonably tweak them. if (placeholder->getKind() == BuiltinType::Overload) return false; // If the context potentially accepts unbridged ARC casts, strip // the unbridged cast and add it to the collection for later restoration. if (placeholder->getKind() == BuiltinType::ARCUnbridgedCast && unbridgedCasts) { unbridgedCasts->save(S, E); return false; } // Go ahead and check everything else. ExprResult result = S.CheckPlaceholderExpr(E); if (result.isInvalid()) return true; E = result.get(); return false; } // Nothing to do. return false; } /// checkArgPlaceholdersForOverload - Check a set of call operands for /// placeholders. static bool checkArgPlaceholdersForOverload(Sema &S, MultiExprArg Args, UnbridgedCastsSet &unbridged) { for (unsigned i = 0, e = Args.size(); i != e; ++i) if (checkPlaceholderForOverload(S, Args[i], &unbridged)) return true; return false; } /// Determine whether the given New declaration is an overload of the /// declarations in Old. This routine returns Ovl_Match or Ovl_NonFunction if /// New and Old cannot be overloaded, e.g., if New has the same signature as /// some function in Old (C++ 1.3.10) or if the Old declarations aren't /// functions (or function templates) at all. When it does return Ovl_Match or /// Ovl_NonFunction, MatchedDecl will point to the decl that New cannot be /// overloaded with. This decl may be a UsingShadowDecl on top of the underlying /// declaration. /// /// Example: Given the following input: /// /// void f(int, float); // #1 /// void f(int, int); // #2 /// int f(int, int); // #3 /// /// When we process #1, there is no previous declaration of "f", so IsOverload /// will not be used. /// /// When we process #2, Old contains only the FunctionDecl for #1. By comparing /// the parameter types, we see that #1 and #2 are overloaded (since they have /// different signatures), so this routine returns Ovl_Overload; MatchedDecl is /// unchanged. /// /// When we process #3, Old is an overload set containing #1 and #2. We compare /// the signatures of #3 to #1 (they're overloaded, so we do nothing) and then /// #3 to #2. Since the signatures of #3 and #2 are identical (return types of /// functions are not part of the signature), IsOverload returns Ovl_Match and /// MatchedDecl will be set to point to the FunctionDecl for #2. /// /// 'NewIsUsingShadowDecl' indicates that 'New' is being introduced into a class /// by a using declaration. The rules for whether to hide shadow declarations /// ignore some properties which otherwise figure into a function template's /// signature. Sema::OverloadKind Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old, NamedDecl *&Match, bool NewIsUsingDecl) { for (LookupResult::iterator I = Old.begin(), E = Old.end(); I != E; ++I) { NamedDecl *OldD = *I; bool OldIsUsingDecl = false; if (isa(OldD)) { OldIsUsingDecl = true; // We can always introduce two using declarations into the same // context, even if they have identical signatures. if (NewIsUsingDecl) continue; OldD = cast(OldD)->getTargetDecl(); } // A using-declaration does not conflict with another declaration // if one of them is hidden. if ((OldIsUsingDecl || NewIsUsingDecl) && !isVisible(*I)) continue; // If either declaration was introduced by a using declaration, // we'll need to use slightly different rules for matching. // Essentially, these rules are the normal rules, except that // function templates hide function templates with different // return types or template parameter lists. bool UseMemberUsingDeclRules = (OldIsUsingDecl || NewIsUsingDecl) && CurContext->isRecord() && !New->getFriendObjectKind(); if (FunctionDecl *OldF = OldD->getAsFunction()) { if (!IsOverload(New, OldF, UseMemberUsingDeclRules)) { if (UseMemberUsingDeclRules && OldIsUsingDecl) { HideUsingShadowDecl(S, cast(*I)); continue; } if (!isa(OldD) && !shouldLinkPossiblyHiddenDecl(*I, New)) continue; Match = *I; return Ovl_Match; } // Builtins that have custom typechecking or have a reference should // not be overloadable or redeclarable. if (!getASTContext().canBuiltinBeRedeclared(OldF)) { Match = *I; return Ovl_NonFunction; } } else if (isa(OldD) || isa(OldD)) { // We can overload with these, which can show up when doing // redeclaration checks for UsingDecls. assert(Old.getLookupKind() == LookupUsingDeclName); } else if (isa(OldD)) { // We can always overload with tags by hiding them. } else if (auto *UUD = dyn_cast(OldD)) { // Optimistically assume that an unresolved using decl will // overload; if it doesn't, we'll have to diagnose during // template instantiation. // // Exception: if the scope is dependent and this is not a class // member, the using declaration can only introduce an enumerator. if (UUD->getQualifier()->isDependent() && !UUD->isCXXClassMember()) { Match = *I; return Ovl_NonFunction; } } else { // (C++ 13p1): // Only function declarations can be overloaded; object and type // declarations cannot be overloaded. Match = *I; return Ovl_NonFunction; } } // C++ [temp.friend]p1: // For a friend function declaration that is not a template declaration: // -- if the name of the friend is a qualified or unqualified template-id, // [...], otherwise // -- if the name of the friend is a qualified-id and a matching // non-template function is found in the specified class or namespace, // the friend declaration refers to that function, otherwise, // -- if the name of the friend is a qualified-id and a matching function // template is found in the specified class or namespace, the friend // declaration refers to the deduced specialization of that function // template, otherwise // -- the name shall be an unqualified-id [...] // If we get here for a qualified friend declaration, we've just reached the // third bullet. If the type of the friend is dependent, skip this lookup // until instantiation. if (New->getFriendObjectKind() && New->getQualifier() && !New->getDescribedFunctionTemplate() && !New->getDependentSpecializationInfo() && !New->getType()->isDependentType()) { LookupResult TemplateSpecResult(LookupResult::Temporary, Old); TemplateSpecResult.addAllDecls(Old); if (CheckFunctionTemplateSpecialization(New, nullptr, TemplateSpecResult, /*QualifiedFriend*/true)) { New->setInvalidDecl(); return Ovl_Overload; } Match = TemplateSpecResult.getAsSingle(); return Ovl_Match; } return Ovl_Overload; } bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, bool UseMemberUsingDeclRules, bool ConsiderCudaAttrs, bool ConsiderRequiresClauses) { // C++ [basic.start.main]p2: This function shall not be overloaded. if (New->isMain()) return false; // MSVCRT user defined entry points cannot be overloaded. if (New->isMSVCRTEntryPoint()) return false; FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate(); FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate(); // C++ [temp.fct]p2: // A function template can be overloaded with other function templates // and with normal (non-template) functions. if ((OldTemplate == nullptr) != (NewTemplate == nullptr)) return true; // Is the function New an overload of the function Old? QualType OldQType = Context.getCanonicalType(Old->getType()); QualType NewQType = Context.getCanonicalType(New->getType()); // Compare the signatures (C++ 1.3.10) of the two functions to // determine whether they are overloads. If we find any mismatch // in the signature, they are overloads. // If either of these functions is a K&R-style function (no // prototype), then we consider them to have matching signatures. if (isa(OldQType.getTypePtr()) || isa(NewQType.getTypePtr())) return false; const FunctionProtoType *OldType = cast(OldQType); const FunctionProtoType *NewType = cast(NewQType); // The signature of a function includes the types of its // parameters (C++ 1.3.10), which includes the presence or absence // of the ellipsis; see C++ DR 357). if (OldQType != NewQType && (OldType->getNumParams() != NewType->getNumParams() || OldType->isVariadic() != NewType->isVariadic() || !FunctionParamTypesAreEqual(OldType, NewType))) return true; // C++ [temp.over.link]p4: // The signature of a function template consists of its function // signature, its return type and its template parameter list. The names // of the template parameters are significant only for establishing the // relationship between the template parameters and the rest of the // signature. // // We check the return type and template parameter lists for function // templates first; the remaining checks follow. // // However, we don't consider either of these when deciding whether // a member introduced by a shadow declaration is hidden. if (!UseMemberUsingDeclRules && NewTemplate && (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), OldTemplate->getTemplateParameters(), false, TPL_TemplateMatch) || !Context.hasSameType(Old->getDeclaredReturnType(), New->getDeclaredReturnType()))) return true; // If the function is a class member, its signature includes the // cv-qualifiers (if any) and ref-qualifier (if any) on the function itself. // // As part of this, also check whether one of the member functions // is static, in which case they are not overloads (C++ // 13.1p2). While not part of the definition of the signature, // this check is important to determine whether these functions // can be overloaded. CXXMethodDecl *OldMethod = dyn_cast(Old); CXXMethodDecl *NewMethod = dyn_cast(New); if (OldMethod && NewMethod && !OldMethod->isStatic() && !NewMethod->isStatic()) { if (OldMethod->getRefQualifier() != NewMethod->getRefQualifier()) { if (!UseMemberUsingDeclRules && (OldMethod->getRefQualifier() == RQ_None || NewMethod->getRefQualifier() == RQ_None)) { // C++0x [over.load]p2: // - Member function declarations with the same name and the same // parameter-type-list as well as member function template // declarations with the same name, the same parameter-type-list, and // the same template parameter lists cannot be overloaded if any of // them, but not all, have a ref-qualifier (8.3.5). Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload) << NewMethod->getRefQualifier() << OldMethod->getRefQualifier(); Diag(OldMethod->getLocation(), diag::note_previous_declaration); } return true; } // We may not have applied the implicit const for a constexpr member // function yet (because we haven't yet resolved whether this is a static // or non-static member function). Add it now, on the assumption that this // is a redeclaration of OldMethod. auto OldQuals = OldMethod->getMethodQualifiers(); auto NewQuals = NewMethod->getMethodQualifiers(); if (!getLangOpts().CPlusPlus14 && NewMethod->isConstexpr() && !isa(NewMethod)) NewQuals.addConst(); // We do not allow overloading based off of '__restrict'. OldQuals.removeRestrict(); NewQuals.removeRestrict(); if (OldQuals != NewQuals) return true; } // Though pass_object_size is placed on parameters and takes an argument, we // consider it to be a function-level modifier for the sake of function // identity. Either the function has one or more parameters with // pass_object_size or it doesn't. if (functionHasPassObjectSizeParams(New) != functionHasPassObjectSizeParams(Old)) return true; // enable_if attributes are an order-sensitive part of the signature. for (specific_attr_iterator NewI = New->specific_attr_begin(), NewE = New->specific_attr_end(), OldI = Old->specific_attr_begin(), OldE = Old->specific_attr_end(); NewI != NewE || OldI != OldE; ++NewI, ++OldI) { if (NewI == NewE || OldI == OldE) return true; llvm::FoldingSetNodeID NewID, OldID; NewI->getCond()->Profile(NewID, Context, true); OldI->getCond()->Profile(OldID, Context, true); if (NewID != OldID) return true; } if (getLangOpts().CUDA && ConsiderCudaAttrs) { // Don't allow overloading of destructors. (In theory we could, but it // would be a giant change to clang.) if (!isa(New)) { CUDAFunctionTarget NewTarget = IdentifyCUDATarget(New), OldTarget = IdentifyCUDATarget(Old); if (NewTarget != CFT_InvalidTarget) { assert((OldTarget != CFT_InvalidTarget) && "Unexpected invalid target."); // Allow overloading of functions with same signature and different CUDA // target attributes. if (NewTarget != OldTarget) return true; } } } if (ConsiderRequiresClauses) { Expr *NewRC = New->getTrailingRequiresClause(), *OldRC = Old->getTrailingRequiresClause(); if ((NewRC != nullptr) != (OldRC != nullptr)) // RC are most certainly different - these are overloads. return true; if (NewRC) { llvm::FoldingSetNodeID NewID, OldID; NewRC->Profile(NewID, Context, /*Canonical=*/true); OldRC->Profile(OldID, Context, /*Canonical=*/true); if (NewID != OldID) // RCs are not equivalent - these are overloads. return true; } } // The signatures match; this is not an overload. return false; } /// Tries a user-defined conversion from From to ToType. /// /// Produces an implicit conversion sequence for when a standard conversion /// is not an option. See TryImplicitConversion for more information. static ImplicitConversionSequence TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType, bool SuppressUserConversions, bool AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion, bool AllowObjCConversionOnExplicit) { ImplicitConversionSequence ICS; if (SuppressUserConversions) { // We're not in the case above, so there is no conversion that // we can perform. ICS.setBad(BadConversionSequence::no_conversion, From, ToType); return ICS; } // Attempt user-defined conversion. OverloadCandidateSet Conversions(From->getExprLoc(), OverloadCandidateSet::CSK_Normal); switch (IsUserDefinedConversion(S, From, ToType, ICS.UserDefined, Conversions, AllowExplicit, AllowObjCConversionOnExplicit)) { case OR_Success: case OR_Deleted: ICS.setUserDefined(); // C++ [over.ics.user]p4: // A conversion of an expression of class type to the same class // type is given Exact Match rank, and a conversion of an // expression of class type to a base class of that type is // given Conversion rank, in spite of the fact that a copy // constructor (i.e., a user-defined conversion function) is // called for those cases. if (CXXConstructorDecl *Constructor = dyn_cast(ICS.UserDefined.ConversionFunction)) { QualType FromCanon = S.Context.getCanonicalType(From->getType().getUnqualifiedType()); QualType ToCanon = S.Context.getCanonicalType(ToType).getUnqualifiedType(); if (Constructor->isCopyConstructor() && (FromCanon == ToCanon || S.IsDerivedFrom(From->getBeginLoc(), FromCanon, ToCanon))) { // Turn this into a "standard" conversion sequence, so that it // gets ranked with standard conversion sequences. DeclAccessPair Found = ICS.UserDefined.FoundConversionFunction; ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); ICS.Standard.setFromType(From->getType()); ICS.Standard.setAllToTypes(ToType); ICS.Standard.CopyConstructor = Constructor; ICS.Standard.FoundCopyConstructor = Found; if (ToCanon != FromCanon) ICS.Standard.Second = ICK_Derived_To_Base; } } break; case OR_Ambiguous: ICS.setAmbiguous(); ICS.Ambiguous.setFromType(From->getType()); ICS.Ambiguous.setToType(ToType); for (OverloadCandidateSet::iterator Cand = Conversions.begin(); Cand != Conversions.end(); ++Cand) if (Cand->Best) ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function); break; // Fall through. case OR_No_Viable_Function: ICS.setBad(BadConversionSequence::no_conversion, From, ToType); break; } return ICS; } /// TryImplicitConversion - Attempt to perform an implicit conversion /// from the given expression (Expr) to the given type (ToType). This /// function returns an implicit conversion sequence that can be used /// to perform the initialization. Given /// /// void f(float f); /// void g(int i) { f(i); } /// /// this routine would produce an implicit conversion sequence to /// describe the initialization of f from i, which will be a standard /// conversion sequence containing an lvalue-to-rvalue conversion (C++ /// 4.1) followed by a floating-integral conversion (C++ 4.9). // /// Note that this routine only determines how the conversion can be /// performed; it does not actually perform the conversion. As such, /// it will not produce any diagnostics if no conversion is available, /// but will instead return an implicit conversion sequence of kind /// "BadConversion". /// /// If @p SuppressUserConversions, then user-defined conversions are /// not permitted. /// If @p AllowExplicit, then explicit user-defined conversions are /// permitted. /// /// \param AllowObjCWritebackConversion Whether we allow the Objective-C /// writeback conversion, which allows __autoreleasing id* parameters to /// be initialized with __strong id* or __weak id* arguments. static ImplicitConversionSequence TryImplicitConversion(Sema &S, Expr *From, QualType ToType, bool SuppressUserConversions, bool AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion, bool AllowObjCConversionOnExplicit) { ImplicitConversionSequence ICS; if (IsStandardConversion(S, From, ToType, InOverloadResolution, ICS.Standard, CStyle, AllowObjCWritebackConversion)){ ICS.setStandard(); return ICS; } if (!S.getLangOpts().CPlusPlus) { ICS.setBad(BadConversionSequence::no_conversion, From, ToType); return ICS; } // C++ [over.ics.user]p4: // A conversion of an expression of class type to the same class // type is given Exact Match rank, and a conversion of an // expression of class type to a base class of that type is // given Conversion rank, in spite of the fact that a copy/move // constructor (i.e., a user-defined conversion function) is // called for those cases. QualType FromType = From->getType(); if (ToType->getAs() && FromType->getAs() && (S.Context.hasSameUnqualifiedType(FromType, ToType) || S.IsDerivedFrom(From->getBeginLoc(), FromType, ToType))) { ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); ICS.Standard.setFromType(FromType); ICS.Standard.setAllToTypes(ToType); // We don't actually check at this point whether there is a valid // copy/move constructor, since overloading just assumes that it // exists. When we actually perform initialization, we'll find the // appropriate constructor to copy the returned object, if needed. ICS.Standard.CopyConstructor = nullptr; // Determine whether this is considered a derived-to-base conversion. if (!S.Context.hasSameUnqualifiedType(FromType, ToType)) ICS.Standard.Second = ICK_Derived_To_Base; return ICS; } return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions, AllowExplicit, InOverloadResolution, CStyle, AllowObjCWritebackConversion, AllowObjCConversionOnExplicit); } ImplicitConversionSequence Sema::TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, bool AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion) { return ::TryImplicitConversion(*this, From, ToType, SuppressUserConversions, AllowExplicit, InOverloadResolution, CStyle, AllowObjCWritebackConversion, /*AllowObjCConversionOnExplicit=*/false); } /// PerformImplicitConversion - Perform an implicit conversion of the /// expression From to the type ToType. Returns the /// converted expression. Flavor is the kind of conversion we're /// performing, used in the error message. If @p AllowExplicit, /// explicit user-defined conversions are permitted. ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit) { ImplicitConversionSequence ICS; return PerformImplicitConversion(From, ToType, Action, AllowExplicit, ICS); } ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit, ImplicitConversionSequence& ICS) { if (checkPlaceholderForOverload(*this, From)) return ExprError(); // Objective-C ARC: Determine whether we will allow the writeback conversion. bool AllowObjCWritebackConversion = getLangOpts().ObjCAutoRefCount && (Action == AA_Passing || Action == AA_Sending); if (getLangOpts().ObjC) CheckObjCBridgeRelatedConversions(From->getBeginLoc(), ToType, From->getType(), From); ICS = ::TryImplicitConversion(*this, From, ToType, /*SuppressUserConversions=*/false, AllowExplicit, /*InOverloadResolution=*/false, /*CStyle=*/false, AllowObjCWritebackConversion, /*AllowObjCConversionOnExplicit=*/false); return PerformImplicitConversion(From, ToType, ICS, Action); } /// Determine whether the conversion from FromType to ToType is a valid /// conversion that strips "noexcept" or "noreturn" off the nested function /// type. bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, QualType &ResultTy) { if (Context.hasSameUnqualifiedType(FromType, ToType)) return false; // Permit the conversion F(t __attribute__((noreturn))) -> F(t) // or F(t noexcept) -> F(t) // where F adds one of the following at most once: // - a pointer // - a member pointer // - a block pointer // Changes here need matching changes in FindCompositePointerType. CanQualType CanTo = Context.getCanonicalType(ToType); CanQualType CanFrom = Context.getCanonicalType(FromType); Type::TypeClass TyClass = CanTo->getTypeClass(); if (TyClass != CanFrom->getTypeClass()) return false; if (TyClass != Type::FunctionProto && TyClass != Type::FunctionNoProto) { if (TyClass == Type::Pointer) { CanTo = CanTo.castAs()->getPointeeType(); CanFrom = CanFrom.castAs()->getPointeeType(); } else if (TyClass == Type::BlockPointer) { CanTo = CanTo.castAs()->getPointeeType(); CanFrom = CanFrom.castAs()->getPointeeType(); } else if (TyClass == Type::MemberPointer) { auto ToMPT = CanTo.castAs(); auto FromMPT = CanFrom.castAs(); // A function pointer conversion cannot change the class of the function. if (ToMPT->getClass() != FromMPT->getClass()) return false; CanTo = ToMPT->getPointeeType(); CanFrom = FromMPT->getPointeeType(); } else { return false; } TyClass = CanTo->getTypeClass(); if (TyClass != CanFrom->getTypeClass()) return false; if (TyClass != Type::FunctionProto && TyClass != Type::FunctionNoProto) return false; } const auto *FromFn = cast(CanFrom); FunctionType::ExtInfo FromEInfo = FromFn->getExtInfo(); const auto *ToFn = cast(CanTo); FunctionType::ExtInfo ToEInfo = ToFn->getExtInfo(); bool Changed = false; // Drop 'noreturn' if not present in target type. if (FromEInfo.getNoReturn() && !ToEInfo.getNoReturn()) { FromFn = Context.adjustFunctionType(FromFn, FromEInfo.withNoReturn(false)); Changed = true; } // Drop 'noexcept' if not present in target type. if (const auto *FromFPT = dyn_cast(FromFn)) { const auto *ToFPT = cast(ToFn); if (FromFPT->isNothrow() && !ToFPT->isNothrow()) { FromFn = cast( Context.getFunctionTypeWithExceptionSpec(QualType(FromFPT, 0), EST_None) .getTypePtr()); Changed = true; } // Convert FromFPT's ExtParameterInfo if necessary. The conversion is valid // only if the ExtParameterInfo lists of the two function prototypes can be // merged and the merged list is identical to ToFPT's ExtParameterInfo list. SmallVector NewParamInfos; bool CanUseToFPT, CanUseFromFPT; if (Context.mergeExtParameterInfo(ToFPT, FromFPT, CanUseToFPT, CanUseFromFPT, NewParamInfos) && CanUseToFPT && !CanUseFromFPT) { FunctionProtoType::ExtProtoInfo ExtInfo = FromFPT->getExtProtoInfo(); ExtInfo.ExtParameterInfos = NewParamInfos.empty() ? nullptr : NewParamInfos.data(); QualType QT = Context.getFunctionType(FromFPT->getReturnType(), FromFPT->getParamTypes(), ExtInfo); FromFn = QT->getAs(); Changed = true; } } if (!Changed) return false; assert(QualType(FromFn, 0).isCanonical()); if (QualType(FromFn, 0) != CanTo) return false; ResultTy = ToType; return true; } /// Determine whether the conversion from FromType to ToType is a valid /// vector conversion. /// /// \param ICK Will be set to the vector conversion kind, if this is a vector /// conversion. static bool IsVectorConversion(Sema &S, QualType FromType, QualType ToType, ImplicitConversionKind &ICK) { // We need at least one of these types to be a vector type to have a vector // conversion. if (!ToType->isVectorType() && !FromType->isVectorType()) return false; // Identical types require no conversions. if (S.Context.hasSameUnqualifiedType(FromType, ToType)) return false; // There are no conversions between extended vector types, only identity. if (ToType->isExtVectorType()) { // There are no conversions between extended vector types other than the // identity conversion. if (FromType->isExtVectorType()) return false; // Vector splat from any arithmetic type to a vector. if (FromType->isArithmeticType()) { ICK = ICK_Vector_Splat; return true; } } // We can perform the conversion between vector types in the following cases: // 1)vector types are equivalent AltiVec and GCC vector types // 2)lax vector conversions are permitted and the vector types are of the // same size if (ToType->isVectorType() && FromType->isVectorType()) { if (S.Context.areCompatibleVectorTypes(FromType, ToType) || S.isLaxVectorConversion(FromType, ToType)) { ICK = ICK_Vector_Conversion; return true; } } return false; } static bool tryAtomicConversion(Sema &S, Expr *From, QualType ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle); /// IsStandardConversion - Determines whether there is a standard /// conversion sequence (C++ [conv], C++ [over.ics.scs]) from the /// expression From to the type ToType. Standard conversion sequences /// only consider non-class types; for conversions that involve class /// types, use TryImplicitConversion. If a conversion exists, SCS will /// contain the standard conversion sequence required to perform this /// conversion and this routine will return true. Otherwise, this /// routine will return false and the value of SCS is unspecified. static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle, bool AllowObjCWritebackConversion) { QualType FromType = From->getType(); // Standard conversions (C++ [conv]) SCS.setAsIdentityConversion(); SCS.IncompatibleObjC = false; SCS.setFromType(FromType); SCS.CopyConstructor = nullptr; // There are no standard conversions for class types in C++, so // abort early. When overloading in C, however, we do permit them. if (S.getLangOpts().CPlusPlus && (FromType->isRecordType() || ToType->isRecordType())) return false; // The first conversion can be an lvalue-to-rvalue conversion, // array-to-pointer conversion, or function-to-pointer conversion // (C++ 4p1). if (FromType == S.Context.OverloadTy) { DeclAccessPair AccessPair; if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(From, ToType, false, AccessPair)) { // We were able to resolve the address of the overloaded function, // so we can convert to the type of that function. FromType = Fn->getType(); SCS.setFromType(FromType); // we can sometimes resolve &foo regardless of ToType, so check // if the type matches (identity) or we are converting to bool if (!S.Context.hasSameUnqualifiedType( S.ExtractUnqualifiedFunctionType(ToType), FromType)) { QualType resultTy; // if the function type matches except for [[noreturn]], it's ok if (!S.IsFunctionConversion(FromType, S.ExtractUnqualifiedFunctionType(ToType), resultTy)) // otherwise, only a boolean conversion is standard if (!ToType->isBooleanType()) return false; } // Check if the "from" expression is taking the address of an overloaded // function and recompute the FromType accordingly. Take advantage of the // fact that non-static member functions *must* have such an address-of // expression. CXXMethodDecl *Method = dyn_cast(Fn); if (Method && !Method->isStatic()) { assert(isa(From->IgnoreParens()) && "Non-unary operator on non-static member address"); assert(cast(From->IgnoreParens())->getOpcode() == UO_AddrOf && "Non-address-of operator on non-static member address"); const Type *ClassType = S.Context.getTypeDeclType(Method->getParent()).getTypePtr(); FromType = S.Context.getMemberPointerType(FromType, ClassType); } else if (isa(From->IgnoreParens())) { assert(cast(From->IgnoreParens())->getOpcode() == UO_AddrOf && "Non-address-of operator for overloaded function expression"); FromType = S.Context.getPointerType(FromType); } // Check that we've computed the proper type after overload resolution. // FIXME: FixOverloadedFunctionReference has side-effects; we shouldn't // be calling it from within an NDEBUG block. assert(S.Context.hasSameType( FromType, S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType())); } else { return false; } } // Lvalue-to-rvalue conversion (C++11 4.1): // A glvalue (3.10) of a non-function, non-array type T can // be converted to a prvalue. bool argIsLValue = From->isGLValue(); if (argIsLValue && !FromType->isFunctionType() && !FromType->isArrayType() && S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) { SCS.First = ICK_Lvalue_To_Rvalue; // C11 6.3.2.1p2: // ... if the lvalue has atomic type, the value has the non-atomic version // of the type of the lvalue ... if (const AtomicType *Atomic = FromType->getAs()) FromType = Atomic->getValueType(); // If T is a non-class type, the type of the rvalue is the // cv-unqualified version of T. Otherwise, the type of the rvalue // is T (C++ 4.1p1). C++ can't get here with class types; in C, we // just strip the qualifiers because they don't matter. FromType = FromType.getUnqualifiedType(); } else if (FromType->isArrayType()) { // Array-to-pointer conversion (C++ 4.2) SCS.First = ICK_Array_To_Pointer; // An lvalue or rvalue of type "array of N T" or "array of unknown // bound of T" can be converted to an rvalue of type "pointer to // T" (C++ 4.2p1). FromType = S.Context.getArrayDecayedType(FromType); if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) { // This conversion is deprecated in C++03 (D.4) SCS.DeprecatedStringLiteralToCharPtr = true; // For the purpose of ranking in overload resolution // (13.3.3.1.1), this conversion is considered an // array-to-pointer conversion followed by a qualification // conversion (4.4). (C++ 4.2p2) SCS.Second = ICK_Identity; SCS.Third = ICK_Qualification; SCS.QualificationIncludesObjCLifetime = false; SCS.setAllToTypes(FromType); return true; } } else if (FromType->isFunctionType() && argIsLValue) { // Function-to-pointer conversion (C++ 4.3). SCS.First = ICK_Function_To_Pointer; if (auto *DRE = dyn_cast(From->IgnoreParenCasts())) if (auto *FD = dyn_cast(DRE->getDecl())) if (!S.checkAddressOfFunctionIsAvailable(FD)) return false; // An lvalue of function type T can be converted to an rvalue of // type "pointer to T." The result is a pointer to the // function. (C++ 4.3p1). FromType = S.Context.getPointerType(FromType); } else { // We don't require any conversions for the first step. SCS.First = ICK_Identity; } SCS.setToType(0, FromType); // The second conversion can be an integral promotion, floating // point promotion, integral conversion, floating point conversion, // floating-integral conversion, pointer conversion, // pointer-to-member conversion, or boolean conversion (C++ 4p1). // For overloading in C, this can also be a "compatible-type" // conversion. bool IncompatibleObjC = false; ImplicitConversionKind SecondICK = ICK_Identity; if (S.Context.hasSameUnqualifiedType(FromType, ToType)) { // The unqualified versions of the types are the same: there's no // conversion to do. SCS.Second = ICK_Identity; } else if (S.IsIntegralPromotion(From, FromType, ToType)) { // Integral promotion (C++ 4.5). SCS.Second = ICK_Integral_Promotion; FromType = ToType.getUnqualifiedType(); } else if (S.IsFloatingPointPromotion(FromType, ToType)) { // Floating point promotion (C++ 4.6). SCS.Second = ICK_Floating_Promotion; FromType = ToType.getUnqualifiedType(); } else if (S.IsComplexPromotion(FromType, ToType)) { // Complex promotion (Clang extension) SCS.Second = ICK_Complex_Promotion; FromType = ToType.getUnqualifiedType(); } else if (ToType->isBooleanType() && (FromType->isArithmeticType() || FromType->isAnyPointerType() || FromType->isBlockPointerType() || FromType->isMemberPointerType() || FromType->isNullPtrType())) { // Boolean conversions (C++ 4.12). SCS.Second = ICK_Boolean_Conversion; FromType = S.Context.BoolTy; } else if (FromType->isIntegralOrUnscopedEnumerationType() && ToType->isIntegralType(S.Context)) { // Integral conversions (C++ 4.7). SCS.Second = ICK_Integral_Conversion; FromType = ToType.getUnqualifiedType(); } else if (FromType->isAnyComplexType() && ToType->isAnyComplexType()) { // Complex conversions (C99 6.3.1.6) SCS.Second = ICK_Complex_Conversion; FromType = ToType.getUnqualifiedType(); } else if ((FromType->isAnyComplexType() && ToType->isArithmeticType()) || (ToType->isAnyComplexType() && FromType->isArithmeticType())) { // Complex-real conversions (C99 6.3.1.7) SCS.Second = ICK_Complex_Real; FromType = ToType.getUnqualifiedType(); } else if (FromType->isRealFloatingType() && ToType->isRealFloatingType()) { // FIXME: disable conversions between long double and __float128 if // their representation is different until there is back end support // We of course allow this conversion if long double is really double. if (&S.Context.getFloatTypeSemantics(FromType) != &S.Context.getFloatTypeSemantics(ToType)) { bool Float128AndLongDouble = ((FromType == S.Context.Float128Ty && ToType == S.Context.LongDoubleTy) || (FromType == S.Context.LongDoubleTy && ToType == S.Context.Float128Ty)); if (Float128AndLongDouble && (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) == &llvm::APFloat::PPCDoubleDouble())) return false; } // Floating point conversions (C++ 4.8). SCS.Second = ICK_Floating_Conversion; FromType = ToType.getUnqualifiedType(); } else if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || (FromType->isIntegralOrUnscopedEnumerationType() && ToType->isRealFloatingType())) { // Floating-integral conversions (C++ 4.9). SCS.Second = ICK_Floating_Integral; FromType = ToType.getUnqualifiedType(); } else if (S.IsBlockPointerConversion(FromType, ToType, FromType)) { SCS.Second = ICK_Block_Pointer_Conversion; } else if (AllowObjCWritebackConversion && S.isObjCWritebackConversion(FromType, ToType, FromType)) { SCS.Second = ICK_Writeback_Conversion; } else if (S.IsPointerConversion(From, FromType, ToType, InOverloadResolution, FromType, IncompatibleObjC)) { // Pointer conversions (C++ 4.10). SCS.Second = ICK_Pointer_Conversion; SCS.IncompatibleObjC = IncompatibleObjC; FromType = FromType.getUnqualifiedType(); } else if (S.IsMemberPointerConversion(From, FromType, ToType, InOverloadResolution, FromType)) { // Pointer to member conversions (4.11). SCS.Second = ICK_Pointer_Member; } else if (IsVectorConversion(S, FromType, ToType, SecondICK)) { SCS.Second = SecondICK; FromType = ToType.getUnqualifiedType(); } else if (!S.getLangOpts().CPlusPlus && S.Context.typesAreCompatible(ToType, FromType)) { // Compatible conversions (Clang extension for C function overloading) SCS.Second = ICK_Compatible_Conversion; FromType = ToType.getUnqualifiedType(); } else if (IsTransparentUnionStandardConversion(S, From, ToType, InOverloadResolution, SCS, CStyle)) { SCS.Second = ICK_TransparentUnionConversion; FromType = ToType; } else if (tryAtomicConversion(S, From, ToType, InOverloadResolution, SCS, CStyle)) { // tryAtomicConversion has updated the standard conversion sequence // appropriately. return true; } else if (ToType->isEventT() && From->isIntegerConstantExpr(S.getASTContext()) && From->EvaluateKnownConstInt(S.getASTContext()) == 0) { SCS.Second = ICK_Zero_Event_Conversion; FromType = ToType; } else if (ToType->isQueueT() && From->isIntegerConstantExpr(S.getASTContext()) && (From->EvaluateKnownConstInt(S.getASTContext()) == 0)) { SCS.Second = ICK_Zero_Queue_Conversion; FromType = ToType; } else if (ToType->isSamplerT() && From->isIntegerConstantExpr(S.getASTContext())) { SCS.Second = ICK_Compatible_Conversion; FromType = ToType; } else { // No second conversion required. SCS.Second = ICK_Identity; } SCS.setToType(1, FromType); // The third conversion can be a function pointer conversion or a // qualification conversion (C++ [conv.fctptr], [conv.qual]). bool ObjCLifetimeConversion; if (S.IsFunctionConversion(FromType, ToType, FromType)) { // Function pointer conversions (removing 'noexcept') including removal of // 'noreturn' (Clang extension). SCS.Third = ICK_Function_Conversion; } else if (S.IsQualificationConversion(FromType, ToType, CStyle, ObjCLifetimeConversion)) { SCS.Third = ICK_Qualification; SCS.QualificationIncludesObjCLifetime = ObjCLifetimeConversion; FromType = ToType; } else { // No conversion required SCS.Third = ICK_Identity; } // C++ [over.best.ics]p6: // [...] Any difference in top-level cv-qualification is // subsumed by the initialization itself and does not constitute // a conversion. [...] QualType CanonFrom = S.Context.getCanonicalType(FromType); QualType CanonTo = S.Context.getCanonicalType(ToType); if (CanonFrom.getLocalUnqualifiedType() == CanonTo.getLocalUnqualifiedType() && CanonFrom.getLocalQualifiers() != CanonTo.getLocalQualifiers()) { FromType = ToType; CanonFrom = CanonTo; } SCS.setToType(2, FromType); if (CanonFrom == CanonTo) return true; // If we have not converted the argument type to the parameter type, // this is a bad conversion sequence, unless we're resolving an overload in C. if (S.getLangOpts().CPlusPlus || !InOverloadResolution) return false; ExprResult ER = ExprResult{From}; Sema::AssignConvertType Conv = S.CheckSingleAssignmentConstraints(ToType, ER, /*Diagnose=*/false, /*DiagnoseCFAudited=*/false, /*ConvertRHS=*/false); ImplicitConversionKind SecondConv; switch (Conv) { case Sema::Compatible: SecondConv = ICK_C_Only_Conversion; break; // For our purposes, discarding qualifiers is just as bad as using an // incompatible pointer. Note that an IncompatiblePointer conversion can drop // qualifiers, as well. case Sema::CompatiblePointerDiscardsQualifiers: case Sema::IncompatiblePointer: case Sema::IncompatiblePointerSign: SecondConv = ICK_Incompatible_Pointer_Conversion; break; default: return false; } // First can only be an lvalue conversion, so we pretend that this was the // second conversion. First should already be valid from earlier in the // function. SCS.Second = SecondConv; SCS.setToType(1, ToType); // Third is Identity, because Second should rank us worse than any other // conversion. This could also be ICK_Qualification, but it's simpler to just // lump everything in with the second conversion, and we don't gain anything // from making this ICK_Qualification. SCS.Third = ICK_Identity; SCS.setToType(2, ToType); return true; } static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From, QualType &ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle) { const RecordType *UT = ToType->getAsUnionType(); if (!UT || !UT->getDecl()->hasAttr()) return false; // The field to initialize within the transparent union. RecordDecl *UD = UT->getDecl(); // It's compatible if the expression matches any of the fields. for (const auto *it : UD->fields()) { if (IsStandardConversion(S, From, it->getType(), InOverloadResolution, SCS, CStyle, /*AllowObjCWritebackConversion=*/false)) { ToType = it->getType(); return true; } } return false; } /// IsIntegralPromotion - Determines whether the conversion from the /// expression From (whose potentially-adjusted type is FromType) to /// ToType is an integral promotion (C++ 4.5). If so, returns true and /// sets PromotedType to the promoted type. bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { const BuiltinType *To = ToType->getAs(); // All integers are built-in. if (!To) { return false; } // An rvalue of type char, signed char, unsigned char, short int, or // unsigned short int can be converted to an rvalue of type int if // int can represent all the values of the source type; otherwise, // the source rvalue can be converted to an rvalue of type unsigned // int (C++ 4.5p1). if (FromType->isPromotableIntegerType() && !FromType->isBooleanType() && !FromType->isEnumeralType()) { if (// We can promote any signed, promotable integer type to an int (FromType->isSignedIntegerType() || // We can promote any unsigned integer type whose size is // less than int to an int. Context.getTypeSize(FromType) < Context.getTypeSize(ToType))) { return To->getKind() == BuiltinType::Int; } return To->getKind() == BuiltinType::UInt; } // C++11 [conv.prom]p3: // A prvalue of an unscoped enumeration type whose underlying type is not // fixed (7.2) can be converted to an rvalue a prvalue of the first of the // following types that can represent all the values of the enumeration // (i.e., the values in the range bmin to bmax as described in 7.2): int, // unsigned int, long int, unsigned long int, long long int, or unsigned // long long int. If none of the types in that list can represent all the // values of the enumeration, an rvalue a prvalue of an unscoped enumeration // type can be converted to an rvalue a prvalue of the extended integer type // with lowest integer conversion rank (4.13) greater than the rank of long // long in which all the values of the enumeration can be represented. If // there are two such extended types, the signed one is chosen. // C++11 [conv.prom]p4: // A prvalue of an unscoped enumeration type whose underlying type is fixed // can be converted to a prvalue of its underlying type. Moreover, if // integral promotion can be applied to its underlying type, a prvalue of an // unscoped enumeration type whose underlying type is fixed can also be // converted to a prvalue of the promoted underlying type. if (const EnumType *FromEnumType = FromType->getAs()) { // C++0x 7.2p9: Note that this implicit enum to int conversion is not // provided for a scoped enumeration. if (FromEnumType->getDecl()->isScoped()) return false; // We can perform an integral promotion to the underlying type of the enum, // even if that's not the promoted type. Note that the check for promoting // the underlying type is based on the type alone, and does not consider // the bitfield-ness of the actual source expression. if (FromEnumType->getDecl()->isFixed()) { QualType Underlying = FromEnumType->getDecl()->getIntegerType(); return Context.hasSameUnqualifiedType(Underlying, ToType) || IsIntegralPromotion(nullptr, Underlying, ToType); } // We have already pre-calculated the promotion type, so this is trivial. if (ToType->isIntegerType() && isCompleteType(From->getBeginLoc(), FromType)) return Context.hasSameUnqualifiedType( ToType, FromEnumType->getDecl()->getPromotionType()); // C++ [conv.prom]p5: // If the bit-field has an enumerated type, it is treated as any other // value of that type for promotion purposes. // // ... so do not fall through into the bit-field checks below in C++. if (getLangOpts().CPlusPlus) return false; } // C++0x [conv.prom]p2: // A prvalue of type char16_t, char32_t, or wchar_t (3.9.1) can be converted // to an rvalue a prvalue of the first of the following types that can // represent all the values of its underlying type: int, unsigned int, // long int, unsigned long int, long long int, or unsigned long long int. // If none of the types in that list can represent all the values of its // underlying type, an rvalue a prvalue of type char16_t, char32_t, // or wchar_t can be converted to an rvalue a prvalue of its underlying // type. if (FromType->isAnyCharacterType() && !FromType->isCharType() && ToType->isIntegerType()) { // Determine whether the type we're converting from is signed or // unsigned. bool FromIsSigned = FromType->isSignedIntegerType(); uint64_t FromSize = Context.getTypeSize(FromType); // The types we'll try to promote to, in the appropriate // order. Try each of these types. QualType PromoteTypes[6] = { Context.IntTy, Context.UnsignedIntTy, Context.LongTy, Context.UnsignedLongTy , Context.LongLongTy, Context.UnsignedLongLongTy }; for (int Idx = 0; Idx < 6; ++Idx) { uint64_t ToSize = Context.getTypeSize(PromoteTypes[Idx]); if (FromSize < ToSize || (FromSize == ToSize && FromIsSigned == PromoteTypes[Idx]->isSignedIntegerType())) { // We found the type that we can promote to. If this is the // type we wanted, we have a promotion. Otherwise, no // promotion. return Context.hasSameUnqualifiedType(ToType, PromoteTypes[Idx]); } } } // An rvalue for an integral bit-field (9.6) can be converted to an // rvalue of type int if int can represent all the values of the // bit-field; otherwise, it can be converted to unsigned int if // unsigned int can represent all the values of the bit-field. If // the bit-field is larger yet, no integral promotion applies to // it. If the bit-field has an enumerated type, it is treated as any // other value of that type for promotion purposes (C++ 4.5p3). // FIXME: We should delay checking of bit-fields until we actually perform the // conversion. // // FIXME: In C, only bit-fields of types _Bool, int, or unsigned int may be // promoted, per C11 6.3.1.1/2. We promote all bit-fields (including enum // bit-fields and those whose underlying type is larger than int) for GCC // compatibility. if (From) { if (FieldDecl *MemberDecl = From->getSourceBitField()) { llvm::APSInt BitWidth; if (FromType->isIntegralType(Context) && MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) { llvm::APSInt ToSize(BitWidth.getBitWidth(), BitWidth.isUnsigned()); ToSize = Context.getTypeSize(ToType); // Are we promoting to an int from a bitfield that fits in an int? if (BitWidth < ToSize || (FromType->isSignedIntegerType() && BitWidth <= ToSize)) { return To->getKind() == BuiltinType::Int; } // Are we promoting to an unsigned int from an unsigned bitfield // that fits into an unsigned int? if (FromType->isUnsignedIntegerType() && BitWidth <= ToSize) { return To->getKind() == BuiltinType::UInt; } return false; } } } // An rvalue of type bool can be converted to an rvalue of type int, // with false becoming zero and true becoming one (C++ 4.5p4). if (FromType->isBooleanType() && To->getKind() == BuiltinType::Int) { return true; } return false; } /// IsFloatingPointPromotion - Determines whether the conversion from /// FromType to ToType is a floating point promotion (C++ 4.6). If so, /// returns true and sets PromotedType to the promoted type. bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType) { if (const BuiltinType *FromBuiltin = FromType->getAs()) if (const BuiltinType *ToBuiltin = ToType->getAs()) { /// An rvalue of type float can be converted to an rvalue of type /// double. (C++ 4.6p1). if (FromBuiltin->getKind() == BuiltinType::Float && ToBuiltin->getKind() == BuiltinType::Double) return true; // C99 6.3.1.5p1: // When a float is promoted to double or long double, or a // double is promoted to long double [...]. if (!getLangOpts().CPlusPlus && (FromBuiltin->getKind() == BuiltinType::Float || FromBuiltin->getKind() == BuiltinType::Double) && (ToBuiltin->getKind() == BuiltinType::LongDouble || ToBuiltin->getKind() == BuiltinType::Float128)) return true; // Half can be promoted to float. if (!getLangOpts().NativeHalfType && FromBuiltin->getKind() == BuiltinType::Half && ToBuiltin->getKind() == BuiltinType::Float) return true; } return false; } /// Determine if a conversion is a complex promotion. /// /// A complex promotion is defined as a complex -> complex conversion /// where the conversion between the underlying real types is a /// floating-point or integral promotion. bool Sema::IsComplexPromotion(QualType FromType, QualType ToType) { const ComplexType *FromComplex = FromType->getAs(); if (!FromComplex) return false; const ComplexType *ToComplex = ToType->getAs(); if (!ToComplex) return false; return IsFloatingPointPromotion(FromComplex->getElementType(), ToComplex->getElementType()) || IsIntegralPromotion(nullptr, FromComplex->getElementType(), ToComplex->getElementType()); } /// BuildSimilarlyQualifiedPointerType - In a pointer conversion from /// the pointer type FromPtr to a pointer to type ToPointee, with the /// same type qualifiers as FromPtr has on its pointee type. ToType, /// if non-empty, will be a pointer to ToType that may or may not have /// the right set of qualifiers on its pointee. /// static QualType BuildSimilarlyQualifiedPointerType(const Type *FromPtr, QualType ToPointee, QualType ToType, ASTContext &Context, bool StripObjCLifetime = false) { assert((FromPtr->getTypeClass() == Type::Pointer || FromPtr->getTypeClass() == Type::ObjCObjectPointer) && "Invalid similarly-qualified pointer type"); /// Conversions to 'id' subsume cv-qualifier conversions. if (ToType->isObjCIdType() || ToType->isObjCQualifiedIdType()) return ToType.getUnqualifiedType(); QualType CanonFromPointee = Context.getCanonicalType(FromPtr->getPointeeType()); QualType CanonToPointee = Context.getCanonicalType(ToPointee); Qualifiers Quals = CanonFromPointee.getQualifiers(); if (StripObjCLifetime) Quals.removeObjCLifetime(); // Exact qualifier match -> return the pointer type we're converting to. if (CanonToPointee.getLocalQualifiers() == Quals) { // ToType is exactly what we need. Return it. if (!ToType.isNull()) return ToType.getUnqualifiedType(); // Build a pointer to ToPointee. It has the right qualifiers // already. if (isa(ToType)) return Context.getObjCObjectPointerType(ToPointee); return Context.getPointerType(ToPointee); } // Just build a canonical type that has the right qualifiers. QualType QualifiedCanonToPointee = Context.getQualifiedType(CanonToPointee.getLocalUnqualifiedType(), Quals); if (isa(ToType)) return Context.getObjCObjectPointerType(QualifiedCanonToPointee); return Context.getPointerType(QualifiedCanonToPointee); } static bool isNullPointerConstantForConversion(Expr *Expr, bool InOverloadResolution, ASTContext &Context) { // Handle value-dependent integral null pointer constants correctly. // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903 if (Expr->isValueDependent() && !Expr->isTypeDependent() && Expr->getType()->isIntegerType() && !Expr->getType()->isEnumeralType()) return !InOverloadResolution; return Expr->isNullPointerConstant(Context, InOverloadResolution? Expr::NPC_ValueDependentIsNotNull : Expr::NPC_ValueDependentIsNull); } /// IsPointerConversion - Determines whether the conversion of the /// expression From, which has the (possibly adjusted) type FromType, /// can be converted to the type ToType via a pointer conversion (C++ /// 4.10). If so, returns true and places the converted type (that /// might differ from ToType in its cv-qualifiers at some level) into /// ConvertedType. /// /// This routine also supports conversions to and from block pointers /// and conversions with Objective-C's 'id', 'id', and /// pointers to interfaces. FIXME: Once we've determined the /// appropriate overloading rules for Objective-C, we may want to /// split the Objective-C checks into a different routine; however, /// GCC seems to consider all of these conversions to be pointer /// conversions, so for now they live here. IncompatibleObjC will be /// set if the conversion is an allowed Objective-C conversion that /// should result in a warning. bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType, bool InOverloadResolution, QualType& ConvertedType, bool &IncompatibleObjC) { IncompatibleObjC = false; if (isObjCPointerConversion(FromType, ToType, ConvertedType, IncompatibleObjC)) return true; // Conversion from a null pointer constant to any Objective-C pointer type. if (ToType->isObjCObjectPointerType() && isNullPointerConstantForConversion(From, InOverloadResolution, Context)) { ConvertedType = ToType; return true; } // Blocks: Block pointers can be converted to void*. if (FromType->isBlockPointerType() && ToType->isPointerType() && ToType->castAs()->getPointeeType()->isVoidType()) { ConvertedType = ToType; return true; } // Blocks: A null pointer constant can be converted to a block // pointer type. if (ToType->isBlockPointerType() && isNullPointerConstantForConversion(From, InOverloadResolution, Context)) { ConvertedType = ToType; return true; } // If the left-hand-side is nullptr_t, the right side can be a null // pointer constant. if (ToType->isNullPtrType() && isNullPointerConstantForConversion(From, InOverloadResolution, Context)) { ConvertedType = ToType; return true; } const PointerType* ToTypePtr = ToType->getAs(); if (!ToTypePtr) return false; // A null pointer constant can be converted to a pointer type (C++ 4.10p1). if (isNullPointerConstantForConversion(From, InOverloadResolution, Context)) { ConvertedType = ToType; return true; } // Beyond this point, both types need to be pointers // , including objective-c pointers. QualType ToPointeeType = ToTypePtr->getPointeeType(); if (FromType->isObjCObjectPointerType() && ToPointeeType->isVoidType() && !getLangOpts().ObjCAutoRefCount) { ConvertedType = BuildSimilarlyQualifiedPointerType( FromType->getAs(), ToPointeeType, ToType, Context); return true; } const PointerType *FromTypePtr = FromType->getAs(); if (!FromTypePtr) return false; QualType FromPointeeType = FromTypePtr->getPointeeType(); // If the unqualified pointee types are the same, this can't be a // pointer conversion, so don't do all of the work below. if (Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) return false; // An rvalue of type "pointer to cv T," where T is an object type, // can be converted to an rvalue of type "pointer to cv void" (C++ // 4.10p2). if (FromPointeeType->isIncompleteOrObjectType() && ToPointeeType->isVoidType()) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context, /*StripObjCLifetime=*/true); return true; } // MSVC allows implicit function to void* type conversion. if (getLangOpts().MSVCCompat && FromPointeeType->isFunctionType() && ToPointeeType->isVoidType()) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context); return true; } // When we're overloading in C, we allow a special kind of pointer // conversion for compatible-but-not-identical pointee types. if (!getLangOpts().CPlusPlus && Context.typesAreCompatible(FromPointeeType, ToPointeeType)) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context); return true; } // C++ [conv.ptr]p3: // // An rvalue of type "pointer to cv D," where D is a class type, // can be converted to an rvalue of type "pointer to cv B," where // B is a base class (clause 10) of D. If B is an inaccessible // (clause 11) or ambiguous (10.2) base class of D, a program that // necessitates this conversion is ill-formed. The result of the // conversion is a pointer to the base class sub-object of the // derived class object. The null pointer value is converted to // the null pointer value of the destination type. // // Note that we do not check for ambiguity or inaccessibility // here. That is handled by CheckPointerConversion. if (getLangOpts().CPlusPlus && FromPointeeType->isRecordType() && ToPointeeType->isRecordType() && !Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType) && IsDerivedFrom(From->getBeginLoc(), FromPointeeType, ToPointeeType)) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context); return true; } if (FromPointeeType->isVectorType() && ToPointeeType->isVectorType() && Context.areCompatibleVectorTypes(FromPointeeType, ToPointeeType)) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context); return true; } return false; } /// Adopt the given qualifiers for the given type. static QualType AdoptQualifiers(ASTContext &Context, QualType T, Qualifiers Qs){ Qualifiers TQs = T.getQualifiers(); // Check whether qualifiers already match. if (TQs == Qs) return T; if (Qs.compatiblyIncludes(TQs)) return Context.getQualifiedType(T, Qs); return Context.getQualifiedType(T.getUnqualifiedType(), Qs); } /// isObjCPointerConversion - Determines whether this is an /// Objective-C pointer conversion. Subroutine of IsPointerConversion, /// with the same arguments and return values. bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, QualType& ConvertedType, bool &IncompatibleObjC) { if (!getLangOpts().ObjC) return false; // The set of qualifiers on the type we're converting from. Qualifiers FromQualifiers = FromType.getQualifiers(); // First, we handle all conversions on ObjC object pointer types. const ObjCObjectPointerType* ToObjCPtr = ToType->getAs(); const ObjCObjectPointerType *FromObjCPtr = FromType->getAs(); if (ToObjCPtr && FromObjCPtr) { // If the pointee types are the same (ignoring qualifications), // then this is not a pointer conversion. if (Context.hasSameUnqualifiedType(ToObjCPtr->getPointeeType(), FromObjCPtr->getPointeeType())) return false; // Conversion between Objective-C pointers. if (Context.canAssignObjCInterfaces(ToObjCPtr, FromObjCPtr)) { const ObjCInterfaceType* LHS = ToObjCPtr->getInterfaceType(); const ObjCInterfaceType* RHS = FromObjCPtr->getInterfaceType(); if (getLangOpts().CPlusPlus && LHS && RHS && !ToObjCPtr->getPointeeType().isAtLeastAsQualifiedAs( FromObjCPtr->getPointeeType())) return false; ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr, ToObjCPtr->getPointeeType(), ToType, Context); ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers); return true; } if (Context.canAssignObjCInterfaces(FromObjCPtr, ToObjCPtr)) { // Okay: this is some kind of implicit downcast of Objective-C // interfaces, which is permitted. However, we're going to // complain about it. IncompatibleObjC = true; ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr, ToObjCPtr->getPointeeType(), ToType, Context); ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers); return true; } } // Beyond this point, both types need to be C pointers or block pointers. QualType ToPointeeType; if (const PointerType *ToCPtr = ToType->getAs()) ToPointeeType = ToCPtr->getPointeeType(); else if (const BlockPointerType *ToBlockPtr = ToType->getAs()) { // Objective C++: We're able to convert from a pointer to any object // to a block pointer type. if (FromObjCPtr && FromObjCPtr->isObjCBuiltinType()) { ConvertedType = AdoptQualifiers(Context, ToType, FromQualifiers); return true; } ToPointeeType = ToBlockPtr->getPointeeType(); } else if (FromType->getAs() && ToObjCPtr && ToObjCPtr->isObjCBuiltinType()) { // Objective C++: We're able to convert from a block pointer type to a // pointer to any object. ConvertedType = AdoptQualifiers(Context, ToType, FromQualifiers); return true; } else return false; QualType FromPointeeType; if (const PointerType *FromCPtr = FromType->getAs()) FromPointeeType = FromCPtr->getPointeeType(); else if (const BlockPointerType *FromBlockPtr = FromType->getAs()) FromPointeeType = FromBlockPtr->getPointeeType(); else return false; // If we have pointers to pointers, recursively check whether this // is an Objective-C conversion. if (FromPointeeType->isPointerType() && ToPointeeType->isPointerType() && isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType, IncompatibleObjC)) { // We always complain about this conversion. IncompatibleObjC = true; ConvertedType = Context.getPointerType(ConvertedType); ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers); return true; } // Allow conversion of pointee being objective-c pointer to another one; // as in I* to id. if (FromPointeeType->getAs() && ToPointeeType->getAs() && isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType, IncompatibleObjC)) { ConvertedType = Context.getPointerType(ConvertedType); ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers); return true; } // If we have pointers to functions or blocks, check whether the only // differences in the argument and result types are in Objective-C // pointer conversions. If so, we permit the conversion (but // complain about it). const FunctionProtoType *FromFunctionType = FromPointeeType->getAs(); const FunctionProtoType *ToFunctionType = ToPointeeType->getAs(); if (FromFunctionType && ToFunctionType) { // If the function types are exactly the same, this isn't an // Objective-C pointer conversion. if (Context.getCanonicalType(FromPointeeType) == Context.getCanonicalType(ToPointeeType)) return false; // Perform the quick checks that will tell us whether these // function types are obviously different. if (FromFunctionType->getNumParams() != ToFunctionType->getNumParams() || FromFunctionType->isVariadic() != ToFunctionType->isVariadic() || FromFunctionType->getMethodQuals() != ToFunctionType->getMethodQuals()) return false; bool HasObjCConversion = false; if (Context.getCanonicalType(FromFunctionType->getReturnType()) == Context.getCanonicalType(ToFunctionType->getReturnType())) { // Okay, the types match exactly. Nothing to do. } else if (isObjCPointerConversion(FromFunctionType->getReturnType(), ToFunctionType->getReturnType(), ConvertedType, IncompatibleObjC)) { // Okay, we have an Objective-C pointer conversion. HasObjCConversion = true; } else { // Function types are too different. Abort. return false; } // Check argument types. for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumParams(); ArgIdx != NumArgs; ++ArgIdx) { QualType FromArgType = FromFunctionType->getParamType(ArgIdx); QualType ToArgType = ToFunctionType->getParamType(ArgIdx); if (Context.getCanonicalType(FromArgType) == Context.getCanonicalType(ToArgType)) { // Okay, the types match exactly. Nothing to do. } else if (isObjCPointerConversion(FromArgType, ToArgType, ConvertedType, IncompatibleObjC)) { // Okay, we have an Objective-C pointer conversion. HasObjCConversion = true; } else { // Argument types are too different. Abort. return false; } } if (HasObjCConversion) { // We had an Objective-C conversion. Allow this pointer // conversion, but complain about it. ConvertedType = AdoptQualifiers(Context, ToType, FromQualifiers); IncompatibleObjC = true; return true; } } return false; } /// Determine whether this is an Objective-C writeback conversion, /// used for parameter passing when performing automatic reference counting. /// /// \param FromType The type we're converting form. /// /// \param ToType The type we're converting to. /// /// \param ConvertedType The type that will be produced after applying /// this conversion. bool Sema::isObjCWritebackConversion(QualType FromType, QualType ToType, QualType &ConvertedType) { if (!getLangOpts().ObjCAutoRefCount || Context.hasSameUnqualifiedType(FromType, ToType)) return false; // Parameter must be a pointer to __autoreleasing (with no other qualifiers). QualType ToPointee; if (const PointerType *ToPointer = ToType->getAs()) ToPointee = ToPointer->getPointeeType(); else return false; Qualifiers ToQuals = ToPointee.getQualifiers(); if (!ToPointee->isObjCLifetimeType() || ToQuals.getObjCLifetime() != Qualifiers::OCL_Autoreleasing || !ToQuals.withoutObjCLifetime().empty()) return false; // Argument must be a pointer to __strong to __weak. QualType FromPointee; if (const PointerType *FromPointer = FromType->getAs()) FromPointee = FromPointer->getPointeeType(); else return false; Qualifiers FromQuals = FromPointee.getQualifiers(); if (!FromPointee->isObjCLifetimeType() || (FromQuals.getObjCLifetime() != Qualifiers::OCL_Strong && FromQuals.getObjCLifetime() != Qualifiers::OCL_Weak)) return false; // Make sure that we have compatible qualifiers. FromQuals.setObjCLifetime(Qualifiers::OCL_Autoreleasing); if (!ToQuals.compatiblyIncludes(FromQuals)) return false; // Remove qualifiers from the pointee type we're converting from; they // aren't used in the compatibility check belong, and we'll be adding back // qualifiers (with __autoreleasing) if the compatibility check succeeds. FromPointee = FromPointee.getUnqualifiedType(); // The unqualified form of the pointee types must be compatible. ToPointee = ToPointee.getUnqualifiedType(); bool IncompatibleObjC; if (Context.typesAreCompatible(FromPointee, ToPointee)) FromPointee = ToPointee; else if (!isObjCPointerConversion(FromPointee, ToPointee, FromPointee, IncompatibleObjC)) return false; /// Construct the type we're converting to, which is a pointer to /// __autoreleasing pointee. FromPointee = Context.getQualifiedType(FromPointee, FromQuals); ConvertedType = Context.getPointerType(FromPointee); return true; } bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType, QualType& ConvertedType) { QualType ToPointeeType; if (const BlockPointerType *ToBlockPtr = ToType->getAs()) ToPointeeType = ToBlockPtr->getPointeeType(); else return false; QualType FromPointeeType; if (const BlockPointerType *FromBlockPtr = FromType->getAs()) FromPointeeType = FromBlockPtr->getPointeeType(); else return false; // We have pointer to blocks, check whether the only // differences in the argument and result types are in Objective-C // pointer conversions. If so, we permit the conversion. const FunctionProtoType *FromFunctionType = FromPointeeType->getAs(); const FunctionProtoType *ToFunctionType = ToPointeeType->getAs(); if (!FromFunctionType || !ToFunctionType) return false; if (Context.hasSameType(FromPointeeType, ToPointeeType)) return true; // Perform the quick checks that will tell us whether these // function types are obviously different. if (FromFunctionType->getNumParams() != ToFunctionType->getNumParams() || FromFunctionType->isVariadic() != ToFunctionType->isVariadic()) return false; FunctionType::ExtInfo FromEInfo = FromFunctionType->getExtInfo(); FunctionType::ExtInfo ToEInfo = ToFunctionType->getExtInfo(); if (FromEInfo != ToEInfo) return false; bool IncompatibleObjC = false; if (Context.hasSameType(FromFunctionType->getReturnType(), ToFunctionType->getReturnType())) { // Okay, the types match exactly. Nothing to do. } else { QualType RHS = FromFunctionType->getReturnType(); QualType LHS = ToFunctionType->getReturnType(); if ((!getLangOpts().CPlusPlus || !RHS->isRecordType()) && !RHS.hasQualifiers() && LHS.hasQualifiers()) LHS = LHS.getUnqualifiedType(); if (Context.hasSameType(RHS,LHS)) { // OK exact match. } else if (isObjCPointerConversion(RHS, LHS, ConvertedType, IncompatibleObjC)) { if (IncompatibleObjC) return false; // Okay, we have an Objective-C pointer conversion. } else return false; } // Check argument types. for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumParams(); ArgIdx != NumArgs; ++ArgIdx) { IncompatibleObjC = false; QualType FromArgType = FromFunctionType->getParamType(ArgIdx); QualType ToArgType = ToFunctionType->getParamType(ArgIdx); if (Context.hasSameType(FromArgType, ToArgType)) { // Okay, the types match exactly. Nothing to do. } else if (isObjCPointerConversion(ToArgType, FromArgType, ConvertedType, IncompatibleObjC)) { if (IncompatibleObjC) return false; // Okay, we have an Objective-C pointer conversion. } else // Argument types are too different. Abort. return false; } SmallVector NewParamInfos; bool CanUseToFPT, CanUseFromFPT; if (!Context.mergeExtParameterInfo(ToFunctionType, FromFunctionType, CanUseToFPT, CanUseFromFPT, NewParamInfos)) return false; ConvertedType = ToType; return true; } enum { ft_default, ft_different_class, ft_parameter_arity, ft_parameter_mismatch, ft_return_type, ft_qualifer_mismatch, ft_noexcept }; /// Attempts to get the FunctionProtoType from a Type. Handles /// MemberFunctionPointers properly. static const FunctionProtoType *tryGetFunctionProtoType(QualType FromType) { if (auto *FPT = FromType->getAs()) return FPT; if (auto *MPT = FromType->getAs()) return MPT->getPointeeType()->getAs(); return nullptr; } /// HandleFunctionTypeMismatch - Gives diagnostic information for differeing /// function types. Catches different number of parameter, mismatch in /// parameter types, and different return types. void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, QualType FromType, QualType ToType) { // If either type is not valid, include no extra info. if (FromType.isNull() || ToType.isNull()) { PDiag << ft_default; return; } // Get the function type from the pointers. if (FromType->isMemberPointerType() && ToType->isMemberPointerType()) { const auto *FromMember = FromType->castAs(), *ToMember = ToType->castAs(); if (!Context.hasSameType(FromMember->getClass(), ToMember->getClass())) { PDiag << ft_different_class << QualType(ToMember->getClass(), 0) << QualType(FromMember->getClass(), 0); return; } FromType = FromMember->getPointeeType(); ToType = ToMember->getPointeeType(); } if (FromType->isPointerType()) FromType = FromType->getPointeeType(); if (ToType->isPointerType()) ToType = ToType->getPointeeType(); // Remove references. FromType = FromType.getNonReferenceType(); ToType = ToType.getNonReferenceType(); // Don't print extra info for non-specialized template functions. if (FromType->isInstantiationDependentType() && !FromType->getAs()) { PDiag << ft_default; return; } // No extra info for same types. if (Context.hasSameType(FromType, ToType)) { PDiag << ft_default; return; } const FunctionProtoType *FromFunction = tryGetFunctionProtoType(FromType), *ToFunction = tryGetFunctionProtoType(ToType); // Both types need to be function types. if (!FromFunction || !ToFunction) { PDiag << ft_default; return; } if (FromFunction->getNumParams() != ToFunction->getNumParams()) { PDiag << ft_parameter_arity << ToFunction->getNumParams() << FromFunction->getNumParams(); return; } // Handle different parameter types. unsigned ArgPos; if (!FunctionParamTypesAreEqual(FromFunction, ToFunction, &ArgPos)) { PDiag << ft_parameter_mismatch << ArgPos + 1 << ToFunction->getParamType(ArgPos) << FromFunction->getParamType(ArgPos); return; } // Handle different return type. if (!Context.hasSameType(FromFunction->getReturnType(), ToFunction->getReturnType())) { PDiag << ft_return_type << ToFunction->getReturnType() << FromFunction->getReturnType(); return; } if (FromFunction->getMethodQuals() != ToFunction->getMethodQuals()) { PDiag << ft_qualifer_mismatch << ToFunction->getMethodQuals() << FromFunction->getMethodQuals(); return; } // Handle exception specification differences on canonical type (in C++17 // onwards). if (cast(FromFunction->getCanonicalTypeUnqualified()) ->isNothrow() != cast(ToFunction->getCanonicalTypeUnqualified()) ->isNothrow()) { PDiag << ft_noexcept; return; } // Unable to find a difference, so add no extra info. PDiag << ft_default; } /// FunctionParamTypesAreEqual - This routine checks two function proto types /// for equality of their argument types. Caller has already checked that /// they have same number of arguments. If the parameters are different, /// ArgPos will have the parameter index of the first different parameter. bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType, const FunctionProtoType *NewType, unsigned *ArgPos) { for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(), N = NewType->param_type_begin(), E = OldType->param_type_end(); O && (O != E); ++O, ++N) { // Ignore address spaces in pointee type. This is to disallow overloading // on __ptr32/__ptr64 address spaces. QualType Old = Context.removePtrSizeAddrSpace(O->getUnqualifiedType()); QualType New = Context.removePtrSizeAddrSpace(N->getUnqualifiedType()); if (!Context.hasSameType(Old, New)) { if (ArgPos) *ArgPos = O - OldType->param_type_begin(); return false; } } return true; } /// CheckPointerConversion - Check the pointer conversion from the /// expression From to the type ToType. This routine checks for /// ambiguous or inaccessible derived-to-base pointer /// conversions for which IsPointerConversion has already returned /// true. It returns true and produces a diagnostic if there was an /// error, or returns false otherwise. bool Sema::CheckPointerConversion(Expr *From, QualType ToType, CastKind &Kind, CXXCastPath& BasePath, bool IgnoreBaseAccess, bool Diagnose) { QualType FromType = From->getType(); bool IsCStyleOrFunctionalCast = IgnoreBaseAccess; Kind = CK_BitCast; if (Diagnose && !IsCStyleOrFunctionalCast && !FromType->isAnyPointerType() && From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) == Expr::NPCK_ZeroExpression) { if (Context.hasSameUnqualifiedType(From->getType(), Context.BoolTy)) DiagRuntimeBehavior(From->getExprLoc(), From, PDiag(diag::warn_impcast_bool_to_null_pointer) << ToType << From->getSourceRange()); else if (!isUnevaluatedContext()) Diag(From->getExprLoc(), diag::warn_non_literal_null_pointer) << ToType << From->getSourceRange(); } if (const PointerType *ToPtrType = ToType->getAs()) { if (const PointerType *FromPtrType = FromType->getAs()) { QualType FromPointeeType = FromPtrType->getPointeeType(), ToPointeeType = ToPtrType->getPointeeType(); if (FromPointeeType->isRecordType() && ToPointeeType->isRecordType() && !Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) { // We must have a derived-to-base conversion. Check an // ambiguous or inaccessible conversion. unsigned InaccessibleID = 0; unsigned AmbigiousID = 0; if (Diagnose) { InaccessibleID = diag::err_upcast_to_inaccessible_base; AmbigiousID = diag::err_ambiguous_derived_to_base_conv; } if (CheckDerivedToBaseConversion( FromPointeeType, ToPointeeType, InaccessibleID, AmbigiousID, From->getExprLoc(), From->getSourceRange(), DeclarationName(), &BasePath, IgnoreBaseAccess)) return true; // The conversion was successful. Kind = CK_DerivedToBase; } if (Diagnose && !IsCStyleOrFunctionalCast && FromPointeeType->isFunctionType() && ToPointeeType->isVoidType()) { assert(getLangOpts().MSVCCompat && "this should only be possible with MSVCCompat!"); Diag(From->getExprLoc(), diag::ext_ms_impcast_fn_obj) << From->getSourceRange(); } } } else if (const ObjCObjectPointerType *ToPtrType = ToType->getAs()) { if (const ObjCObjectPointerType *FromPtrType = FromType->getAs()) { // Objective-C++ conversions are always okay. // FIXME: We should have a different class of conversions for the // Objective-C++ implicit conversions. if (FromPtrType->isObjCBuiltinType() || ToPtrType->isObjCBuiltinType()) return false; } else if (FromType->isBlockPointerType()) { Kind = CK_BlockPointerToObjCPointerCast; } else { Kind = CK_CPointerToObjCPointerCast; } } else if (ToType->isBlockPointerType()) { if (!FromType->isBlockPointerType()) Kind = CK_AnyPointerToBlockPointerCast; } // We shouldn't fall into this case unless it's valid for other // reasons. if (From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) Kind = CK_NullToPointer; return false; } /// IsMemberPointerConversion - Determines whether the conversion of the /// expression From, which has the (possibly adjusted) type FromType, can be /// converted to the type ToType via a member pointer conversion (C++ 4.11). /// If so, returns true and places the converted type (that might differ from /// ToType in its cv-qualifiers at some level) into ConvertedType. bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType, bool InOverloadResolution, QualType &ConvertedType) { const MemberPointerType *ToTypePtr = ToType->getAs(); if (!ToTypePtr) return false; // A null pointer constant can be converted to a member pointer (C++ 4.11p1) if (From->isNullPointerConstant(Context, InOverloadResolution? Expr::NPC_ValueDependentIsNotNull : Expr::NPC_ValueDependentIsNull)) { ConvertedType = ToType; return true; } // Otherwise, both types have to be member pointers. const MemberPointerType *FromTypePtr = FromType->getAs(); if (!FromTypePtr) return false; // A pointer to member of B can be converted to a pointer to member of D, // where D is derived from B (C++ 4.11p2). QualType FromClass(FromTypePtr->getClass(), 0); QualType ToClass(ToTypePtr->getClass(), 0); if (!Context.hasSameUnqualifiedType(FromClass, ToClass) && IsDerivedFrom(From->getBeginLoc(), ToClass, FromClass)) { ConvertedType = Context.getMemberPointerType(FromTypePtr->getPointeeType(), ToClass.getTypePtr()); return true; } return false; } /// CheckMemberPointerConversion - Check the member pointer conversion from the /// expression From to the type ToType. This routine checks for ambiguous or /// virtual or inaccessible base-to-derived member pointer conversions /// for which IsMemberPointerConversion has already returned true. It returns /// true and produces a diagnostic if there was an error, or returns false /// otherwise. bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType, CastKind &Kind, CXXCastPath &BasePath, bool IgnoreBaseAccess) { QualType FromType = From->getType(); const MemberPointerType *FromPtrType = FromType->getAs(); if (!FromPtrType) { // This must be a null pointer to member pointer conversion assert(From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull) && "Expr must be null pointer constant!"); Kind = CK_NullToMemberPointer; return false; } const MemberPointerType *ToPtrType = ToType->getAs(); assert(ToPtrType && "No member pointer cast has a target type " "that is not a member pointer."); QualType FromClass = QualType(FromPtrType->getClass(), 0); QualType ToClass = QualType(ToPtrType->getClass(), 0); // FIXME: What about dependent types? assert(FromClass->isRecordType() && "Pointer into non-class."); assert(ToClass->isRecordType() && "Pointer into non-class."); CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/true); bool DerivationOkay = IsDerivedFrom(From->getBeginLoc(), ToClass, FromClass, Paths); assert(DerivationOkay && "Should not have been called if derivation isn't OK."); (void)DerivationOkay; if (Paths.isAmbiguous(Context.getCanonicalType(FromClass). getUnqualifiedType())) { std::string PathDisplayStr = getAmbiguousPathsDisplayString(Paths); Diag(From->getExprLoc(), diag::err_ambiguous_memptr_conv) << 0 << FromClass << ToClass << PathDisplayStr << From->getSourceRange(); return true; } if (const RecordType *VBase = Paths.getDetectedVirtual()) { Diag(From->getExprLoc(), diag::err_memptr_conv_via_virtual) << FromClass << ToClass << QualType(VBase, 0) << From->getSourceRange(); return true; } if (!IgnoreBaseAccess) CheckBaseClassAccess(From->getExprLoc(), FromClass, ToClass, Paths.front(), diag::err_downcast_from_inaccessible_base); // Must be a base to derived member conversion. BuildBasePathArray(Paths, BasePath); Kind = CK_BaseToDerivedMemberPointer; return false; } /// Determine whether the lifetime conversion between the two given /// qualifiers sets is nontrivial. static bool isNonTrivialObjCLifetimeConversion(Qualifiers FromQuals, Qualifiers ToQuals) { // Converting anything to const __unsafe_unretained is trivial. if (ToQuals.hasConst() && ToQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone) return false; return true; } /// Perform a single iteration of the loop for checking if a qualification /// conversion is valid. /// /// Specifically, check whether any change between the qualifiers of \p /// FromType and \p ToType is permissible, given knowledge about whether every /// outer layer is const-qualified. static bool isQualificationConversionStep(QualType FromType, QualType ToType, bool CStyle, bool IsTopLevel, bool &PreviousToQualsIncludeConst, bool &ObjCLifetimeConversion) { Qualifiers FromQuals = FromType.getQualifiers(); Qualifiers ToQuals = ToType.getQualifiers(); // Ignore __unaligned qualifier if this type is void. if (ToType.getUnqualifiedType()->isVoidType()) FromQuals.removeUnaligned(); // Objective-C ARC: // Check Objective-C lifetime conversions. if (FromQuals.getObjCLifetime() != ToQuals.getObjCLifetime()) { if (ToQuals.compatiblyIncludesObjCLifetime(FromQuals)) { if (isNonTrivialObjCLifetimeConversion(FromQuals, ToQuals)) ObjCLifetimeConversion = true; FromQuals.removeObjCLifetime(); ToQuals.removeObjCLifetime(); } else { // Qualification conversions cannot cast between different // Objective-C lifetime qualifiers. return false; } } // Allow addition/removal of GC attributes but not changing GC attributes. if (FromQuals.getObjCGCAttr() != ToQuals.getObjCGCAttr() && (!FromQuals.hasObjCGCAttr() || !ToQuals.hasObjCGCAttr())) { FromQuals.removeObjCGCAttr(); ToQuals.removeObjCGCAttr(); } // -- for every j > 0, if const is in cv 1,j then const is in cv // 2,j, and similarly for volatile. if (!CStyle && !ToQuals.compatiblyIncludes(FromQuals)) return false; // If address spaces mismatch: // - in top level it is only valid to convert to addr space that is a // superset in all cases apart from C-style casts where we allow // conversions between overlapping address spaces. // - in non-top levels it is not a valid conversion. if (ToQuals.getAddressSpace() != FromQuals.getAddressSpace() && (!IsTopLevel || !(ToQuals.isAddressSpaceSupersetOf(FromQuals) || (CStyle && FromQuals.isAddressSpaceSupersetOf(ToQuals))))) return false; // -- if the cv 1,j and cv 2,j are different, then const is in // every cv for 0 < k < j. if (!CStyle && FromQuals.getCVRQualifiers() != ToQuals.getCVRQualifiers() && !PreviousToQualsIncludeConst) return false; // Keep track of whether all prior cv-qualifiers in the "to" type // include const. PreviousToQualsIncludeConst = PreviousToQualsIncludeConst && ToQuals.hasConst(); return true; } /// IsQualificationConversion - Determines whether the conversion from /// an rvalue of type FromType to ToType is a qualification conversion /// (C++ 4.4). /// /// \param ObjCLifetimeConversion Output parameter that will be set to indicate /// when the qualification conversion involves a change in the Objective-C /// object lifetime. bool Sema::IsQualificationConversion(QualType FromType, QualType ToType, bool CStyle, bool &ObjCLifetimeConversion) { FromType = Context.getCanonicalType(FromType); ToType = Context.getCanonicalType(ToType); ObjCLifetimeConversion = false; // If FromType and ToType are the same type, this is not a // qualification conversion. if (FromType.getUnqualifiedType() == ToType.getUnqualifiedType()) return false; // (C++ 4.4p4): // A conversion can add cv-qualifiers at levels other than the first // in multi-level pointers, subject to the following rules: [...] bool PreviousToQualsIncludeConst = true; bool UnwrappedAnyPointer = false; while (Context.UnwrapSimilarTypes(FromType, ToType)) { if (!isQualificationConversionStep( FromType, ToType, CStyle, !UnwrappedAnyPointer, PreviousToQualsIncludeConst, ObjCLifetimeConversion)) return false; UnwrappedAnyPointer = true; } // We are left with FromType and ToType being the pointee types // after unwrapping the original FromType and ToType the same number // of times. If we unwrapped any pointers, and if FromType and // ToType have the same unqualified type (since we checked // qualifiers above), then this is a qualification conversion. return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType); } /// - Determine whether this is a conversion from a scalar type to an /// atomic type. /// /// If successful, updates \c SCS's second and third steps in the conversion /// sequence to finish the conversion. static bool tryAtomicConversion(Sema &S, Expr *From, QualType ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle) { const AtomicType *ToAtomic = ToType->getAs(); if (!ToAtomic) return false; StandardConversionSequence InnerSCS; if (!IsStandardConversion(S, From, ToAtomic->getValueType(), InOverloadResolution, InnerSCS, CStyle, /*AllowObjCWritebackConversion=*/false)) return false; SCS.Second = InnerSCS.Second; SCS.setToType(1, InnerSCS.getToType(1)); SCS.Third = InnerSCS.Third; SCS.QualificationIncludesObjCLifetime = InnerSCS.QualificationIncludesObjCLifetime; SCS.setToType(2, InnerSCS.getToType(2)); return true; } static bool isFirstArgumentCompatibleWithType(ASTContext &Context, CXXConstructorDecl *Constructor, QualType Type) { const auto *CtorType = Constructor->getType()->castAs(); if (CtorType->getNumParams() > 0) { QualType FirstArg = CtorType->getParamType(0); if (Context.hasSameUnqualifiedType(Type, FirstArg.getNonReferenceType())) return true; } return false; } static OverloadingResult IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType, CXXRecordDecl *To, UserDefinedConversionSequence &User, OverloadCandidateSet &CandidateSet, bool AllowExplicit) { CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion); for (auto *D : S.LookupConstructors(To)) { auto Info = getConstructorInfo(D); if (!Info) continue; bool Usable = !Info.Constructor->isInvalidDecl() && S.isInitListConstructor(Info.Constructor); if (Usable) { // If the first argument is (a reference to) the target type, // suppress conversions. bool SuppressUserConversions = isFirstArgumentCompatibleWithType( S.Context, Info.Constructor, ToType); if (Info.ConstructorTmpl) S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl, /*ExplicitArgs*/ nullptr, From, CandidateSet, SuppressUserConversions, /*PartialOverloading*/ false, AllowExplicit); else S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, From, CandidateSet, SuppressUserConversions, /*PartialOverloading*/ false, AllowExplicit); } } bool HadMultipleCandidates = (CandidateSet.size() > 1); OverloadCandidateSet::iterator Best; switch (auto Result = CandidateSet.BestViableFunction(S, From->getBeginLoc(), Best)) { case OR_Deleted: case OR_Success: { // Record the standard conversion we used and the conversion function. CXXConstructorDecl *Constructor = cast(Best->Function); QualType ThisType = Constructor->getThisType(); // Initializer lists don't have conversions as such. User.Before.setAsIdentityConversion(); User.HadMultipleCandidates = HadMultipleCandidates; User.ConversionFunction = Constructor; User.FoundConversionFunction = Best->FoundDecl; User.After.setAsIdentityConversion(); User.After.setFromType(ThisType->castAs()->getPointeeType()); User.After.setAllToTypes(ToType); return Result; } case OR_No_Viable_Function: return OR_No_Viable_Function; case OR_Ambiguous: return OR_Ambiguous; } llvm_unreachable("Invalid OverloadResult!"); } /// Determines whether there is a user-defined conversion sequence /// (C++ [over.ics.user]) that converts expression From to the type /// ToType. If such a conversion exists, User will contain the /// user-defined conversion sequence that performs such a conversion /// and this routine will return true. Otherwise, this routine returns /// false and User is unspecified. /// /// \param AllowExplicit true if the conversion should consider C++0x /// "explicit" conversion functions as well as non-explicit conversion /// functions (C++0x [class.conv.fct]p2). /// /// \param AllowObjCConversionOnExplicit true if the conversion should /// allow an extra Objective-C pointer conversion on uses of explicit /// constructors. Requires \c AllowExplicit to also be set. static OverloadingResult IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, UserDefinedConversionSequence &User, OverloadCandidateSet &CandidateSet, bool AllowExplicit, bool AllowObjCConversionOnExplicit) { assert(AllowExplicit || !AllowObjCConversionOnExplicit); CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion); // Whether we will only visit constructors. bool ConstructorsOnly = false; // If the type we are conversion to is a class type, enumerate its // constructors. if (const RecordType *ToRecordType = ToType->getAs()) { // C++ [over.match.ctor]p1: // When objects of class type are direct-initialized (8.5), or // copy-initialized from an expression of the same or a // derived class type (8.5), overload resolution selects the // constructor. [...] For copy-initialization, the candidate // functions are all the converting constructors (12.3.1) of // that class. The argument list is the expression-list within // the parentheses of the initializer. if (S.Context.hasSameUnqualifiedType(ToType, From->getType()) || (From->getType()->getAs() && S.IsDerivedFrom(From->getBeginLoc(), From->getType(), ToType))) ConstructorsOnly = true; if (!S.isCompleteType(From->getExprLoc(), ToType)) { // We're not going to find any constructors. } else if (CXXRecordDecl *ToRecordDecl = dyn_cast(ToRecordType->getDecl())) { Expr **Args = &From; unsigned NumArgs = 1; bool ListInitializing = false; if (InitListExpr *InitList = dyn_cast(From)) { // But first, see if there is an init-list-constructor that will work. OverloadingResult Result = IsInitializerListConstructorConversion( S, From, ToType, ToRecordDecl, User, CandidateSet, AllowExplicit); if (Result != OR_No_Viable_Function) return Result; // Never mind. CandidateSet.clear( OverloadCandidateSet::CSK_InitByUserDefinedConversion); // If we're list-initializing, we pass the individual elements as // arguments, not the entire list. Args = InitList->getInits(); NumArgs = InitList->getNumInits(); ListInitializing = true; } for (auto *D : S.LookupConstructors(ToRecordDecl)) { auto Info = getConstructorInfo(D); if (!Info) continue; bool Usable = !Info.Constructor->isInvalidDecl(); if (!ListInitializing) Usable = Usable && Info.Constructor->isConvertingConstructor( /*AllowExplicit*/ true); if (Usable) { bool SuppressUserConversions = !ConstructorsOnly; if (SuppressUserConversions && ListInitializing) { SuppressUserConversions = false; if (NumArgs == 1) { // If the first argument is (a reference to) the target type, // suppress conversions. SuppressUserConversions = isFirstArgumentCompatibleWithType( S.Context, Info.Constructor, ToType); } } if (Info.ConstructorTmpl) S.AddTemplateOverloadCandidate( Info.ConstructorTmpl, Info.FoundDecl, /*ExplicitArgs*/ nullptr, llvm::makeArrayRef(Args, NumArgs), CandidateSet, SuppressUserConversions, /*PartialOverloading*/ false, AllowExplicit); else // Allow one user-defined conversion when user specifies a // From->ToType conversion via an static cast (c-style, etc). S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, llvm::makeArrayRef(Args, NumArgs), CandidateSet, SuppressUserConversions, /*PartialOverloading*/ false, AllowExplicit); } } } } // Enumerate conversion functions, if we're allowed to. if (ConstructorsOnly || isa(From)) { } else if (!S.isCompleteType(From->getBeginLoc(), From->getType())) { // No conversion functions from incomplete types. } else if (const RecordType *FromRecordType = From->getType()->getAs()) { if (CXXRecordDecl *FromRecordDecl = dyn_cast(FromRecordType->getDecl())) { // Add all of the conversion functions as candidates. const auto &Conversions = FromRecordDecl->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { DeclAccessPair FoundDecl = I.getPair(); NamedDecl *D = FoundDecl.getDecl(); CXXRecordDecl *ActingContext = cast(D->getDeclContext()); if (isa(D)) D = cast(D)->getTargetDecl(); CXXConversionDecl *Conv; FunctionTemplateDecl *ConvTemplate; if ((ConvTemplate = dyn_cast(D))) Conv = cast(ConvTemplate->getTemplatedDecl()); else Conv = cast(D); if (ConvTemplate) S.AddTemplateConversionCandidate( ConvTemplate, FoundDecl, ActingContext, From, ToType, CandidateSet, AllowObjCConversionOnExplicit, AllowExplicit); else S.AddConversionCandidate( Conv, FoundDecl, ActingContext, From, ToType, CandidateSet, AllowObjCConversionOnExplicit, AllowExplicit); } } } bool HadMultipleCandidates = (CandidateSet.size() > 1); OverloadCandidateSet::iterator Best; switch (auto Result = CandidateSet.BestViableFunction(S, From->getBeginLoc(), Best)) { case OR_Success: case OR_Deleted: // Record the standard conversion we used and the conversion function. if (CXXConstructorDecl *Constructor = dyn_cast(Best->Function)) { // C++ [over.ics.user]p1: // If the user-defined conversion is specified by a // constructor (12.3.1), the initial standard conversion // sequence converts the source type to the type required by // the argument of the constructor. // QualType ThisType = Constructor->getThisType(); if (isa(From)) { // Initializer lists don't have conversions as such. User.Before.setAsIdentityConversion(); } else { if (Best->Conversions[0].isEllipsis()) User.EllipsisConversion = true; else { User.Before = Best->Conversions[0].Standard; User.EllipsisConversion = false; } } User.HadMultipleCandidates = HadMultipleCandidates; User.ConversionFunction = Constructor; User.FoundConversionFunction = Best->FoundDecl; User.After.setAsIdentityConversion(); User.After.setFromType(ThisType->castAs()->getPointeeType()); User.After.setAllToTypes(ToType); return Result; } if (CXXConversionDecl *Conversion = dyn_cast(Best->Function)) { // C++ [over.ics.user]p1: // // [...] If the user-defined conversion is specified by a // conversion function (12.3.2), the initial standard // conversion sequence converts the source type to the // implicit object parameter of the conversion function. User.Before = Best->Conversions[0].Standard; User.HadMultipleCandidates = HadMultipleCandidates; User.ConversionFunction = Conversion; User.FoundConversionFunction = Best->FoundDecl; User.EllipsisConversion = false; // C++ [over.ics.user]p2: // The second standard conversion sequence converts the // result of the user-defined conversion to the target type // for the sequence. Since an implicit conversion sequence // is an initialization, the special rules for // initialization by user-defined conversion apply when // selecting the best user-defined conversion for a // user-defined conversion sequence (see 13.3.3 and // 13.3.3.1). User.After = Best->FinalConversion; return Result; } llvm_unreachable("Not a constructor or conversion function?"); case OR_No_Viable_Function: return OR_No_Viable_Function; case OR_Ambiguous: return OR_Ambiguous; } llvm_unreachable("Invalid OverloadResult!"); } bool Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) { ImplicitConversionSequence ICS; OverloadCandidateSet CandidateSet(From->getExprLoc(), OverloadCandidateSet::CSK_Normal); OverloadingResult OvResult = IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined, CandidateSet, false, false); if (!(OvResult == OR_Ambiguous || (OvResult == OR_No_Viable_Function && !CandidateSet.empty()))) return false; auto Cands = CandidateSet.CompleteCandidates( *this, OvResult == OR_Ambiguous ? OCD_AmbiguousCandidates : OCD_AllCandidates, From); if (OvResult == OR_Ambiguous) Diag(From->getBeginLoc(), diag::err_typecheck_ambiguous_condition) << From->getType() << ToType << From->getSourceRange(); else { // OR_No_Viable_Function && !CandidateSet.empty() if (!RequireCompleteType(From->getBeginLoc(), ToType, diag::err_typecheck_nonviable_condition_incomplete, From->getType(), From->getSourceRange())) Diag(From->getBeginLoc(), diag::err_typecheck_nonviable_condition) << false << From->getType() << From->getSourceRange() << ToType; } CandidateSet.NoteCandidates( *this, From, Cands); return true; } /// Compare the user-defined conversion functions or constructors /// of two user-defined conversion sequences to determine whether any ordering /// is possible. static ImplicitConversionSequence::CompareKind compareConversionFunctions(Sema &S, FunctionDecl *Function1, FunctionDecl *Function2) { if (!S.getLangOpts().ObjC || !S.getLangOpts().CPlusPlus11) return ImplicitConversionSequence::Indistinguishable; // Objective-C++: // If both conversion functions are implicitly-declared conversions from // a lambda closure type to a function pointer and a block pointer, // respectively, always prefer the conversion to a function pointer, // because the function pointer is more lightweight and is more likely // to keep code working. CXXConversionDecl *Conv1 = dyn_cast_or_null(Function1); if (!Conv1) return ImplicitConversionSequence::Indistinguishable; CXXConversionDecl *Conv2 = dyn_cast(Function2); if (!Conv2) return ImplicitConversionSequence::Indistinguishable; if (Conv1->getParent()->isLambda() && Conv2->getParent()->isLambda()) { bool Block1 = Conv1->getConversionType()->isBlockPointerType(); bool Block2 = Conv2->getConversionType()->isBlockPointerType(); if (Block1 != Block2) return Block1 ? ImplicitConversionSequence::Worse : ImplicitConversionSequence::Better; } return ImplicitConversionSequence::Indistinguishable; } static bool hasDeprecatedStringLiteralToCharPtrConversion( const ImplicitConversionSequence &ICS) { return (ICS.isStandard() && ICS.Standard.DeprecatedStringLiteralToCharPtr) || (ICS.isUserDefined() && ICS.UserDefined.Before.DeprecatedStringLiteralToCharPtr); } /// CompareImplicitConversionSequences - Compare two implicit /// conversion sequences to determine whether one is better than the /// other or if they are indistinguishable (C++ 13.3.3.2). static ImplicitConversionSequence::CompareKind CompareImplicitConversionSequences(Sema &S, SourceLocation Loc, const ImplicitConversionSequence& ICS1, const ImplicitConversionSequence& ICS2) { // (C++ 13.3.3.2p2): When comparing the basic forms of implicit // conversion sequences (as defined in 13.3.3.1) // -- a standard conversion sequence (13.3.3.1.1) is a better // conversion sequence than a user-defined conversion sequence or // an ellipsis conversion sequence, and // -- a user-defined conversion sequence (13.3.3.1.2) is a better // conversion sequence than an ellipsis conversion sequence // (13.3.3.1.3). // // C++0x [over.best.ics]p10: // For the purpose of ranking implicit conversion sequences as // described in 13.3.3.2, the ambiguous conversion sequence is // treated as a user-defined sequence that is indistinguishable // from any other user-defined conversion sequence. // String literal to 'char *' conversion has been deprecated in C++03. It has // been removed from C++11. We still accept this conversion, if it happens at // the best viable function. Otherwise, this conversion is considered worse // than ellipsis conversion. Consider this as an extension; this is not in the // standard. For example: // // int &f(...); // #1 // void f(char*); // #2 // void g() { int &r = f("foo"); } // // In C++03, we pick #2 as the best viable function. // In C++11, we pick #1 as the best viable function, because ellipsis // conversion is better than string-literal to char* conversion (since there // is no such conversion in C++11). If there was no #1 at all or #1 couldn't // convert arguments, #2 would be the best viable function in C++11. // If the best viable function has this conversion, a warning will be issued // in C++03, or an ExtWarn (+SFINAE failure) will be issued in C++11. if (S.getLangOpts().CPlusPlus11 && !S.getLangOpts().WritableStrings && hasDeprecatedStringLiteralToCharPtrConversion(ICS1) != hasDeprecatedStringLiteralToCharPtrConversion(ICS2)) return hasDeprecatedStringLiteralToCharPtrConversion(ICS1) ? ImplicitConversionSequence::Worse : ImplicitConversionSequence::Better; if (ICS1.getKindRank() < ICS2.getKindRank()) return ImplicitConversionSequence::Better; if (ICS2.getKindRank() < ICS1.getKindRank()) return ImplicitConversionSequence::Worse; // The following checks require both conversion sequences to be of // the same kind. if (ICS1.getKind() != ICS2.getKind()) return ImplicitConversionSequence::Indistinguishable; ImplicitConversionSequence::CompareKind Result = ImplicitConversionSequence::Indistinguishable; // Two implicit conversion sequences of the same form are // indistinguishable conversion sequences unless one of the // following rules apply: (C++ 13.3.3.2p3): // List-initialization sequence L1 is a better conversion sequence than // list-initialization sequence L2 if: // - L1 converts to std::initializer_list for some X and L2 does not, or, // if not that, // - L1 converts to type "array of N1 T", L2 converts to type "array of N2 T", // and N1 is smaller than N2., // even if one of the other rules in this paragraph would otherwise apply. if (!ICS1.isBad()) { if (ICS1.isStdInitializerListElement() && !ICS2.isStdInitializerListElement()) return ImplicitConversionSequence::Better; if (!ICS1.isStdInitializerListElement() && ICS2.isStdInitializerListElement()) return ImplicitConversionSequence::Worse; } if (ICS1.isStandard()) // Standard conversion sequence S1 is a better conversion sequence than // standard conversion sequence S2 if [...] Result = CompareStandardConversionSequences(S, Loc, ICS1.Standard, ICS2.Standard); else if (ICS1.isUserDefined()) { // User-defined conversion sequence U1 is a better conversion // sequence than another user-defined conversion sequence U2 if // they contain the same user-defined conversion function or // constructor and if the second standard conversion sequence of // U1 is better than the second standard conversion sequence of // U2 (C++ 13.3.3.2p3). if (ICS1.UserDefined.ConversionFunction == ICS2.UserDefined.ConversionFunction) Result = CompareStandardConversionSequences(S, Loc, ICS1.UserDefined.After, ICS2.UserDefined.After); else Result = compareConversionFunctions(S, ICS1.UserDefined.ConversionFunction, ICS2.UserDefined.ConversionFunction); } return Result; } // Per 13.3.3.2p3, compare the given standard conversion sequences to // determine if one is a proper subset of the other. static ImplicitConversionSequence::CompareKind compareStandardConversionSubsets(ASTContext &Context, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { ImplicitConversionSequence::CompareKind Result = ImplicitConversionSequence::Indistinguishable; // the identity conversion sequence is considered to be a subsequence of // any non-identity conversion sequence if (SCS1.isIdentityConversion() && !SCS2.isIdentityConversion()) return ImplicitConversionSequence::Better; else if (!SCS1.isIdentityConversion() && SCS2.isIdentityConversion()) return ImplicitConversionSequence::Worse; if (SCS1.Second != SCS2.Second) { if (SCS1.Second == ICK_Identity) Result = ImplicitConversionSequence::Better; else if (SCS2.Second == ICK_Identity) Result = ImplicitConversionSequence::Worse; else return ImplicitConversionSequence::Indistinguishable; } else if (!Context.hasSimilarType(SCS1.getToType(1), SCS2.getToType(1))) return ImplicitConversionSequence::Indistinguishable; if (SCS1.Third == SCS2.Third) { return Context.hasSameType(SCS1.getToType(2), SCS2.getToType(2))? Result : ImplicitConversionSequence::Indistinguishable; } if (SCS1.Third == ICK_Identity) return Result == ImplicitConversionSequence::Worse ? ImplicitConversionSequence::Indistinguishable : ImplicitConversionSequence::Better; if (SCS2.Third == ICK_Identity) return Result == ImplicitConversionSequence::Better ? ImplicitConversionSequence::Indistinguishable : ImplicitConversionSequence::Worse; return ImplicitConversionSequence::Indistinguishable; } /// Determine whether one of the given reference bindings is better /// than the other based on what kind of bindings they are. static bool isBetterReferenceBindingKind(const StandardConversionSequence &SCS1, const StandardConversionSequence &SCS2) { // C++0x [over.ics.rank]p3b4: // -- S1 and S2 are reference bindings (8.5.3) and neither refers to an // implicit object parameter of a non-static member function declared // without a ref-qualifier, and *either* S1 binds an rvalue reference // to an rvalue and S2 binds an lvalue reference *or S1 binds an // lvalue reference to a function lvalue and S2 binds an rvalue // reference*. // // FIXME: Rvalue references. We're going rogue with the above edits, // because the semantics in the current C++0x working paper (N3225 at the // time of this writing) break the standard definition of std::forward // and std::reference_wrapper when dealing with references to functions. // Proposed wording changes submitted to CWG for consideration. if (SCS1.BindsImplicitObjectArgumentWithoutRefQualifier || SCS2.BindsImplicitObjectArgumentWithoutRefQualifier) return false; return (!SCS1.IsLvalueReference && SCS1.BindsToRvalue && SCS2.IsLvalueReference) || (SCS1.IsLvalueReference && SCS1.BindsToFunctionLvalue && !SCS2.IsLvalueReference && SCS2.BindsToFunctionLvalue); } enum class FixedEnumPromotion { None, ToUnderlyingType, ToPromotedUnderlyingType }; /// Returns kind of fixed enum promotion the \a SCS uses. static FixedEnumPromotion getFixedEnumPromtion(Sema &S, const StandardConversionSequence &SCS) { if (SCS.Second != ICK_Integral_Promotion) return FixedEnumPromotion::None; QualType FromType = SCS.getFromType(); if (!FromType->isEnumeralType()) return FixedEnumPromotion::None; EnumDecl *Enum = FromType->getAs()->getDecl(); if (!Enum->isFixed()) return FixedEnumPromotion::None; QualType UnderlyingType = Enum->getIntegerType(); if (S.Context.hasSameType(SCS.getToType(1), UnderlyingType)) return FixedEnumPromotion::ToUnderlyingType; return FixedEnumPromotion::ToPromotedUnderlyingType; } /// CompareStandardConversionSequences - Compare two standard /// conversion sequences to determine whether one is better than the /// other or if they are indistinguishable (C++ 13.3.3.2p3). static ImplicitConversionSequence::CompareKind CompareStandardConversionSequences(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { // Standard conversion sequence S1 is a better conversion sequence // than standard conversion sequence S2 if (C++ 13.3.3.2p3): // -- S1 is a proper subsequence of S2 (comparing the conversion // sequences in the canonical form defined by 13.3.3.1.1, // excluding any Lvalue Transformation; the identity conversion // sequence is considered to be a subsequence of any // non-identity conversion sequence) or, if not that, if (ImplicitConversionSequence::CompareKind CK = compareStandardConversionSubsets(S.Context, SCS1, SCS2)) return CK; // -- the rank of S1 is better than the rank of S2 (by the rules // defined below), or, if not that, ImplicitConversionRank Rank1 = SCS1.getRank(); ImplicitConversionRank Rank2 = SCS2.getRank(); if (Rank1 < Rank2) return ImplicitConversionSequence::Better; else if (Rank2 < Rank1) return ImplicitConversionSequence::Worse; // (C++ 13.3.3.2p4): Two conversion sequences with the same rank // are indistinguishable unless one of the following rules // applies: // A conversion that is not a conversion of a pointer, or // pointer to member, to bool is better than another conversion // that is such a conversion. if (SCS1.isPointerConversionToBool() != SCS2.isPointerConversionToBool()) return SCS2.isPointerConversionToBool() ? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; // C++14 [over.ics.rank]p4b2: // This is retroactively applied to C++11 by CWG 1601. // // A conversion that promotes an enumeration whose underlying type is fixed // to its underlying type is better than one that promotes to the promoted // underlying type, if the two are different. FixedEnumPromotion FEP1 = getFixedEnumPromtion(S, SCS1); FixedEnumPromotion FEP2 = getFixedEnumPromtion(S, SCS2); if (FEP1 != FixedEnumPromotion::None && FEP2 != FixedEnumPromotion::None && FEP1 != FEP2) return FEP1 == FixedEnumPromotion::ToUnderlyingType ? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; // C++ [over.ics.rank]p4b2: // // If class B is derived directly or indirectly from class A, // conversion of B* to A* is better than conversion of B* to // void*, and conversion of A* to void* is better than conversion // of B* to void*. bool SCS1ConvertsToVoid = SCS1.isPointerConversionToVoidPointer(S.Context); bool SCS2ConvertsToVoid = SCS2.isPointerConversionToVoidPointer(S.Context); if (SCS1ConvertsToVoid != SCS2ConvertsToVoid) { // Exactly one of the conversion sequences is a conversion to // a void pointer; it's the worse conversion. return SCS2ConvertsToVoid ? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; } else if (!SCS1ConvertsToVoid && !SCS2ConvertsToVoid) { // Neither conversion sequence converts to a void pointer; compare // their derived-to-base conversions. if (ImplicitConversionSequence::CompareKind DerivedCK = CompareDerivedToBaseConversions(S, Loc, SCS1, SCS2)) return DerivedCK; } else if (SCS1ConvertsToVoid && SCS2ConvertsToVoid && !S.Context.hasSameType(SCS1.getFromType(), SCS2.getFromType())) { // Both conversion sequences are conversions to void // pointers. Compare the source types to determine if there's an // inheritance relationship in their sources. QualType FromType1 = SCS1.getFromType(); QualType FromType2 = SCS2.getFromType(); // Adjust the types we're converting from via the array-to-pointer // conversion, if we need to. if (SCS1.First == ICK_Array_To_Pointer) FromType1 = S.Context.getArrayDecayedType(FromType1); if (SCS2.First == ICK_Array_To_Pointer) FromType2 = S.Context.getArrayDecayedType(FromType2); QualType FromPointee1 = FromType1->getPointeeType().getUnqualifiedType(); QualType FromPointee2 = FromType2->getPointeeType().getUnqualifiedType(); if (S.IsDerivedFrom(Loc, FromPointee2, FromPointee1)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, FromPointee1, FromPointee2)) return ImplicitConversionSequence::Worse; // Objective-C++: If one interface is more specific than the // other, it is the better one. const ObjCObjectPointerType* FromObjCPtr1 = FromType1->getAs(); const ObjCObjectPointerType* FromObjCPtr2 = FromType2->getAs(); if (FromObjCPtr1 && FromObjCPtr2) { bool AssignLeft = S.Context.canAssignObjCInterfaces(FromObjCPtr1, FromObjCPtr2); bool AssignRight = S.Context.canAssignObjCInterfaces(FromObjCPtr2, FromObjCPtr1); if (AssignLeft != AssignRight) { return AssignLeft? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; } } } if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) { // Check for a better reference binding based on the kind of bindings. if (isBetterReferenceBindingKind(SCS1, SCS2)) return ImplicitConversionSequence::Better; else if (isBetterReferenceBindingKind(SCS2, SCS1)) return ImplicitConversionSequence::Worse; } // Compare based on qualification conversions (C++ 13.3.3.2p3, // bullet 3). if (ImplicitConversionSequence::CompareKind QualCK = CompareQualificationConversions(S, SCS1, SCS2)) return QualCK; if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) { // C++ [over.ics.rank]p3b4: // -- S1 and S2 are reference bindings (8.5.3), and the types to // which the references refer are the same type except for // top-level cv-qualifiers, and the type to which the reference // initialized by S2 refers is more cv-qualified than the type // to which the reference initialized by S1 refers. QualType T1 = SCS1.getToType(2); QualType T2 = SCS2.getToType(2); T1 = S.Context.getCanonicalType(T1); T2 = S.Context.getCanonicalType(T2); Qualifiers T1Quals, T2Quals; QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals); QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals); if (UnqualT1 == UnqualT2) { // Objective-C++ ARC: If the references refer to objects with different // lifetimes, prefer bindings that don't change lifetime. if (SCS1.ObjCLifetimeConversionBinding != SCS2.ObjCLifetimeConversionBinding) { return SCS1.ObjCLifetimeConversionBinding ? ImplicitConversionSequence::Worse : ImplicitConversionSequence::Better; } // If the type is an array type, promote the element qualifiers to the // type for comparison. if (isa(T1) && T1Quals) T1 = S.Context.getQualifiedType(UnqualT1, T1Quals); if (isa(T2) && T2Quals) T2 = S.Context.getQualifiedType(UnqualT2, T2Quals); if (T2.isMoreQualifiedThan(T1)) return ImplicitConversionSequence::Better; if (T1.isMoreQualifiedThan(T2)) return ImplicitConversionSequence::Worse; } } // In Microsoft mode, prefer an integral conversion to a // floating-to-integral conversion if the integral conversion // is between types of the same size. // For example: // void f(float); // void f(int); // int main { // long a; // f(a); // } // Here, MSVC will call f(int) instead of generating a compile error // as clang will do in standard mode. if (S.getLangOpts().MSVCCompat && SCS1.Second == ICK_Integral_Conversion && SCS2.Second == ICK_Floating_Integral && S.Context.getTypeSize(SCS1.getFromType()) == S.Context.getTypeSize(SCS1.getToType(2))) return ImplicitConversionSequence::Better; // Prefer a compatible vector conversion over a lax vector conversion // For example: // // typedef float __v4sf __attribute__((__vector_size__(16))); // void f(vector float); // void f(vector signed int); // int main() { // __v4sf a; // f(a); // } // Here, we'd like to choose f(vector float) and not // report an ambiguous call error if (SCS1.Second == ICK_Vector_Conversion && SCS2.Second == ICK_Vector_Conversion) { bool SCS1IsCompatibleVectorConversion = S.Context.areCompatibleVectorTypes( SCS1.getFromType(), SCS1.getToType(2)); bool SCS2IsCompatibleVectorConversion = S.Context.areCompatibleVectorTypes( SCS2.getFromType(), SCS2.getToType(2)); if (SCS1IsCompatibleVectorConversion != SCS2IsCompatibleVectorConversion) return SCS1IsCompatibleVectorConversion ? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; } return ImplicitConversionSequence::Indistinguishable; } /// CompareQualificationConversions - Compares two standard conversion /// sequences to determine whether they can be ranked based on their /// qualification conversions (C++ 13.3.3.2p3 bullet 3). static ImplicitConversionSequence::CompareKind CompareQualificationConversions(Sema &S, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { // C++ 13.3.3.2p3: // -- S1 and S2 differ only in their qualification conversion and // yield similar types T1 and T2 (C++ 4.4), respectively, and the // cv-qualification signature of type T1 is a proper subset of // the cv-qualification signature of type T2, and S1 is not the // deprecated string literal array-to-pointer conversion (4.2). if (SCS1.First != SCS2.First || SCS1.Second != SCS2.Second || SCS1.Third != SCS2.Third || SCS1.Third != ICK_Qualification) return ImplicitConversionSequence::Indistinguishable; // FIXME: the example in the standard doesn't use a qualification // conversion (!) QualType T1 = SCS1.getToType(2); QualType T2 = SCS2.getToType(2); T1 = S.Context.getCanonicalType(T1); T2 = S.Context.getCanonicalType(T2); assert(!T1->isReferenceType() && !T2->isReferenceType()); Qualifiers T1Quals, T2Quals; QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals); QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals); // If the types are the same, we won't learn anything by unwrapping // them. if (UnqualT1 == UnqualT2) return ImplicitConversionSequence::Indistinguishable; ImplicitConversionSequence::CompareKind Result = ImplicitConversionSequence::Indistinguishable; // Objective-C++ ARC: // Prefer qualification conversions not involving a change in lifetime // to qualification conversions that do not change lifetime. if (SCS1.QualificationIncludesObjCLifetime != SCS2.QualificationIncludesObjCLifetime) { Result = SCS1.QualificationIncludesObjCLifetime ? ImplicitConversionSequence::Worse : ImplicitConversionSequence::Better; } while (S.Context.UnwrapSimilarTypes(T1, T2)) { // Within each iteration of the loop, we check the qualifiers to // determine if this still looks like a qualification // conversion. Then, if all is well, we unwrap one more level of // pointers or pointers-to-members and do it all again // until there are no more pointers or pointers-to-members left // to unwrap. This essentially mimics what // IsQualificationConversion does, but here we're checking for a // strict subset of qualifiers. if (T1.getQualifiers().withoutObjCLifetime() == T2.getQualifiers().withoutObjCLifetime()) // The qualifiers are the same, so this doesn't tell us anything // about how the sequences rank. // ObjC ownership quals are omitted above as they interfere with // the ARC overload rule. ; else if (T2.isMoreQualifiedThan(T1)) { // T1 has fewer qualifiers, so it could be the better sequence. if (Result == ImplicitConversionSequence::Worse) // Neither has qualifiers that are a subset of the other's // qualifiers. return ImplicitConversionSequence::Indistinguishable; Result = ImplicitConversionSequence::Better; } else if (T1.isMoreQualifiedThan(T2)) { // T2 has fewer qualifiers, so it could be the better sequence. if (Result == ImplicitConversionSequence::Better) // Neither has qualifiers that are a subset of the other's // qualifiers. return ImplicitConversionSequence::Indistinguishable; Result = ImplicitConversionSequence::Worse; } else { // Qualifiers are disjoint. return ImplicitConversionSequence::Indistinguishable; } // If the types after this point are equivalent, we're done. if (S.Context.hasSameUnqualifiedType(T1, T2)) break; } // Check that the winning standard conversion sequence isn't using // the deprecated string literal array to pointer conversion. switch (Result) { case ImplicitConversionSequence::Better: if (SCS1.DeprecatedStringLiteralToCharPtr) Result = ImplicitConversionSequence::Indistinguishable; break; case ImplicitConversionSequence::Indistinguishable: break; case ImplicitConversionSequence::Worse: if (SCS2.DeprecatedStringLiteralToCharPtr) Result = ImplicitConversionSequence::Indistinguishable; break; } return Result; } /// CompareDerivedToBaseConversions - Compares two standard conversion /// sequences to determine whether they can be ranked based on their /// various kinds of derived-to-base conversions (C++ /// [over.ics.rank]p4b3). As part of these checks, we also look at /// conversions between Objective-C interface types. static ImplicitConversionSequence::CompareKind CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { QualType FromType1 = SCS1.getFromType(); QualType ToType1 = SCS1.getToType(1); QualType FromType2 = SCS2.getFromType(); QualType ToType2 = SCS2.getToType(1); // Adjust the types we're converting from via the array-to-pointer // conversion, if we need to. if (SCS1.First == ICK_Array_To_Pointer) FromType1 = S.Context.getArrayDecayedType(FromType1); if (SCS2.First == ICK_Array_To_Pointer) FromType2 = S.Context.getArrayDecayedType(FromType2); // Canonicalize all of the types. FromType1 = S.Context.getCanonicalType(FromType1); ToType1 = S.Context.getCanonicalType(ToType1); FromType2 = S.Context.getCanonicalType(FromType2); ToType2 = S.Context.getCanonicalType(ToType2); // C++ [over.ics.rank]p4b3: // // If class B is derived directly or indirectly from class A and // class C is derived directly or indirectly from B, // // Compare based on pointer conversions. if (SCS1.Second == ICK_Pointer_Conversion && SCS2.Second == ICK_Pointer_Conversion && /*FIXME: Remove if Objective-C id conversions get their own rank*/ FromType1->isPointerType() && FromType2->isPointerType() && ToType1->isPointerType() && ToType2->isPointerType()) { QualType FromPointee1 = FromType1->castAs()->getPointeeType().getUnqualifiedType(); QualType ToPointee1 = ToType1->castAs()->getPointeeType().getUnqualifiedType(); QualType FromPointee2 = FromType2->castAs()->getPointeeType().getUnqualifiedType(); QualType ToPointee2 = ToType2->castAs()->getPointeeType().getUnqualifiedType(); // -- conversion of C* to B* is better than conversion of C* to A*, if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) { if (S.IsDerivedFrom(Loc, ToPointee1, ToPointee2)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, ToPointee2, ToPointee1)) return ImplicitConversionSequence::Worse; } // -- conversion of B* to A* is better than conversion of C* to A*, if (FromPointee1 != FromPointee2 && ToPointee1 == ToPointee2) { if (S.IsDerivedFrom(Loc, FromPointee2, FromPointee1)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, FromPointee1, FromPointee2)) return ImplicitConversionSequence::Worse; } } else if (SCS1.Second == ICK_Pointer_Conversion && SCS2.Second == ICK_Pointer_Conversion) { const ObjCObjectPointerType *FromPtr1 = FromType1->getAs(); const ObjCObjectPointerType *FromPtr2 = FromType2->getAs(); const ObjCObjectPointerType *ToPtr1 = ToType1->getAs(); const ObjCObjectPointerType *ToPtr2 = ToType2->getAs(); if (FromPtr1 && FromPtr2 && ToPtr1 && ToPtr2) { // Apply the same conversion ranking rules for Objective-C pointer types // that we do for C++ pointers to class types. However, we employ the // Objective-C pseudo-subtyping relationship used for assignment of // Objective-C pointer types. bool FromAssignLeft = S.Context.canAssignObjCInterfaces(FromPtr1, FromPtr2); bool FromAssignRight = S.Context.canAssignObjCInterfaces(FromPtr2, FromPtr1); bool ToAssignLeft = S.Context.canAssignObjCInterfaces(ToPtr1, ToPtr2); bool ToAssignRight = S.Context.canAssignObjCInterfaces(ToPtr2, ToPtr1); // A conversion to an a non-id object pointer type or qualified 'id' // type is better than a conversion to 'id'. if (ToPtr1->isObjCIdType() && (ToPtr2->isObjCQualifiedIdType() || ToPtr2->getInterfaceDecl())) return ImplicitConversionSequence::Worse; if (ToPtr2->isObjCIdType() && (ToPtr1->isObjCQualifiedIdType() || ToPtr1->getInterfaceDecl())) return ImplicitConversionSequence::Better; // A conversion to a non-id object pointer type is better than a // conversion to a qualified 'id' type if (ToPtr1->isObjCQualifiedIdType() && ToPtr2->getInterfaceDecl()) return ImplicitConversionSequence::Worse; if (ToPtr2->isObjCQualifiedIdType() && ToPtr1->getInterfaceDecl()) return ImplicitConversionSequence::Better; // A conversion to an a non-Class object pointer type or qualified 'Class' // type is better than a conversion to 'Class'. if (ToPtr1->isObjCClassType() && (ToPtr2->isObjCQualifiedClassType() || ToPtr2->getInterfaceDecl())) return ImplicitConversionSequence::Worse; if (ToPtr2->isObjCClassType() && (ToPtr1->isObjCQualifiedClassType() || ToPtr1->getInterfaceDecl())) return ImplicitConversionSequence::Better; // A conversion to a non-Class object pointer type is better than a // conversion to a qualified 'Class' type. if (ToPtr1->isObjCQualifiedClassType() && ToPtr2->getInterfaceDecl()) return ImplicitConversionSequence::Worse; if (ToPtr2->isObjCQualifiedClassType() && ToPtr1->getInterfaceDecl()) return ImplicitConversionSequence::Better; // -- "conversion of C* to B* is better than conversion of C* to A*," if (S.Context.hasSameType(FromType1, FromType2) && !FromPtr1->isObjCIdType() && !FromPtr1->isObjCClassType() && (ToAssignLeft != ToAssignRight)) { if (FromPtr1->isSpecialized()) { // "conversion of B * to B * is better than conversion of B * to // C *. bool IsFirstSame = FromPtr1->getInterfaceDecl() == ToPtr1->getInterfaceDecl(); bool IsSecondSame = FromPtr1->getInterfaceDecl() == ToPtr2->getInterfaceDecl(); if (IsFirstSame) { if (!IsSecondSame) return ImplicitConversionSequence::Better; } else if (IsSecondSame) return ImplicitConversionSequence::Worse; } return ToAssignLeft? ImplicitConversionSequence::Worse : ImplicitConversionSequence::Better; } // -- "conversion of B* to A* is better than conversion of C* to A*," if (S.Context.hasSameUnqualifiedType(ToType1, ToType2) && (FromAssignLeft != FromAssignRight)) return FromAssignLeft? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; } } // Ranking of member-pointer types. if (SCS1.Second == ICK_Pointer_Member && SCS2.Second == ICK_Pointer_Member && FromType1->isMemberPointerType() && FromType2->isMemberPointerType() && ToType1->isMemberPointerType() && ToType2->isMemberPointerType()) { const auto *FromMemPointer1 = FromType1->castAs(); const auto *ToMemPointer1 = ToType1->castAs(); const auto *FromMemPointer2 = FromType2->castAs(); const auto *ToMemPointer2 = ToType2->castAs(); const Type *FromPointeeType1 = FromMemPointer1->getClass(); const Type *ToPointeeType1 = ToMemPointer1->getClass(); const Type *FromPointeeType2 = FromMemPointer2->getClass(); const Type *ToPointeeType2 = ToMemPointer2->getClass(); QualType FromPointee1 = QualType(FromPointeeType1, 0).getUnqualifiedType(); QualType ToPointee1 = QualType(ToPointeeType1, 0).getUnqualifiedType(); QualType FromPointee2 = QualType(FromPointeeType2, 0).getUnqualifiedType(); QualType ToPointee2 = QualType(ToPointeeType2, 0).getUnqualifiedType(); // conversion of A::* to B::* is better than conversion of A::* to C::*, if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) { if (S.IsDerivedFrom(Loc, ToPointee1, ToPointee2)) return ImplicitConversionSequence::Worse; else if (S.IsDerivedFrom(Loc, ToPointee2, ToPointee1)) return ImplicitConversionSequence::Better; } // conversion of B::* to C::* is better than conversion of A::* to C::* if (ToPointee1 == ToPointee2 && FromPointee1 != FromPointee2) { if (S.IsDerivedFrom(Loc, FromPointee1, FromPointee2)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, FromPointee2, FromPointee1)) return ImplicitConversionSequence::Worse; } } if (SCS1.Second == ICK_Derived_To_Base) { // -- conversion of C to B is better than conversion of C to A, // -- binding of an expression of type C to a reference of type // B& is better than binding an expression of type C to a // reference of type A&, if (S.Context.hasSameUnqualifiedType(FromType1, FromType2) && !S.Context.hasSameUnqualifiedType(ToType1, ToType2)) { if (S.IsDerivedFrom(Loc, ToType1, ToType2)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, ToType2, ToType1)) return ImplicitConversionSequence::Worse; } // -- conversion of B to A is better than conversion of C to A. // -- binding of an expression of type B to a reference of type // A& is better than binding an expression of type C to a // reference of type A&, if (!S.Context.hasSameUnqualifiedType(FromType1, FromType2) && S.Context.hasSameUnqualifiedType(ToType1, ToType2)) { if (S.IsDerivedFrom(Loc, FromType2, FromType1)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, FromType1, FromType2)) return ImplicitConversionSequence::Worse; } } return ImplicitConversionSequence::Indistinguishable; } /// Determine whether the given type is valid, e.g., it is not an invalid /// C++ class. static bool isTypeValid(QualType T) { if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) return !Record->isInvalidDecl(); return true; } static QualType withoutUnaligned(ASTContext &Ctx, QualType T) { if (!T.getQualifiers().hasUnaligned()) return T; Qualifiers Q; T = Ctx.getUnqualifiedArrayType(T, Q); Q.removeUnaligned(); return Ctx.getQualifiedType(T, Q); } /// CompareReferenceRelationship - Compare the two types T1 and T2 to /// determine whether they are reference-compatible, /// reference-related, or incompatible, for use in C++ initialization by /// reference (C++ [dcl.ref.init]p4). Neither type can be a reference /// type, and the first type (T1) is the pointee type of the reference /// type being initialized. Sema::ReferenceCompareResult Sema::CompareReferenceRelationship(SourceLocation Loc, QualType OrigT1, QualType OrigT2, ReferenceConversions *ConvOut) { assert(!OrigT1->isReferenceType() && "T1 must be the pointee type of the reference type"); assert(!OrigT2->isReferenceType() && "T2 cannot be a reference type"); QualType T1 = Context.getCanonicalType(OrigT1); QualType T2 = Context.getCanonicalType(OrigT2); Qualifiers T1Quals, T2Quals; QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals); QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals); ReferenceConversions ConvTmp; ReferenceConversions &Conv = ConvOut ? *ConvOut : ConvTmp; Conv = ReferenceConversions(); // C++2a [dcl.init.ref]p4: // Given types "cv1 T1" and "cv2 T2," "cv1 T1" is // reference-related to "cv2 T2" if T1 is similar to T2, or // T1 is a base class of T2. // "cv1 T1" is reference-compatible with "cv2 T2" if // a prvalue of type "pointer to cv2 T2" can be converted to the type // "pointer to cv1 T1" via a standard conversion sequence. // Check for standard conversions we can apply to pointers: derived-to-base // conversions, ObjC pointer conversions, and function pointer conversions. // (Qualification conversions are checked last.) QualType ConvertedT2; if (UnqualT1 == UnqualT2) { // Nothing to do. } else if (isCompleteType(Loc, OrigT2) && isTypeValid(UnqualT1) && isTypeValid(UnqualT2) && IsDerivedFrom(Loc, UnqualT2, UnqualT1)) Conv |= ReferenceConversions::DerivedToBase; else if (UnqualT1->isObjCObjectOrInterfaceType() && UnqualT2->isObjCObjectOrInterfaceType() && Context.canBindObjCObjectType(UnqualT1, UnqualT2)) Conv |= ReferenceConversions::ObjC; else if (UnqualT2->isFunctionType() && IsFunctionConversion(UnqualT2, UnqualT1, ConvertedT2)) { Conv |= ReferenceConversions::Function; // No need to check qualifiers; function types don't have them. return Ref_Compatible; } bool ConvertedReferent = Conv != 0; // We can have a qualification conversion. Compute whether the types are // similar at the same time. bool PreviousToQualsIncludeConst = true; bool TopLevel = true; do { if (T1 == T2) break; // We will need a qualification conversion. Conv |= ReferenceConversions::Qualification; // Track whether we performed a qualification conversion anywhere other // than the top level. This matters for ranking reference bindings in // overload resolution. if (!TopLevel) Conv |= ReferenceConversions::NestedQualification; // MS compiler ignores __unaligned qualifier for references; do the same. T1 = withoutUnaligned(Context, T1); T2 = withoutUnaligned(Context, T2); // If we find a qualifier mismatch, the types are not reference-compatible, // but are still be reference-related if they're similar. bool ObjCLifetimeConversion = false; if (!isQualificationConversionStep(T2, T1, /*CStyle=*/false, TopLevel, PreviousToQualsIncludeConst, ObjCLifetimeConversion)) return (ConvertedReferent || Context.hasSimilarType(T1, T2)) ? Ref_Related : Ref_Incompatible; // FIXME: Should we track this for any level other than the first? if (ObjCLifetimeConversion) Conv |= ReferenceConversions::ObjCLifetime; TopLevel = false; } while (Context.UnwrapSimilarTypes(T1, T2)); // At this point, if the types are reference-related, we must either have the // same inner type (ignoring qualifiers), or must have already worked out how // to convert the referent. return (ConvertedReferent || Context.hasSameUnqualifiedType(T1, T2)) ? Ref_Compatible : Ref_Incompatible; } /// Look for a user-defined conversion to a value reference-compatible /// with DeclType. Return true if something definite is found. static bool FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS, QualType DeclType, SourceLocation DeclLoc, Expr *Init, QualType T2, bool AllowRvalues, bool AllowExplicit) { assert(T2->isRecordType() && "Can only find conversions of record types."); auto *T2RecordDecl = cast(T2->castAs()->getDecl()); OverloadCandidateSet CandidateSet( DeclLoc, OverloadCandidateSet::CSK_InitByUserDefinedConversion); const auto &Conversions = T2RecordDecl->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { NamedDecl *D = *I; CXXRecordDecl *ActingDC = cast(D->getDeclContext()); if (isa(D)) D = cast(D)->getTargetDecl(); FunctionTemplateDecl *ConvTemplate = dyn_cast(D); CXXConversionDecl *Conv; if (ConvTemplate) Conv = cast(ConvTemplate->getTemplatedDecl()); else Conv = cast(D); if (AllowRvalues) { // If we are initializing an rvalue reference, don't permit conversion // functions that return lvalues. if (!ConvTemplate && DeclType->isRValueReferenceType()) { const ReferenceType *RefType = Conv->getConversionType()->getAs(); if (RefType && !RefType->getPointeeType()->isFunctionType()) continue; } if (!ConvTemplate && S.CompareReferenceRelationship( DeclLoc, Conv->getConversionType() .getNonReferenceType() .getUnqualifiedType(), DeclType.getNonReferenceType().getUnqualifiedType()) == Sema::Ref_Incompatible) continue; } else { // If the conversion function doesn't return a reference type, // it can't be considered for this conversion. An rvalue reference // is only acceptable if its referencee is a function type. const ReferenceType *RefType = Conv->getConversionType()->getAs(); if (!RefType || (!RefType->isLValueReferenceType() && !RefType->getPointeeType()->isFunctionType())) continue; } if (ConvTemplate) S.AddTemplateConversionCandidate( ConvTemplate, I.getPair(), ActingDC, Init, DeclType, CandidateSet, /*AllowObjCConversionOnExplicit=*/false, AllowExplicit); else S.AddConversionCandidate( Conv, I.getPair(), ActingDC, Init, DeclType, CandidateSet, /*AllowObjCConversionOnExplicit=*/false, AllowExplicit); } bool HadMultipleCandidates = (CandidateSet.size() > 1); OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(S, DeclLoc, Best)) { case OR_Success: // C++ [over.ics.ref]p1: // // [...] If the parameter binds directly to the result of // applying a conversion function to the argument // expression, the implicit conversion sequence is a // user-defined conversion sequence (13.3.3.1.2), with the // second standard conversion sequence either an identity // conversion or, if the conversion function returns an // entity of a type that is a derived class of the parameter // type, a derived-to-base Conversion. if (!Best->FinalConversion.DirectBinding) return false; ICS.setUserDefined(); ICS.UserDefined.Before = Best->Conversions[0].Standard; ICS.UserDefined.After = Best->FinalConversion; ICS.UserDefined.HadMultipleCandidates = HadMultipleCandidates; ICS.UserDefined.ConversionFunction = Best->Function; ICS.UserDefined.FoundConversionFunction = Best->FoundDecl; ICS.UserDefined.EllipsisConversion = false; assert(ICS.UserDefined.After.ReferenceBinding && ICS.UserDefined.After.DirectBinding && "Expected a direct reference binding!"); return true; case OR_Ambiguous: ICS.setAmbiguous(); for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(); Cand != CandidateSet.end(); ++Cand) if (Cand->Best) ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function); return true; case OR_No_Viable_Function: case OR_Deleted: // There was no suitable conversion, or we found a deleted // conversion; continue with other checks. return false; } llvm_unreachable("Invalid OverloadResult!"); } /// Compute an implicit conversion sequence for reference /// initialization. static ImplicitConversionSequence TryReferenceInit(Sema &S, Expr *Init, QualType DeclType, SourceLocation DeclLoc, bool SuppressUserConversions, bool AllowExplicit) { assert(DeclType->isReferenceType() && "Reference init needs a reference"); // Most paths end in a failed conversion. ImplicitConversionSequence ICS; ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType); QualType T1 = DeclType->castAs()->getPointeeType(); QualType T2 = Init->getType(); // If the initializer is the address of an overloaded function, try // to resolve the overloaded function. If all goes well, T2 is the // type of the resulting function. if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) { DeclAccessPair Found; if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Init, DeclType, false, Found)) T2 = Fn->getType(); } // Compute some basic properties of the types and the initializer. bool isRValRef = DeclType->isRValueReferenceType(); Expr::Classification InitCategory = Init->Classify(S.Context); Sema::ReferenceConversions RefConv; Sema::ReferenceCompareResult RefRelationship = S.CompareReferenceRelationship(DeclLoc, T1, T2, &RefConv); auto SetAsReferenceBinding = [&](bool BindsDirectly) { ICS.setStandard(); ICS.Standard.First = ICK_Identity; // FIXME: A reference binding can be a function conversion too. We should // consider that when ordering reference-to-function bindings. ICS.Standard.Second = (RefConv & Sema::ReferenceConversions::DerivedToBase) ? ICK_Derived_To_Base : (RefConv & Sema::ReferenceConversions::ObjC) ? ICK_Compatible_Conversion : ICK_Identity; // FIXME: As a speculative fix to a defect introduced by CWG2352, we rank // a reference binding that performs a non-top-level qualification // conversion as a qualification conversion, not as an identity conversion. ICS.Standard.Third = (RefConv & Sema::ReferenceConversions::NestedQualification) ? ICK_Qualification : ICK_Identity; - ICS.Standard.FromTypePtr = T2.getAsOpaquePtr(); + ICS.Standard.setFromType(T2); ICS.Standard.setToType(0, T2); ICS.Standard.setToType(1, T1); ICS.Standard.setToType(2, T1); ICS.Standard.ReferenceBinding = true; ICS.Standard.DirectBinding = BindsDirectly; ICS.Standard.IsLvalueReference = !isRValRef; ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType(); ICS.Standard.BindsToRvalue = InitCategory.isRValue(); ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false; ICS.Standard.ObjCLifetimeConversionBinding = (RefConv & Sema::ReferenceConversions::ObjCLifetime) != 0; ICS.Standard.CopyConstructor = nullptr; ICS.Standard.DeprecatedStringLiteralToCharPtr = false; }; // C++0x [dcl.init.ref]p5: // A reference to type "cv1 T1" is initialized by an expression // of type "cv2 T2" as follows: // -- If reference is an lvalue reference and the initializer expression if (!isRValRef) { // -- is an lvalue (but is not a bit-field), and "cv1 T1" is // reference-compatible with "cv2 T2," or // // Per C++ [over.ics.ref]p4, we don't check the bit-field property here. if (InitCategory.isLValue() && RefRelationship == Sema::Ref_Compatible) { // C++ [over.ics.ref]p1: // When a parameter of reference type binds directly (8.5.3) // to an argument expression, the implicit conversion sequence // is the identity conversion, unless the argument expression // has a type that is a derived class of the parameter type, // in which case the implicit conversion sequence is a // derived-to-base Conversion (13.3.3.1). SetAsReferenceBinding(/*BindsDirectly=*/true); // Nothing more to do: the inaccessibility/ambiguity check for // derived-to-base conversions is suppressed when we're // computing the implicit conversion sequence (C++ // [over.best.ics]p2). return ICS; } // -- has a class type (i.e., T2 is a class type), where T1 is // not reference-related to T2, and can be implicitly // converted to an lvalue of type "cv3 T3," where "cv1 T1" // is reference-compatible with "cv3 T3" 92) (this // conversion is selected by enumerating the applicable // conversion functions (13.3.1.6) and choosing the best // one through overload resolution (13.3)), if (!SuppressUserConversions && T2->isRecordType() && S.isCompleteType(DeclLoc, T2) && RefRelationship == Sema::Ref_Incompatible) { if (FindConversionForRefInit(S, ICS, DeclType, DeclLoc, Init, T2, /*AllowRvalues=*/false, AllowExplicit)) return ICS; } } // -- Otherwise, the reference shall be an lvalue reference to a // non-volatile const type (i.e., cv1 shall be const), or the reference // shall be an rvalue reference. if (!isRValRef && (!T1.isConstQualified() || T1.isVolatileQualified())) return ICS; // -- If the initializer expression // // -- is an xvalue, class prvalue, array prvalue or function // lvalue and "cv1 T1" is reference-compatible with "cv2 T2", or if (RefRelationship == Sema::Ref_Compatible && (InitCategory.isXValue() || (InitCategory.isPRValue() && (T2->isRecordType() || T2->isArrayType())) || (InitCategory.isLValue() && T2->isFunctionType()))) { // In C++11, this is always a direct binding. In C++98/03, it's a direct // binding unless we're binding to a class prvalue. // Note: Although xvalues wouldn't normally show up in C++98/03 code, we // allow the use of rvalue references in C++98/03 for the benefit of // standard library implementors; therefore, we need the xvalue check here. SetAsReferenceBinding(/*BindsDirectly=*/S.getLangOpts().CPlusPlus11 || !(InitCategory.isPRValue() || T2->isRecordType())); return ICS; } // -- has a class type (i.e., T2 is a class type), where T1 is not // reference-related to T2, and can be implicitly converted to // an xvalue, class prvalue, or function lvalue of type // "cv3 T3", where "cv1 T1" is reference-compatible with // "cv3 T3", // // then the reference is bound to the value of the initializer // expression in the first case and to the result of the conversion // in the second case (or, in either case, to an appropriate base // class subobject). if (!SuppressUserConversions && RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() && S.isCompleteType(DeclLoc, T2) && FindConversionForRefInit(S, ICS, DeclType, DeclLoc, Init, T2, /*AllowRvalues=*/true, AllowExplicit)) { // In the second case, if the reference is an rvalue reference // and the second standard conversion sequence of the // user-defined conversion sequence includes an lvalue-to-rvalue // conversion, the program is ill-formed. if (ICS.isUserDefined() && isRValRef && ICS.UserDefined.After.First == ICK_Lvalue_To_Rvalue) ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType); return ICS; } // A temporary of function type cannot be created; don't even try. if (T1->isFunctionType()) return ICS; // -- Otherwise, a temporary of type "cv1 T1" is created and // initialized from the initializer expression using the // rules for a non-reference copy initialization (8.5). The // reference is then bound to the temporary. If T1 is // reference-related to T2, cv1 must be the same // cv-qualification as, or greater cv-qualification than, // cv2; otherwise, the program is ill-formed. if (RefRelationship == Sema::Ref_Related) { // If cv1 == cv2 or cv1 is a greater cv-qualified than cv2, then // we would be reference-compatible or reference-compatible with // added qualification. But that wasn't the case, so the reference // initialization fails. // // Note that we only want to check address spaces and cvr-qualifiers here. // ObjC GC, lifetime and unaligned qualifiers aren't important. Qualifiers T1Quals = T1.getQualifiers(); Qualifiers T2Quals = T2.getQualifiers(); T1Quals.removeObjCGCAttr(); T1Quals.removeObjCLifetime(); T2Quals.removeObjCGCAttr(); T2Quals.removeObjCLifetime(); // MS compiler ignores __unaligned qualifier for references; do the same. T1Quals.removeUnaligned(); T2Quals.removeUnaligned(); if (!T1Quals.compatiblyIncludes(T2Quals)) return ICS; } // If at least one of the types is a class type, the types are not // related, and we aren't allowed any user conversions, the // reference binding fails. This case is important for breaking // recursion, since TryImplicitConversion below will attempt to // create a temporary through the use of a copy constructor. if (SuppressUserConversions && RefRelationship == Sema::Ref_Incompatible && (T1->isRecordType() || T2->isRecordType())) return ICS; // If T1 is reference-related to T2 and the reference is an rvalue // reference, the initializer expression shall not be an lvalue. if (RefRelationship >= Sema::Ref_Related && isRValRef && Init->Classify(S.Context).isLValue()) return ICS; // C++ [over.ics.ref]p2: // When a parameter of reference type is not bound directly to // an argument expression, the conversion sequence is the one // required to convert the argument expression to the // underlying type of the reference according to // 13.3.3.1. Conceptually, this conversion sequence corresponds // to copy-initializing a temporary of the underlying type with // the argument expression. Any difference in top-level // cv-qualification is subsumed by the initialization itself // and does not constitute a conversion. ICS = TryImplicitConversion(S, Init, T1, SuppressUserConversions, /*AllowExplicit=*/false, /*InOverloadResolution=*/false, /*CStyle=*/false, /*AllowObjCWritebackConversion=*/false, /*AllowObjCConversionOnExplicit=*/false); // Of course, that's still a reference binding. if (ICS.isStandard()) { ICS.Standard.ReferenceBinding = true; ICS.Standard.IsLvalueReference = !isRValRef; ICS.Standard.BindsToFunctionLvalue = false; ICS.Standard.BindsToRvalue = true; ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false; ICS.Standard.ObjCLifetimeConversionBinding = false; } else if (ICS.isUserDefined()) { const ReferenceType *LValRefType = ICS.UserDefined.ConversionFunction->getReturnType() ->getAs(); // C++ [over.ics.ref]p3: // Except for an implicit object parameter, for which see 13.3.1, a // standard conversion sequence cannot be formed if it requires [...] // binding an rvalue reference to an lvalue other than a function // lvalue. // Note that the function case is not possible here. if (DeclType->isRValueReferenceType() && LValRefType) { // FIXME: This is the wrong BadConversionSequence. The problem is binding // an rvalue reference to a (non-function) lvalue, not binding an lvalue // reference to an rvalue! ICS.setBad(BadConversionSequence::lvalue_ref_to_rvalue, Init, DeclType); return ICS; } ICS.UserDefined.After.ReferenceBinding = true; ICS.UserDefined.After.IsLvalueReference = !isRValRef; ICS.UserDefined.After.BindsToFunctionLvalue = false; ICS.UserDefined.After.BindsToRvalue = !LValRefType; ICS.UserDefined.After.BindsImplicitObjectArgumentWithoutRefQualifier = false; ICS.UserDefined.After.ObjCLifetimeConversionBinding = false; } return ICS; } static ImplicitConversionSequence TryCopyInitialization(Sema &S, Expr *From, QualType ToType, bool SuppressUserConversions, bool InOverloadResolution, bool AllowObjCWritebackConversion, bool AllowExplicit = false); /// TryListConversion - Try to copy-initialize a value of type ToType from the /// initializer list From. static ImplicitConversionSequence TryListConversion(Sema &S, InitListExpr *From, QualType ToType, bool SuppressUserConversions, bool InOverloadResolution, bool AllowObjCWritebackConversion) { // C++11 [over.ics.list]p1: // When an argument is an initializer list, it is not an expression and // special rules apply for converting it to a parameter type. ImplicitConversionSequence Result; Result.setBad(BadConversionSequence::no_conversion, From, ToType); // We need a complete type for what follows. Incomplete types can never be // initialized from init lists. if (!S.isCompleteType(From->getBeginLoc(), ToType)) return Result; // Per DR1467: // If the parameter type is a class X and the initializer list has a single // element of type cv U, where U is X or a class derived from X, the // implicit conversion sequence is the one required to convert the element // to the parameter type. // // Otherwise, if the parameter type is a character array [... ] // and the initializer list has a single element that is an // appropriately-typed string literal (8.5.2 [dcl.init.string]), the // implicit conversion sequence is the identity conversion. if (From->getNumInits() == 1) { if (ToType->isRecordType()) { QualType InitType = From->getInit(0)->getType(); if (S.Context.hasSameUnqualifiedType(InitType, ToType) || S.IsDerivedFrom(From->getBeginLoc(), InitType, ToType)) return TryCopyInitialization(S, From->getInit(0), ToType, SuppressUserConversions, InOverloadResolution, AllowObjCWritebackConversion); } // FIXME: Check the other conditions here: array of character type, // initializer is a string literal. if (ToType->isArrayType()) { InitializedEntity Entity = InitializedEntity::InitializeParameter(S.Context, ToType, /*Consumed=*/false); if (S.CanPerformCopyInitialization(Entity, From)) { Result.setStandard(); Result.Standard.setAsIdentityConversion(); Result.Standard.setFromType(ToType); Result.Standard.setAllToTypes(ToType); return Result; } } } // C++14 [over.ics.list]p2: Otherwise, if the parameter type [...] (below). // C++11 [over.ics.list]p2: // If the parameter type is std::initializer_list or "array of X" and // all the elements can be implicitly converted to X, the implicit // conversion sequence is the worst conversion necessary to convert an // element of the list to X. // // C++14 [over.ics.list]p3: // Otherwise, if the parameter type is "array of N X", if the initializer // list has exactly N elements or if it has fewer than N elements and X is // default-constructible, and if all the elements of the initializer list // can be implicitly converted to X, the implicit conversion sequence is // the worst conversion necessary to convert an element of the list to X. // // FIXME: We're missing a lot of these checks. bool toStdInitializerList = false; QualType X; if (ToType->isArrayType()) X = S.Context.getAsArrayType(ToType)->getElementType(); else toStdInitializerList = S.isStdInitializerList(ToType, &X); if (!X.isNull()) { for (unsigned i = 0, e = From->getNumInits(); i < e; ++i) { Expr *Init = From->getInit(i); ImplicitConversionSequence ICS = TryCopyInitialization(S, Init, X, SuppressUserConversions, InOverloadResolution, AllowObjCWritebackConversion); // If a single element isn't convertible, fail. if (ICS.isBad()) { Result = ICS; break; } // Otherwise, look for the worst conversion. if (Result.isBad() || CompareImplicitConversionSequences( S, From->getBeginLoc(), ICS, Result) == ImplicitConversionSequence::Worse) Result = ICS; } // For an empty list, we won't have computed any conversion sequence. // Introduce the identity conversion sequence. if (From->getNumInits() == 0) { Result.setStandard(); Result.Standard.setAsIdentityConversion(); Result.Standard.setFromType(ToType); Result.Standard.setAllToTypes(ToType); } Result.setStdInitializerListElement(toStdInitializerList); return Result; } // C++14 [over.ics.list]p4: // C++11 [over.ics.list]p3: // Otherwise, if the parameter is a non-aggregate class X and overload // resolution chooses a single best constructor [...] the implicit // conversion sequence is a user-defined conversion sequence. If multiple // constructors are viable but none is better than the others, the // implicit conversion sequence is a user-defined conversion sequence. if (ToType->isRecordType() && !ToType->isAggregateType()) { // This function can deal with initializer lists. return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions, /*AllowExplicit=*/false, InOverloadResolution, /*CStyle=*/false, AllowObjCWritebackConversion, /*AllowObjCConversionOnExplicit=*/false); } // C++14 [over.ics.list]p5: // C++11 [over.ics.list]p4: // Otherwise, if the parameter has an aggregate type which can be // initialized from the initializer list [...] the implicit conversion // sequence is a user-defined conversion sequence. if (ToType->isAggregateType()) { // Type is an aggregate, argument is an init list. At this point it comes // down to checking whether the initialization works. // FIXME: Find out whether this parameter is consumed or not. InitializedEntity Entity = InitializedEntity::InitializeParameter(S.Context, ToType, /*Consumed=*/false); if (S.CanPerformAggregateInitializationForOverloadResolution(Entity, From)) { Result.setUserDefined(); Result.UserDefined.Before.setAsIdentityConversion(); // Initializer lists don't have a type. Result.UserDefined.Before.setFromType(QualType()); Result.UserDefined.Before.setAllToTypes(QualType()); Result.UserDefined.After.setAsIdentityConversion(); Result.UserDefined.After.setFromType(ToType); Result.UserDefined.After.setAllToTypes(ToType); Result.UserDefined.ConversionFunction = nullptr; } return Result; } // C++14 [over.ics.list]p6: // C++11 [over.ics.list]p5: // Otherwise, if the parameter is a reference, see 13.3.3.1.4. if (ToType->isReferenceType()) { // The standard is notoriously unclear here, since 13.3.3.1.4 doesn't // mention initializer lists in any way. So we go by what list- // initialization would do and try to extrapolate from that. QualType T1 = ToType->castAs()->getPointeeType(); // If the initializer list has a single element that is reference-related // to the parameter type, we initialize the reference from that. if (From->getNumInits() == 1) { Expr *Init = From->getInit(0); QualType T2 = Init->getType(); // If the initializer is the address of an overloaded function, try // to resolve the overloaded function. If all goes well, T2 is the // type of the resulting function. if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) { DeclAccessPair Found; if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction( Init, ToType, false, Found)) T2 = Fn->getType(); } // Compute some basic properties of the types and the initializer. Sema::ReferenceCompareResult RefRelationship = S.CompareReferenceRelationship(From->getBeginLoc(), T1, T2); if (RefRelationship >= Sema::Ref_Related) { return TryReferenceInit(S, Init, ToType, /*FIXME*/ From->getBeginLoc(), SuppressUserConversions, /*AllowExplicit=*/false); } } // Otherwise, we bind the reference to a temporary created from the // initializer list. Result = TryListConversion(S, From, T1, SuppressUserConversions, InOverloadResolution, AllowObjCWritebackConversion); if (Result.isFailure()) return Result; assert(!Result.isEllipsis() && "Sub-initialization cannot result in ellipsis conversion."); // Can we even bind to a temporary? if (ToType->isRValueReferenceType() || (T1.isConstQualified() && !T1.isVolatileQualified())) { StandardConversionSequence &SCS = Result.isStandard() ? Result.Standard : Result.UserDefined.After; SCS.ReferenceBinding = true; SCS.IsLvalueReference = ToType->isLValueReferenceType(); SCS.BindsToRvalue = true; SCS.BindsToFunctionLvalue = false; SCS.BindsImplicitObjectArgumentWithoutRefQualifier = false; SCS.ObjCLifetimeConversionBinding = false; } else Result.setBad(BadConversionSequence::lvalue_ref_to_rvalue, From, ToType); return Result; } // C++14 [over.ics.list]p7: // C++11 [over.ics.list]p6: // Otherwise, if the parameter type is not a class: if (!ToType->isRecordType()) { // - if the initializer list has one element that is not itself an // initializer list, the implicit conversion sequence is the one // required to convert the element to the parameter type. unsigned NumInits = From->getNumInits(); if (NumInits == 1 && !isa(From->getInit(0))) Result = TryCopyInitialization(S, From->getInit(0), ToType, SuppressUserConversions, InOverloadResolution, AllowObjCWritebackConversion); // - if the initializer list has no elements, the implicit conversion // sequence is the identity conversion. else if (NumInits == 0) { Result.setStandard(); Result.Standard.setAsIdentityConversion(); Result.Standard.setFromType(ToType); Result.Standard.setAllToTypes(ToType); } return Result; } // C++14 [over.ics.list]p8: // C++11 [over.ics.list]p7: // In all cases other than those enumerated above, no conversion is possible return Result; } /// TryCopyInitialization - Try to copy-initialize a value of type /// ToType from the expression From. Return the implicit conversion /// sequence required to pass this argument, which may be a bad /// conversion sequence (meaning that the argument cannot be passed to /// a parameter of this type). If @p SuppressUserConversions, then we /// do not permit any user-defined conversion sequences. static ImplicitConversionSequence TryCopyInitialization(Sema &S, Expr *From, QualType ToType, bool SuppressUserConversions, bool InOverloadResolution, bool AllowObjCWritebackConversion, bool AllowExplicit) { if (InitListExpr *FromInitList = dyn_cast(From)) return TryListConversion(S, FromInitList, ToType, SuppressUserConversions, InOverloadResolution,AllowObjCWritebackConversion); if (ToType->isReferenceType()) return TryReferenceInit(S, From, ToType, /*FIXME:*/ From->getBeginLoc(), SuppressUserConversions, AllowExplicit); return TryImplicitConversion(S, From, ToType, SuppressUserConversions, /*AllowExplicit=*/false, InOverloadResolution, /*CStyle=*/false, AllowObjCWritebackConversion, /*AllowObjCConversionOnExplicit=*/false); } static bool TryCopyInitialization(const CanQualType FromQTy, const CanQualType ToQTy, Sema &S, SourceLocation Loc, ExprValueKind FromVK) { OpaqueValueExpr TmpExpr(Loc, FromQTy, FromVK); ImplicitConversionSequence ICS = TryCopyInitialization(S, &TmpExpr, ToQTy, true, true, false); return !ICS.isBad(); } /// TryObjectArgumentInitialization - Try to initialize the object /// parameter of the given member function (@c Method) from the /// expression @p From. static ImplicitConversionSequence TryObjectArgumentInitialization(Sema &S, SourceLocation Loc, QualType FromType, Expr::Classification FromClassification, CXXMethodDecl *Method, CXXRecordDecl *ActingContext) { QualType ClassType = S.Context.getTypeDeclType(ActingContext); // [class.dtor]p2: A destructor can be invoked for a const, volatile or // const volatile object. Qualifiers Quals = Method->getMethodQualifiers(); if (isa(Method)) { Quals.addConst(); Quals.addVolatile(); } QualType ImplicitParamType = S.Context.getQualifiedType(ClassType, Quals); // Set up the conversion sequence as a "bad" conversion, to allow us // to exit early. ImplicitConversionSequence ICS; // We need to have an object of class type. if (const PointerType *PT = FromType->getAs()) { FromType = PT->getPointeeType(); // When we had a pointer, it's implicitly dereferenced, so we // better have an lvalue. assert(FromClassification.isLValue()); } assert(FromType->isRecordType()); // C++0x [over.match.funcs]p4: // For non-static member functions, the type of the implicit object // parameter is // // - "lvalue reference to cv X" for functions declared without a // ref-qualifier or with the & ref-qualifier // - "rvalue reference to cv X" for functions declared with the && // ref-qualifier // // where X is the class of which the function is a member and cv is the // cv-qualification on the member function declaration. // // However, when finding an implicit conversion sequence for the argument, we // are not allowed to perform user-defined conversions // (C++ [over.match.funcs]p5). We perform a simplified version of // reference binding here, that allows class rvalues to bind to // non-constant references. // First check the qualifiers. QualType FromTypeCanon = S.Context.getCanonicalType(FromType); if (ImplicitParamType.getCVRQualifiers() != FromTypeCanon.getLocalCVRQualifiers() && !ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon)) { ICS.setBad(BadConversionSequence::bad_qualifiers, FromType, ImplicitParamType); return ICS; } if (FromTypeCanon.hasAddressSpace()) { Qualifiers QualsImplicitParamType = ImplicitParamType.getQualifiers(); Qualifiers QualsFromType = FromTypeCanon.getQualifiers(); if (!QualsImplicitParamType.isAddressSpaceSupersetOf(QualsFromType)) { ICS.setBad(BadConversionSequence::bad_qualifiers, FromType, ImplicitParamType); return ICS; } } // Check that we have either the same type or a derived type. It // affects the conversion rank. QualType ClassTypeCanon = S.Context.getCanonicalType(ClassType); ImplicitConversionKind SecondKind; if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType()) { SecondKind = ICK_Identity; } else if (S.IsDerivedFrom(Loc, FromType, ClassType)) SecondKind = ICK_Derived_To_Base; else { ICS.setBad(BadConversionSequence::unrelated_class, FromType, ImplicitParamType); return ICS; } // Check the ref-qualifier. switch (Method->getRefQualifier()) { case RQ_None: // Do nothing; we don't care about lvalueness or rvalueness. break; case RQ_LValue: if (!FromClassification.isLValue() && !Quals.hasOnlyConst()) { // non-const lvalue reference cannot bind to an rvalue ICS.setBad(BadConversionSequence::lvalue_ref_to_rvalue, FromType, ImplicitParamType); return ICS; } break; case RQ_RValue: if (!FromClassification.isRValue()) { // rvalue reference cannot bind to an lvalue ICS.setBad(BadConversionSequence::rvalue_ref_to_lvalue, FromType, ImplicitParamType); return ICS; } break; } // Success. Mark this as a reference binding. ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); ICS.Standard.Second = SecondKind; ICS.Standard.setFromType(FromType); ICS.Standard.setAllToTypes(ImplicitParamType); ICS.Standard.ReferenceBinding = true; ICS.Standard.DirectBinding = true; ICS.Standard.IsLvalueReference = Method->getRefQualifier() != RQ_RValue; ICS.Standard.BindsToFunctionLvalue = false; ICS.Standard.BindsToRvalue = FromClassification.isRValue(); ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = (Method->getRefQualifier() == RQ_None); return ICS; } /// PerformObjectArgumentInitialization - Perform initialization of /// the implicit object parameter for the given Method with the given /// expression. ExprResult Sema::PerformObjectArgumentInitialization(Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl, CXXMethodDecl *Method) { QualType FromRecordType, DestType; QualType ImplicitParamRecordType = Method->getThisType()->castAs()->getPointeeType(); Expr::Classification FromClassification; if (const PointerType *PT = From->getType()->getAs()) { FromRecordType = PT->getPointeeType(); DestType = Method->getThisType(); FromClassification = Expr::Classification::makeSimpleLValue(); } else { FromRecordType = From->getType(); DestType = ImplicitParamRecordType; FromClassification = From->Classify(Context); // When performing member access on an rvalue, materialize a temporary. if (From->isRValue()) { From = CreateMaterializeTemporaryExpr(FromRecordType, From, Method->getRefQualifier() != RefQualifierKind::RQ_RValue); } } // Note that we always use the true parent context when performing // the actual argument initialization. ImplicitConversionSequence ICS = TryObjectArgumentInitialization( *this, From->getBeginLoc(), From->getType(), FromClassification, Method, Method->getParent()); if (ICS.isBad()) { switch (ICS.Bad.Kind) { case BadConversionSequence::bad_qualifiers: { Qualifiers FromQs = FromRecordType.getQualifiers(); Qualifiers ToQs = DestType.getQualifiers(); unsigned CVR = FromQs.getCVRQualifiers() & ~ToQs.getCVRQualifiers(); if (CVR) { Diag(From->getBeginLoc(), diag::err_member_function_call_bad_cvr) << Method->getDeclName() << FromRecordType << (CVR - 1) << From->getSourceRange(); Diag(Method->getLocation(), diag::note_previous_decl) << Method->getDeclName(); return ExprError(); } break; } case BadConversionSequence::lvalue_ref_to_rvalue: case BadConversionSequence::rvalue_ref_to_lvalue: { bool IsRValueQualified = Method->getRefQualifier() == RefQualifierKind::RQ_RValue; Diag(From->getBeginLoc(), diag::err_member_function_call_bad_ref) << Method->getDeclName() << FromClassification.isRValue() << IsRValueQualified; Diag(Method->getLocation(), diag::note_previous_decl) << Method->getDeclName(); return ExprError(); } case BadConversionSequence::no_conversion: case BadConversionSequence::unrelated_class: break; } return Diag(From->getBeginLoc(), diag::err_member_function_call_bad_type) << ImplicitParamRecordType << FromRecordType << From->getSourceRange(); } if (ICS.Standard.Second == ICK_Derived_To_Base) { ExprResult FromRes = PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method); if (FromRes.isInvalid()) return ExprError(); From = FromRes.get(); } if (!Context.hasSameType(From->getType(), DestType)) { CastKind CK; QualType PteeTy = DestType->getPointeeType(); LangAS DestAS = PteeTy.isNull() ? DestType.getAddressSpace() : PteeTy.getAddressSpace(); if (FromRecordType.getAddressSpace() != DestAS) CK = CK_AddressSpaceConversion; else CK = CK_NoOp; From = ImpCastExprToType(From, DestType, CK, From->getValueKind()).get(); } return From; } /// TryContextuallyConvertToBool - Attempt to contextually convert the /// expression From to bool (C++0x [conv]p3). static ImplicitConversionSequence TryContextuallyConvertToBool(Sema &S, Expr *From) { return TryImplicitConversion(S, From, S.Context.BoolTy, /*SuppressUserConversions=*/false, /*AllowExplicit=*/true, /*InOverloadResolution=*/false, /*CStyle=*/false, /*AllowObjCWritebackConversion=*/false, /*AllowObjCConversionOnExplicit=*/false); } /// PerformContextuallyConvertToBool - Perform a contextual conversion /// of the expression From to bool (C++0x [conv]p3). ExprResult Sema::PerformContextuallyConvertToBool(Expr *From) { if (checkPlaceholderForOverload(*this, From)) return ExprError(); ImplicitConversionSequence ICS = TryContextuallyConvertToBool(*this, From); if (!ICS.isBad()) return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting); if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy)) return Diag(From->getBeginLoc(), diag::err_typecheck_bool_condition) << From->getType() << From->getSourceRange(); return ExprError(); } /// Check that the specified conversion is permitted in a converted constant /// expression, according to C++11 [expr.const]p3. Return true if the conversion /// is acceptable. static bool CheckConvertedConstantConversions(Sema &S, StandardConversionSequence &SCS) { // Since we know that the target type is an integral or unscoped enumeration // type, most conversion kinds are impossible. All possible First and Third // conversions are fine. switch (SCS.Second) { case ICK_Identity: case ICK_Function_Conversion: case ICK_Integral_Promotion: case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere. case ICK_Zero_Queue_Conversion: return true; case ICK_Boolean_Conversion: // Conversion from an integral or unscoped enumeration type to bool is // classified as ICK_Boolean_Conversion, but it's also arguably an integral // conversion, so we allow it in a converted constant expression. // // FIXME: Per core issue 1407, we should not allow this, but that breaks // a lot of popular code. We should at least add a warning for this // (non-conforming) extension. return SCS.getFromType()->isIntegralOrUnscopedEnumerationType() && SCS.getToType(2)->isBooleanType(); case ICK_Pointer_Conversion: case ICK_Pointer_Member: // C++1z: null pointer conversions and null member pointer conversions are // only permitted if the source type is std::nullptr_t. return SCS.getFromType()->isNullPtrType(); case ICK_Floating_Promotion: case ICK_Complex_Promotion: case ICK_Floating_Conversion: case ICK_Complex_Conversion: case ICK_Floating_Integral: case ICK_Compatible_Conversion: case ICK_Derived_To_Base: case ICK_Vector_Conversion: case ICK_Vector_Splat: case ICK_Complex_Real: case ICK_Block_Pointer_Conversion: case ICK_TransparentUnionConversion: case ICK_Writeback_Conversion: case ICK_Zero_Event_Conversion: case ICK_C_Only_Conversion: case ICK_Incompatible_Pointer_Conversion: return false; case ICK_Lvalue_To_Rvalue: case ICK_Array_To_Pointer: case ICK_Function_To_Pointer: llvm_unreachable("found a first conversion kind in Second"); case ICK_Qualification: llvm_unreachable("found a third conversion kind in Second"); case ICK_Num_Conversion_Kinds: break; } llvm_unreachable("unknown conversion kind"); } /// CheckConvertedConstantExpression - Check that the expression From is a /// converted constant expression of type T, perform the conversion and produce /// the converted expression, per C++11 [expr.const]p3. static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, QualType T, APValue &Value, Sema::CCEKind CCE, bool RequireInt) { assert(S.getLangOpts().CPlusPlus11 && "converted constant expression outside C++11"); if (checkPlaceholderForOverload(S, From)) return ExprError(); // C++1z [expr.const]p3: // A converted constant expression of type T is an expression, // implicitly converted to type T, where the converted // expression is a constant expression and the implicit conversion // sequence contains only [... list of conversions ...]. // C++1z [stmt.if]p2: // If the if statement is of the form if constexpr, the value of the // condition shall be a contextually converted constant expression of type // bool. ImplicitConversionSequence ICS = CCE == Sema::CCEK_ConstexprIf || CCE == Sema::CCEK_ExplicitBool ? TryContextuallyConvertToBool(S, From) : TryCopyInitialization(S, From, T, /*SuppressUserConversions=*/false, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/false, /*AllowExplicit=*/false); StandardConversionSequence *SCS = nullptr; switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: SCS = &ICS.Standard; break; case ImplicitConversionSequence::UserDefinedConversion: // We are converting to a non-class type, so the Before sequence // must be trivial. SCS = &ICS.UserDefined.After; break; case ImplicitConversionSequence::AmbiguousConversion: case ImplicitConversionSequence::BadConversion: if (!S.DiagnoseMultipleUserDefinedConversion(From, T)) return S.Diag(From->getBeginLoc(), diag::err_typecheck_converted_constant_expression) << From->getType() << From->getSourceRange() << T; return ExprError(); case ImplicitConversionSequence::EllipsisConversion: llvm_unreachable("ellipsis conversion in converted constant expression"); } // Check that we would only use permitted conversions. if (!CheckConvertedConstantConversions(S, *SCS)) { return S.Diag(From->getBeginLoc(), diag::err_typecheck_converted_constant_expression_disallowed) << From->getType() << From->getSourceRange() << T; } // [...] and where the reference binding (if any) binds directly. if (SCS->ReferenceBinding && !SCS->DirectBinding) { return S.Diag(From->getBeginLoc(), diag::err_typecheck_converted_constant_expression_indirect) << From->getType() << From->getSourceRange() << T; } ExprResult Result = S.PerformImplicitConversion(From, T, ICS, Sema::AA_Converting); if (Result.isInvalid()) return Result; // C++2a [intro.execution]p5: // A full-expression is [...] a constant-expression [...] Result = S.ActOnFinishFullExpr(Result.get(), From->getExprLoc(), /*DiscardedValue=*/false, /*IsConstexpr=*/true); if (Result.isInvalid()) return Result; // Check for a narrowing implicit conversion. APValue PreNarrowingValue; QualType PreNarrowingType; switch (SCS->getNarrowingKind(S.Context, Result.get(), PreNarrowingValue, PreNarrowingType)) { case NK_Dependent_Narrowing: // Implicit conversion to a narrower type, but the expression is // value-dependent so we can't tell whether it's actually narrowing. case NK_Variable_Narrowing: // Implicit conversion to a narrower type, and the value is not a constant // expression. We'll diagnose this in a moment. case NK_Not_Narrowing: break; case NK_Constant_Narrowing: S.Diag(From->getBeginLoc(), diag::ext_cce_narrowing) << CCE << /*Constant*/ 1 << PreNarrowingValue.getAsString(S.Context, PreNarrowingType) << T; break; case NK_Type_Narrowing: S.Diag(From->getBeginLoc(), diag::ext_cce_narrowing) << CCE << /*Constant*/ 0 << From->getType() << T; break; } if (Result.get()->isValueDependent()) { Value = APValue(); return Result; } // Check the expression is a constant expression. SmallVector Notes; Expr::EvalResult Eval; Eval.Diag = &Notes; Expr::ConstExprUsage Usage = CCE == Sema::CCEK_TemplateArg ? Expr::EvaluateForMangling : Expr::EvaluateForCodeGen; if (!Result.get()->EvaluateAsConstantExpr(Eval, Usage, S.Context) || (RequireInt && !Eval.Val.isInt())) { // The expression can't be folded, so we can't keep it at this position in // the AST. Result = ExprError(); } else { Value = Eval.Val; if (Notes.empty()) { // It's a constant expression. return ConstantExpr::Create(S.Context, Result.get(), Value); } } // It's not a constant expression. Produce an appropriate diagnostic. if (Notes.size() == 1 && Notes[0].second.getDiagID() == diag::note_invalid_subexpr_in_const_expr) S.Diag(Notes[0].first, diag::err_expr_not_cce) << CCE; else { S.Diag(From->getBeginLoc(), diag::err_expr_not_cce) << CCE << From->getSourceRange(); for (unsigned I = 0; I < Notes.size(); ++I) S.Diag(Notes[I].first, Notes[I].second); } return ExprError(); } ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, APValue &Value, CCEKind CCE) { return ::CheckConvertedConstantExpression(*this, From, T, Value, CCE, false); } ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE) { assert(T->isIntegralOrEnumerationType() && "unexpected converted const type"); APValue V; auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true); if (!R.isInvalid() && !R.get()->isValueDependent()) Value = V.getInt(); return R; } /// dropPointerConversions - If the given standard conversion sequence /// involves any pointer conversions, remove them. This may change /// the result type of the conversion sequence. static void dropPointerConversion(StandardConversionSequence &SCS) { if (SCS.Second == ICK_Pointer_Conversion) { SCS.Second = ICK_Identity; SCS.Third = ICK_Identity; SCS.ToTypePtrs[2] = SCS.ToTypePtrs[1] = SCS.ToTypePtrs[0]; } } /// TryContextuallyConvertToObjCPointer - Attempt to contextually /// convert the expression From to an Objective-C pointer type. static ImplicitConversionSequence TryContextuallyConvertToObjCPointer(Sema &S, Expr *From) { // Do an implicit conversion to 'id'. QualType Ty = S.Context.getObjCIdType(); ImplicitConversionSequence ICS = TryImplicitConversion(S, From, Ty, // FIXME: Are these flags correct? /*SuppressUserConversions=*/false, /*AllowExplicit=*/true, /*InOverloadResolution=*/false, /*CStyle=*/false, /*AllowObjCWritebackConversion=*/false, /*AllowObjCConversionOnExplicit=*/true); // Strip off any final conversions to 'id'. switch (ICS.getKind()) { case ImplicitConversionSequence::BadConversion: case ImplicitConversionSequence::AmbiguousConversion: case ImplicitConversionSequence::EllipsisConversion: break; case ImplicitConversionSequence::UserDefinedConversion: dropPointerConversion(ICS.UserDefined.After); break; case ImplicitConversionSequence::StandardConversion: dropPointerConversion(ICS.Standard); break; } return ICS; } /// PerformContextuallyConvertToObjCPointer - Perform a contextual /// conversion of the expression From to an Objective-C pointer type. /// Returns a valid but null ExprResult if no conversion sequence exists. ExprResult Sema::PerformContextuallyConvertToObjCPointer(Expr *From) { if (checkPlaceholderForOverload(*this, From)) return ExprError(); QualType Ty = Context.getObjCIdType(); ImplicitConversionSequence ICS = TryContextuallyConvertToObjCPointer(*this, From); if (!ICS.isBad()) return PerformImplicitConversion(From, Ty, ICS, AA_Converting); return ExprResult(); } /// Determine whether the provided type is an integral type, or an enumeration /// type of a permitted flavor. bool Sema::ICEConvertDiagnoser::match(QualType T) { return AllowScopedEnumerations ? T->isIntegralOrEnumerationType() : T->isIntegralOrUnscopedEnumerationType(); } static ExprResult diagnoseAmbiguousConversion(Sema &SemaRef, SourceLocation Loc, Expr *From, Sema::ContextualImplicitConverter &Converter, QualType T, UnresolvedSetImpl &ViableConversions) { if (Converter.Suppress) return ExprError(); Converter.diagnoseAmbiguous(SemaRef, Loc, T) << From->getSourceRange(); for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) { CXXConversionDecl *Conv = cast(ViableConversions[I]->getUnderlyingDecl()); QualType ConvTy = Conv->getConversionType().getNonReferenceType(); Converter.noteAmbiguous(SemaRef, Conv, ConvTy); } return From; } static bool diagnoseNoViableConversion(Sema &SemaRef, SourceLocation Loc, Expr *&From, Sema::ContextualImplicitConverter &Converter, QualType T, bool HadMultipleCandidates, UnresolvedSetImpl &ExplicitConversions) { if (ExplicitConversions.size() == 1 && !Converter.Suppress) { DeclAccessPair Found = ExplicitConversions[0]; CXXConversionDecl *Conversion = cast(Found->getUnderlyingDecl()); // The user probably meant to invoke the given explicit // conversion; use it. QualType ConvTy = Conversion->getConversionType().getNonReferenceType(); std::string TypeStr; ConvTy.getAsStringInternal(TypeStr, SemaRef.getPrintingPolicy()); Converter.diagnoseExplicitConv(SemaRef, Loc, T, ConvTy) << FixItHint::CreateInsertion(From->getBeginLoc(), "static_cast<" + TypeStr + ">(") << FixItHint::CreateInsertion( SemaRef.getLocForEndOfToken(From->getEndLoc()), ")"); Converter.noteExplicitConv(SemaRef, Conversion, ConvTy); // If we aren't in a SFINAE context, build a call to the // explicit conversion function. if (SemaRef.isSFINAEContext()) return true; SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found); ExprResult Result = SemaRef.BuildCXXMemberCallExpr(From, Found, Conversion, HadMultipleCandidates); if (Result.isInvalid()) return true; // Record usage of conversion in an implicit cast. From = ImplicitCastExpr::Create(SemaRef.Context, Result.get()->getType(), CK_UserDefinedConversion, Result.get(), nullptr, Result.get()->getValueKind()); } return false; } static bool recordConversion(Sema &SemaRef, SourceLocation Loc, Expr *&From, Sema::ContextualImplicitConverter &Converter, QualType T, bool HadMultipleCandidates, DeclAccessPair &Found) { CXXConversionDecl *Conversion = cast(Found->getUnderlyingDecl()); SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found); QualType ToType = Conversion->getConversionType().getNonReferenceType(); if (!Converter.SuppressConversion) { if (SemaRef.isSFINAEContext()) return true; Converter.diagnoseConversion(SemaRef, Loc, T, ToType) << From->getSourceRange(); } ExprResult Result = SemaRef.BuildCXXMemberCallExpr(From, Found, Conversion, HadMultipleCandidates); if (Result.isInvalid()) return true; // Record usage of conversion in an implicit cast. From = ImplicitCastExpr::Create(SemaRef.Context, Result.get()->getType(), CK_UserDefinedConversion, Result.get(), nullptr, Result.get()->getValueKind()); return false; } static ExprResult finishContextualImplicitConversion( Sema &SemaRef, SourceLocation Loc, Expr *From, Sema::ContextualImplicitConverter &Converter) { if (!Converter.match(From->getType()) && !Converter.Suppress) Converter.diagnoseNoMatch(SemaRef, Loc, From->getType()) << From->getSourceRange(); return SemaRef.DefaultLvalueConversion(From); } static void collectViableConversionCandidates(Sema &SemaRef, Expr *From, QualType ToType, UnresolvedSetImpl &ViableConversions, OverloadCandidateSet &CandidateSet) { for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) { DeclAccessPair FoundDecl = ViableConversions[I]; NamedDecl *D = FoundDecl.getDecl(); CXXRecordDecl *ActingContext = cast(D->getDeclContext()); if (isa(D)) D = cast(D)->getTargetDecl(); CXXConversionDecl *Conv; FunctionTemplateDecl *ConvTemplate; if ((ConvTemplate = dyn_cast(D))) Conv = cast(ConvTemplate->getTemplatedDecl()); else Conv = cast(D); if (ConvTemplate) SemaRef.AddTemplateConversionCandidate( ConvTemplate, FoundDecl, ActingContext, From, ToType, CandidateSet, /*AllowObjCConversionOnExplicit=*/false, /*AllowExplicit*/ true); else SemaRef.AddConversionCandidate(Conv, FoundDecl, ActingContext, From, ToType, CandidateSet, /*AllowObjCConversionOnExplicit=*/false, /*AllowExplicit*/ true); } } /// Attempt to convert the given expression to a type which is accepted /// by the given converter. /// /// This routine will attempt to convert an expression of class type to a /// type accepted by the specified converter. In C++11 and before, the class /// must have a single non-explicit conversion function converting to a matching /// type. In C++1y, there can be multiple such conversion functions, but only /// one target type. /// /// \param Loc The source location of the construct that requires the /// conversion. /// /// \param From The expression we're converting from. /// /// \param Converter Used to control and diagnose the conversion process. /// /// \returns The expression, converted to an integral or enumeration type if /// successful. ExprResult Sema::PerformContextualImplicitConversion( SourceLocation Loc, Expr *From, ContextualImplicitConverter &Converter) { // We can't perform any more checking for type-dependent expressions. if (From->isTypeDependent()) return From; // Process placeholders immediately. if (From->hasPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(From); if (result.isInvalid()) return result; From = result.get(); } // If the expression already has a matching type, we're golden. QualType T = From->getType(); if (Converter.match(T)) return DefaultLvalueConversion(From); // FIXME: Check for missing '()' if T is a function type? // We can only perform contextual implicit conversions on objects of class // type. const RecordType *RecordTy = T->getAs(); if (!RecordTy || !getLangOpts().CPlusPlus) { if (!Converter.Suppress) Converter.diagnoseNoMatch(*this, Loc, T) << From->getSourceRange(); return From; } // We must have a complete class type. struct TypeDiagnoserPartialDiag : TypeDiagnoser { ContextualImplicitConverter &Converter; Expr *From; TypeDiagnoserPartialDiag(ContextualImplicitConverter &Converter, Expr *From) : Converter(Converter), From(From) {} void diagnose(Sema &S, SourceLocation Loc, QualType T) override { Converter.diagnoseIncomplete(S, Loc, T) << From->getSourceRange(); } } IncompleteDiagnoser(Converter, From); if (Converter.Suppress ? !isCompleteType(Loc, T) : RequireCompleteType(Loc, T, IncompleteDiagnoser)) return From; // Look for a conversion to an integral or enumeration type. UnresolvedSet<4> ViableConversions; // These are *potentially* viable in C++1y. UnresolvedSet<4> ExplicitConversions; const auto &Conversions = cast(RecordTy->getDecl())->getVisibleConversionFunctions(); bool HadMultipleCandidates = (std::distance(Conversions.begin(), Conversions.end()) > 1); // To check that there is only one target type, in C++1y: QualType ToType; bool HasUniqueTargetType = true; // Collect explicit or viable (potentially in C++1y) conversions. for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { NamedDecl *D = (*I)->getUnderlyingDecl(); CXXConversionDecl *Conversion; FunctionTemplateDecl *ConvTemplate = dyn_cast(D); if (ConvTemplate) { if (getLangOpts().CPlusPlus14) Conversion = cast(ConvTemplate->getTemplatedDecl()); else continue; // C++11 does not consider conversion operator templates(?). } else Conversion = cast(D); assert((!ConvTemplate || getLangOpts().CPlusPlus14) && "Conversion operator templates are considered potentially " "viable in C++1y"); QualType CurToType = Conversion->getConversionType().getNonReferenceType(); if (Converter.match(CurToType) || ConvTemplate) { if (Conversion->isExplicit()) { // FIXME: For C++1y, do we need this restriction? // cf. diagnoseNoViableConversion() if (!ConvTemplate) ExplicitConversions.addDecl(I.getDecl(), I.getAccess()); } else { if (!ConvTemplate && getLangOpts().CPlusPlus14) { if (ToType.isNull()) ToType = CurToType.getUnqualifiedType(); else if (HasUniqueTargetType && (CurToType.getUnqualifiedType() != ToType)) HasUniqueTargetType = false; } ViableConversions.addDecl(I.getDecl(), I.getAccess()); } } } if (getLangOpts().CPlusPlus14) { // C++1y [conv]p6: // ... An expression e of class type E appearing in such a context // is said to be contextually implicitly converted to a specified // type T and is well-formed if and only if e can be implicitly // converted to a type T that is determined as follows: E is searched // for conversion functions whose return type is cv T or reference to // cv T such that T is allowed by the context. There shall be // exactly one such T. // If no unique T is found: if (ToType.isNull()) { if (diagnoseNoViableConversion(*this, Loc, From, Converter, T, HadMultipleCandidates, ExplicitConversions)) return ExprError(); return finishContextualImplicitConversion(*this, Loc, From, Converter); } // If more than one unique Ts are found: if (!HasUniqueTargetType) return diagnoseAmbiguousConversion(*this, Loc, From, Converter, T, ViableConversions); // If one unique T is found: // First, build a candidate set from the previously recorded // potentially viable conversions. OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); collectViableConversionCandidates(*this, From, ToType, ViableConversions, CandidateSet); // Then, perform overload resolution over the candidate set. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, Loc, Best)) { case OR_Success: { // Apply this conversion. DeclAccessPair Found = DeclAccessPair::make(Best->Function, Best->FoundDecl.getAccess()); if (recordConversion(*this, Loc, From, Converter, T, HadMultipleCandidates, Found)) return ExprError(); break; } case OR_Ambiguous: return diagnoseAmbiguousConversion(*this, Loc, From, Converter, T, ViableConversions); case OR_No_Viable_Function: if (diagnoseNoViableConversion(*this, Loc, From, Converter, T, HadMultipleCandidates, ExplicitConversions)) return ExprError(); LLVM_FALLTHROUGH; case OR_Deleted: // We'll complain below about a non-integral condition type. break; } } else { switch (ViableConversions.size()) { case 0: { if (diagnoseNoViableConversion(*this, Loc, From, Converter, T, HadMultipleCandidates, ExplicitConversions)) return ExprError(); // We'll complain below about a non-integral condition type. break; } case 1: { // Apply this conversion. DeclAccessPair Found = ViableConversions[0]; if (recordConversion(*this, Loc, From, Converter, T, HadMultipleCandidates, Found)) return ExprError(); break; } default: return diagnoseAmbiguousConversion(*this, Loc, From, Converter, T, ViableConversions); } } return finishContextualImplicitConversion(*this, Loc, From, Converter); } /// IsAcceptableNonMemberOperatorCandidate - Determine whether Fn is /// an acceptable non-member overloaded operator for a call whose /// arguments have types T1 (and, if non-empty, T2). This routine /// implements the check in C++ [over.match.oper]p3b2 concerning /// enumeration types. static bool IsAcceptableNonMemberOperatorCandidate(ASTContext &Context, FunctionDecl *Fn, ArrayRef Args) { QualType T1 = Args[0]->getType(); QualType T2 = Args.size() > 1 ? Args[1]->getType() : QualType(); if (T1->isDependentType() || (!T2.isNull() && T2->isDependentType())) return true; if (T1->isRecordType() || (!T2.isNull() && T2->isRecordType())) return true; const auto *Proto = Fn->getType()->castAs(); if (Proto->getNumParams() < 1) return false; if (T1->isEnumeralType()) { QualType ArgType = Proto->getParamType(0).getNonReferenceType(); if (Context.hasSameUnqualifiedType(T1, ArgType)) return true; } if (Proto->getNumParams() < 2) return false; if (!T2.isNull() && T2->isEnumeralType()) { QualType ArgType = Proto->getParamType(1).getNonReferenceType(); if (Context.hasSameUnqualifiedType(T2, ArgType)) return true; } return false; } /// AddOverloadCandidate - Adds the given function to the set of /// candidate functions, using the given function call arguments. If /// @p SuppressUserConversions, then don't allow user-defined /// conversions via constructors or conversion operators. /// /// \param PartialOverloading true if we are performing "partial" overloading /// based on an incomplete set of function arguments. This feature is used by /// code completion. void Sema::AddOverloadCandidate( FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, bool AllowExplicit, bool AllowExplicitConversions, ADLCallKind IsADLCandidate, ConversionSequenceList EarlyConversions, OverloadCandidateParamOrder PO) { const FunctionProtoType *Proto = dyn_cast(Function->getType()->getAs()); assert(Proto && "Functions without a prototype cannot be overloaded"); assert(!Function->getDescribedFunctionTemplate() && "Use AddTemplateOverloadCandidate for function templates"); if (CXXMethodDecl *Method = dyn_cast(Function)) { if (!isa(Method)) { // If we get here, it's because we're calling a member function // that is named without a member access expression (e.g., // "this->f") that was either written explicitly or created // implicitly. This can happen with a qualified call to a member // function, e.g., X::f(). We use an empty type for the implied // object argument (C++ [over.call.func]p3), and the acting context // is irrelevant. AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(), Expr::Classification::makeSimpleLValue(), Args, CandidateSet, SuppressUserConversions, PartialOverloading, EarlyConversions, PO); return; } // We treat a constructor like a non-member function, since its object // argument doesn't participate in overload resolution. } if (!CandidateSet.isNewCandidate(Function, PO)) return; // C++11 [class.copy]p11: [DR1402] // A defaulted move constructor that is defined as deleted is ignored by // overload resolution. CXXConstructorDecl *Constructor = dyn_cast(Function); if (Constructor && Constructor->isDefaulted() && Constructor->isDeleted() && Constructor->isMoveConstructor()) return; // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); // C++ [over.match.oper]p3: // if no operand has a class type, only those non-member functions in the // lookup set that have a first parameter of type T1 or "reference to // (possibly cv-qualified) T1", when T1 is an enumeration type, or (if there // is a right operand) a second parameter of type T2 or "reference to // (possibly cv-qualified) T2", when T2 is an enumeration type, are // candidate functions. if (CandidateSet.getKind() == OverloadCandidateSet::CSK_Operator && !IsAcceptableNonMemberOperatorCandidate(Context, Function, Args)) return; // Add this candidate OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size(), EarlyConversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = Function; Candidate.Viable = true; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Function, PO); Candidate.IsSurrogate = false; Candidate.IsADLCandidate = IsADLCandidate; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = Args.size(); // Explicit functions are not actually candidates at all if we're not // allowing them in this context, but keep them around so we can point // to them in diagnostics. if (!AllowExplicit && ExplicitSpecifier::getFromDecl(Function).isExplicit()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_explicit; return; } if (Function->isMultiVersion() && Function->hasAttr() && !Function->getAttr()->isDefaultVersion()) { Candidate.Viable = false; Candidate.FailureKind = ovl_non_default_multiversion_function; return; } if (Constructor) { // C++ [class.copy]p3: // A member function template is never instantiated to perform the copy // of a class object to an object of its class type. QualType ClassType = Context.getTypeDeclType(Constructor->getParent()); if (Args.size() == 1 && Constructor->isSpecializationCopyingObject() && (Context.hasSameUnqualifiedType(ClassType, Args[0]->getType()) || IsDerivedFrom(Args[0]->getBeginLoc(), Args[0]->getType(), ClassType))) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_illegal_constructor; return; } // C++ [over.match.funcs]p8: (proposed DR resolution) // A constructor inherited from class type C that has a first parameter // of type "reference to P" (including such a constructor instantiated // from a template) is excluded from the set of candidate functions when // constructing an object of type cv D if the argument list has exactly // one argument and D is reference-related to P and P is reference-related // to C. auto *Shadow = dyn_cast(FoundDecl.getDecl()); if (Shadow && Args.size() == 1 && Constructor->getNumParams() >= 1 && Constructor->getParamDecl(0)->getType()->isReferenceType()) { QualType P = Constructor->getParamDecl(0)->getType()->getPointeeType(); QualType C = Context.getRecordType(Constructor->getParent()); QualType D = Context.getRecordType(Shadow->getParent()); SourceLocation Loc = Args.front()->getExprLoc(); if ((Context.hasSameUnqualifiedType(P, C) || IsDerivedFrom(Loc, P, C)) && (Context.hasSameUnqualifiedType(D, P) || IsDerivedFrom(Loc, D, P))) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_inhctor_slice; return; } } // Check that the constructor is capable of constructing an object in the // destination address space. if (!Qualifiers::isAddressSpaceSupersetOf( Constructor->getMethodQualifiers().getAddressSpace(), CandidateSet.getDestAS())) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_object_addrspace_mismatch; } } unsigned NumParams = Proto->getNumParams(); // (C++ 13.3.2p2): A candidate function having fewer than m // parameters is viable only if it has an ellipsis in its parameter // list (8.3.5). if (TooManyArguments(NumParams, Args.size(), PartialOverloading) && !Proto->isVariadic()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_many_arguments; return; } // (C++ 13.3.2p2): A candidate function having more than m parameters // is viable only if the (m+1)st parameter has a default argument // (8.3.6). For the purposes of overload resolution, the // parameter list is truncated on the right, so that there are // exactly m parameters. unsigned MinRequiredArgs = Function->getMinRequiredArguments(); if (Args.size() < MinRequiredArgs && !PartialOverloading) { // Not enough arguments. Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_few_arguments; return; } // (CUDA B.1): Check for invalid calls between targets. if (getLangOpts().CUDA) if (const FunctionDecl *Caller = dyn_cast(CurContext)) // Skip the check for callers that are implicit members, because in this // case we may not yet know what the member's target is; the target is // inferred for the member automatically, based on the bases and fields of // the class. if (!Caller->isImplicit() && !IsAllowedCUDACall(Caller, Function)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_target; return; } if (Function->getTrailingRequiresClause()) { ConstraintSatisfaction Satisfaction; if (CheckFunctionConstraints(Function, Satisfaction) || !Satisfaction.IsSatisfied) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_constraints_not_satisfied; return; } } // Determine the implicit conversion sequences for each of the // arguments. for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 1 - ArgIdx : ArgIdx; if (Candidate.Conversions[ConvIdx].isInitialized()) { // We already formed a conversion sequence for this parameter during // template argument deduction. } else if (ArgIdx < NumParams) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding // parameter of F. QualType ParamType = Proto->getParamType(ArgIdx); Candidate.Conversions[ConvIdx] = TryCopyInitialization( *this, Args[ArgIdx], ParamType, SuppressUserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, AllowExplicitConversions); if (Candidate.Conversions[ConvIdx].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; return; } } else { // (C++ 13.3.2p2): For the purposes of overload resolution, any // argument for which there is no corresponding parameter is // considered to ""match the ellipsis" (C+ 13.3.3.1.3). Candidate.Conversions[ConvIdx].setEllipsis(); } } if (EnableIfAttr *FailedAttr = CheckEnableIf(Function, Args)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; Candidate.DeductionFailure.Data = FailedAttr; return; } if (LangOpts.OpenCL && isOpenCLDisabledDecl(Function)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_ext_disabled; return; } } ObjCMethodDecl * Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance, SmallVectorImpl &Methods) { if (Methods.size() <= 1) return nullptr; for (unsigned b = 0, e = Methods.size(); b < e; b++) { bool Match = true; ObjCMethodDecl *Method = Methods[b]; unsigned NumNamedArgs = Sel.getNumArgs(); // Method might have more arguments than selector indicates. This is due // to addition of c-style arguments in method. if (Method->param_size() > NumNamedArgs) NumNamedArgs = Method->param_size(); if (Args.size() < NumNamedArgs) continue; for (unsigned i = 0; i < NumNamedArgs; i++) { // We can't do any type-checking on a type-dependent argument. if (Args[i]->isTypeDependent()) { Match = false; break; } ParmVarDecl *param = Method->parameters()[i]; Expr *argExpr = Args[i]; assert(argExpr && "SelectBestMethod(): missing expression"); // Strip the unbridged-cast placeholder expression off unless it's // a consumed argument. if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) && !param->hasAttr()) argExpr = stripARCUnbridgedCast(argExpr); // If the parameter is __unknown_anytype, move on to the next method. if (param->getType() == Context.UnknownAnyTy) { Match = false; break; } ImplicitConversionSequence ConversionState = TryCopyInitialization(*this, argExpr, param->getType(), /*SuppressUserConversions*/false, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, /*AllowExplicit*/false); // This function looks for a reasonably-exact match, so we consider // incompatible pointer conversions to be a failure here. if (ConversionState.isBad() || (ConversionState.isStandard() && ConversionState.Standard.Second == ICK_Incompatible_Pointer_Conversion)) { Match = false; break; } } // Promote additional arguments to variadic methods. if (Match && Method->isVariadic()) { for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) { if (Args[i]->isTypeDependent()) { Match = false; break; } ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, nullptr); if (Arg.isInvalid()) { Match = false; break; } } } else { // Check for extra arguments to non-variadic methods. if (Args.size() != NumNamedArgs) Match = false; else if (Match && NumNamedArgs == 0 && Methods.size() > 1) { // Special case when selectors have no argument. In this case, select // one with the most general result type of 'id'. for (unsigned b = 0, e = Methods.size(); b < e; b++) { QualType ReturnT = Methods[b]->getReturnType(); if (ReturnT->isObjCIdType()) return Methods[b]; } } } if (Match) return Method; } return nullptr; } static bool convertArgsForAvailabilityChecks(Sema &S, FunctionDecl *Function, Expr *ThisArg, ArrayRef Args, Sema::SFINAETrap &Trap, bool MissingImplicitThis, Expr *&ConvertedThis, SmallVectorImpl &ConvertedArgs) { if (ThisArg) { CXXMethodDecl *Method = cast(Function); assert(!isa(Method) && "Shouldn't have `this` for ctors!"); assert(!Method->isStatic() && "Shouldn't have `this` for static methods!"); ExprResult R = S.PerformObjectArgumentInitialization( ThisArg, /*Qualifier=*/nullptr, Method, Method); if (R.isInvalid()) return false; ConvertedThis = R.get(); } else { if (auto *MD = dyn_cast(Function)) { (void)MD; assert((MissingImplicitThis || MD->isStatic() || isa(MD)) && "Expected `this` for non-ctor instance methods"); } ConvertedThis = nullptr; } // Ignore any variadic arguments. Converting them is pointless, since the // user can't refer to them in the function condition. unsigned ArgSizeNoVarargs = std::min(Function->param_size(), Args.size()); // Convert the arguments. for (unsigned I = 0; I != ArgSizeNoVarargs; ++I) { ExprResult R; R = S.PerformCopyInitialization(InitializedEntity::InitializeParameter( S.Context, Function->getParamDecl(I)), SourceLocation(), Args[I]); if (R.isInvalid()) return false; ConvertedArgs.push_back(R.get()); } if (Trap.hasErrorOccurred()) return false; // Push default arguments if needed. if (!Function->isVariadic() && Args.size() < Function->getNumParams()) { for (unsigned i = Args.size(), e = Function->getNumParams(); i != e; ++i) { ParmVarDecl *P = Function->getParamDecl(i); Expr *DefArg = P->hasUninstantiatedDefaultArg() ? P->getUninstantiatedDefaultArg() : P->getDefaultArg(); // This can only happen in code completion, i.e. when PartialOverloading // is true. if (!DefArg) return false; ExprResult R = S.PerformCopyInitialization(InitializedEntity::InitializeParameter( S.Context, Function->getParamDecl(i)), SourceLocation(), DefArg); if (R.isInvalid()) return false; ConvertedArgs.push_back(R.get()); } if (Trap.hasErrorOccurred()) return false; } return true; } EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef Args, bool MissingImplicitThis) { auto EnableIfAttrs = Function->specific_attrs(); if (EnableIfAttrs.begin() == EnableIfAttrs.end()) return nullptr; SFINAETrap Trap(*this); SmallVector ConvertedArgs; // FIXME: We should look into making enable_if late-parsed. Expr *DiscardedThis; if (!convertArgsForAvailabilityChecks( *this, Function, /*ThisArg=*/nullptr, Args, Trap, /*MissingImplicitThis=*/true, DiscardedThis, ConvertedArgs)) return *EnableIfAttrs.begin(); for (auto *EIA : EnableIfAttrs) { APValue Result; // FIXME: This doesn't consider value-dependent cases, because doing so is // very difficult. Ideally, we should handle them more gracefully. if (EIA->getCond()->isValueDependent() || !EIA->getCond()->EvaluateWithSubstitution( Result, Context, Function, llvm::makeArrayRef(ConvertedArgs))) return EIA; if (!Result.isInt() || !Result.getInt().getBoolValue()) return EIA; } return nullptr; } template static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const NamedDecl *ND, bool ArgDependent, SourceLocation Loc, CheckFn &&IsSuccessful) { SmallVector Attrs; for (const auto *DIA : ND->specific_attrs()) { if (ArgDependent == DIA->getArgDependent()) Attrs.push_back(DIA); } // Common case: No diagnose_if attributes, so we can quit early. if (Attrs.empty()) return false; auto WarningBegin = std::stable_partition( Attrs.begin(), Attrs.end(), [](const DiagnoseIfAttr *DIA) { return DIA->isError(); }); // Note that diagnose_if attributes are late-parsed, so they appear in the // correct order (unlike enable_if attributes). auto ErrAttr = llvm::find_if(llvm::make_range(Attrs.begin(), WarningBegin), IsSuccessful); if (ErrAttr != WarningBegin) { const DiagnoseIfAttr *DIA = *ErrAttr; S.Diag(Loc, diag::err_diagnose_if_succeeded) << DIA->getMessage(); S.Diag(DIA->getLocation(), diag::note_from_diagnose_if) << DIA->getParent() << DIA->getCond()->getSourceRange(); return true; } for (const auto *DIA : llvm::make_range(WarningBegin, Attrs.end())) if (IsSuccessful(DIA)) { S.Diag(Loc, diag::warn_diagnose_if_succeeded) << DIA->getMessage(); S.Diag(DIA->getLocation(), diag::note_from_diagnose_if) << DIA->getParent() << DIA->getCond()->getSourceRange(); } return false; } bool Sema::diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef Args, SourceLocation Loc) { return diagnoseDiagnoseIfAttrsWith( *this, Function, /*ArgDependent=*/true, Loc, [&](const DiagnoseIfAttr *DIA) { APValue Result; // It's sane to use the same Args for any redecl of this function, since // EvaluateWithSubstitution only cares about the position of each // argument in the arg list, not the ParmVarDecl* it maps to. if (!DIA->getCond()->EvaluateWithSubstitution( Result, Context, cast(DIA->getParent()), Args, ThisArg)) return false; return Result.isInt() && Result.getInt().getBoolValue(); }); } bool Sema::diagnoseArgIndependentDiagnoseIfAttrs(const NamedDecl *ND, SourceLocation Loc) { return diagnoseDiagnoseIfAttrsWith( *this, ND, /*ArgDependent=*/false, Loc, [&](const DiagnoseIfAttr *DIA) { bool Result; return DIA->getCond()->EvaluateAsBooleanCondition(Result, Context) && Result; }); } /// Add all of the function declarations in the given function set to /// the overload candidate set. void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, ArrayRef Args, OverloadCandidateSet &CandidateSet, TemplateArgumentListInfo *ExplicitTemplateArgs, bool SuppressUserConversions, bool PartialOverloading, bool FirstArgumentIsBase) { for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { NamedDecl *D = F.getDecl()->getUnderlyingDecl(); ArrayRef FunctionArgs = Args; FunctionTemplateDecl *FunTmpl = dyn_cast(D); FunctionDecl *FD = FunTmpl ? FunTmpl->getTemplatedDecl() : cast(D); if (isa(FD) && !cast(FD)->isStatic()) { QualType ObjectType; Expr::Classification ObjectClassification; if (Args.size() > 0) { if (Expr *E = Args[0]) { // Use the explicit base to restrict the lookup: ObjectType = E->getType(); // Pointers in the object arguments are implicitly dereferenced, so we // always classify them as l-values. if (!ObjectType.isNull() && ObjectType->isPointerType()) ObjectClassification = Expr::Classification::makeSimpleLValue(); else ObjectClassification = E->Classify(Context); } // .. else there is an implicit base. FunctionArgs = Args.slice(1); } if (FunTmpl) { AddMethodTemplateCandidate( FunTmpl, F.getPair(), cast(FunTmpl->getDeclContext()), ExplicitTemplateArgs, ObjectType, ObjectClassification, FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } else { AddMethodCandidate(cast(FD), F.getPair(), cast(FD)->getParent(), ObjectType, ObjectClassification, FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } } else { // This branch handles both standalone functions and static methods. // Slice the first argument (which is the base) when we access // static method as non-static. if (Args.size() > 0 && (!Args[0] || (FirstArgumentIsBase && isa(FD) && !isa(FD)))) { assert(cast(FD)->isStatic()); FunctionArgs = Args.slice(1); } if (FunTmpl) { AddTemplateOverloadCandidate(FunTmpl, F.getPair(), ExplicitTemplateArgs, FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } else { AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } } } } /// AddMethodCandidate - Adds a named decl (which is some kind of /// method) as a method candidate to the given overload set. void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, OverloadCandidateParamOrder PO) { NamedDecl *Decl = FoundDecl.getDecl(); CXXRecordDecl *ActingContext = cast(Decl->getDeclContext()); if (isa(Decl)) Decl = cast(Decl)->getTargetDecl(); if (FunctionTemplateDecl *TD = dyn_cast(Decl)) { assert(isa(TD->getTemplatedDecl()) && "Expected a member function template"); AddMethodTemplateCandidate(TD, FoundDecl, ActingContext, /*ExplicitArgs*/ nullptr, ObjectType, ObjectClassification, Args, CandidateSet, SuppressUserConversions, false, PO); } else { AddMethodCandidate(cast(Decl), FoundDecl, ActingContext, ObjectType, ObjectClassification, Args, CandidateSet, SuppressUserConversions, false, None, PO); } } /// AddMethodCandidate - Adds the given C++ member function to the set /// of candidate functions, using the given function call arguments /// and the object argument (@c Object). For example, in a call /// @c o.f(a1,a2), @c Object will contain @c o and @c Args will contain /// both @c a1 and @c a2. If @p SuppressUserConversions, then don't /// allow user-defined conversions via constructors or conversion /// operators. void Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, ConversionSequenceList EarlyConversions, OverloadCandidateParamOrder PO) { const FunctionProtoType *Proto = dyn_cast(Method->getType()->getAs()); assert(Proto && "Methods without a prototype cannot be overloaded"); assert(!isa(Method) && "Use AddOverloadCandidate for constructors"); if (!CandidateSet.isNewCandidate(Method, PO)) return; // C++11 [class.copy]p23: [DR1402] // A defaulted move assignment operator that is defined as deleted is // ignored by overload resolution. if (Method->isDefaulted() && Method->isDeleted() && Method->isMoveAssignmentOperator()) return; // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); // Add this candidate OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1, EarlyConversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = Method; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Method, PO); Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = Args.size(); unsigned NumParams = Proto->getNumParams(); // (C++ 13.3.2p2): A candidate function having fewer than m // parameters is viable only if it has an ellipsis in its parameter // list (8.3.5). if (TooManyArguments(NumParams, Args.size(), PartialOverloading) && !Proto->isVariadic()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_many_arguments; return; } // (C++ 13.3.2p2): A candidate function having more than m parameters // is viable only if the (m+1)st parameter has a default argument // (8.3.6). For the purposes of overload resolution, the // parameter list is truncated on the right, so that there are // exactly m parameters. unsigned MinRequiredArgs = Method->getMinRequiredArguments(); if (Args.size() < MinRequiredArgs && !PartialOverloading) { // Not enough arguments. Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_few_arguments; return; } Candidate.Viable = true; if (Method->isStatic() || ObjectType.isNull()) // The implicit object argument is ignored. Candidate.IgnoreObjectArgument = true; else { unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 1 : 0; // Determine the implicit conversion sequence for the object // parameter. Candidate.Conversions[ConvIdx] = TryObjectArgumentInitialization( *this, CandidateSet.getLocation(), ObjectType, ObjectClassification, Method, ActingContext); if (Candidate.Conversions[ConvIdx].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; return; } } // (CUDA B.1): Check for invalid calls between targets. if (getLangOpts().CUDA) if (const FunctionDecl *Caller = dyn_cast(CurContext)) if (!IsAllowedCUDACall(Caller, Method)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_target; return; } if (Method->getTrailingRequiresClause()) { ConstraintSatisfaction Satisfaction; if (CheckFunctionConstraints(Method, Satisfaction) || !Satisfaction.IsSatisfied) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_constraints_not_satisfied; return; } } // Determine the implicit conversion sequences for each of the // arguments. for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 0 : (ArgIdx + 1); if (Candidate.Conversions[ConvIdx].isInitialized()) { // We already formed a conversion sequence for this parameter during // template argument deduction. } else if (ArgIdx < NumParams) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding // parameter of F. QualType ParamType = Proto->getParamType(ArgIdx); Candidate.Conversions[ConvIdx] = TryCopyInitialization(*this, Args[ArgIdx], ParamType, SuppressUserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount); if (Candidate.Conversions[ConvIdx].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; return; } } else { // (C++ 13.3.2p2): For the purposes of overload resolution, any // argument for which there is no corresponding parameter is // considered to "match the ellipsis" (C+ 13.3.3.1.3). Candidate.Conversions[ConvIdx].setEllipsis(); } } if (EnableIfAttr *FailedAttr = CheckEnableIf(Method, Args, true)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; Candidate.DeductionFailure.Data = FailedAttr; return; } if (Method->isMultiVersion() && Method->hasAttr() && !Method->getAttr()->isDefaultVersion()) { Candidate.Viable = false; Candidate.FailureKind = ovl_non_default_multiversion_function; } } /// Add a C++ member function template as a candidate to the candidate /// set, using template argument deduction to produce an appropriate member /// function template specialization. void Sema::AddMethodTemplateCandidate( FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, OverloadCandidateParamOrder PO) { if (!CandidateSet.isNewCandidate(MethodTmpl, PO)) return; // C++ [over.match.funcs]p7: // In each case where a candidate is a function template, candidate // function template specializations are generated using template argument // deduction (14.8.3, 14.8.2). Those candidates are then handled as // candidate functions in the usual way.113) A given name can refer to one // or more function templates and also to a set of overloaded non-template // functions. In such a case, the candidate functions generated from each // function template are combined with the set of non-template candidate // functions. TemplateDeductionInfo Info(CandidateSet.getLocation()); FunctionDecl *Specialization = nullptr; ConversionSequenceList Conversions; if (TemplateDeductionResult Result = DeduceTemplateArguments( MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info, PartialOverloading, [&](ArrayRef ParamTypes) { return CheckNonDependentConversions( MethodTmpl, ParamTypes, Args, CandidateSet, Conversions, SuppressUserConversions, ActingContext, ObjectType, ObjectClassification, PO); })) { OverloadCandidate &Candidate = CandidateSet.addCandidate(Conversions.size(), Conversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = MethodTmpl->getTemplatedDecl(); Candidate.Viable = false; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Candidate.Function, PO); Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = cast(Candidate.Function)->isStatic() || ObjectType.isNull(); Candidate.ExplicitCallArguments = Args.size(); if (Result == TDK_NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; else { Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, Info); } return; } // Add the function template specialization produced by template argument // deduction as a candidate. assert(Specialization && "Missing member function template specialization?"); assert(isa(Specialization) && "Specialization is not a member function?"); AddMethodCandidate(cast(Specialization), FoundDecl, ActingContext, ObjectType, ObjectClassification, Args, CandidateSet, SuppressUserConversions, PartialOverloading, Conversions, PO); } /// Determine whether a given function template has a simple explicit specifier /// or a non-value-dependent explicit-specification that evaluates to true. static bool isNonDependentlyExplicit(FunctionTemplateDecl *FTD) { return ExplicitSpecifier::getFromDecl(FTD->getTemplatedDecl()).isExplicit(); } /// Add a C++ function template specialization as a candidate /// in the candidate set, using template argument deduction to produce /// an appropriate function template specialization. void Sema::AddTemplateOverloadCandidate( FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, bool AllowExplicit, ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO) { if (!CandidateSet.isNewCandidate(FunctionTemplate, PO)) return; // If the function template has a non-dependent explicit specification, // exclude it now if appropriate; we are not permitted to perform deduction // and substitution in this case. if (!AllowExplicit && isNonDependentlyExplicit(FunctionTemplate)) { OverloadCandidate &Candidate = CandidateSet.addCandidate(); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.FailureKind = ovl_fail_explicit; return; } // C++ [over.match.funcs]p7: // In each case where a candidate is a function template, candidate // function template specializations are generated using template argument // deduction (14.8.3, 14.8.2). Those candidates are then handled as // candidate functions in the usual way.113) A given name can refer to one // or more function templates and also to a set of overloaded non-template // functions. In such a case, the candidate functions generated from each // function template are combined with the set of non-template candidate // functions. TemplateDeductionInfo Info(CandidateSet.getLocation()); FunctionDecl *Specialization = nullptr; ConversionSequenceList Conversions; if (TemplateDeductionResult Result = DeduceTemplateArguments( FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info, PartialOverloading, [&](ArrayRef ParamTypes) { return CheckNonDependentConversions( FunctionTemplate, ParamTypes, Args, CandidateSet, Conversions, SuppressUserConversions, nullptr, QualType(), {}, PO); })) { OverloadCandidate &Candidate = CandidateSet.addCandidate(Conversions.size(), Conversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Candidate.Function, PO); Candidate.IsSurrogate = false; Candidate.IsADLCandidate = IsADLCandidate; // Ignore the object argument if there is one, since we don't have an object // type. Candidate.IgnoreObjectArgument = isa(Candidate.Function) && !isa(Candidate.Function); Candidate.ExplicitCallArguments = Args.size(); if (Result == TDK_NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; else { Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, Info); } return; } // Add the function template specialization produced by template argument // deduction as a candidate. assert(Specialization && "Missing function template specialization?"); AddOverloadCandidate( Specialization, FoundDecl, Args, CandidateSet, SuppressUserConversions, PartialOverloading, AllowExplicit, /*AllowExplicitConversions*/ false, IsADLCandidate, Conversions, PO); } /// Check that implicit conversion sequences can be formed for each argument /// whose corresponding parameter has a non-dependent type, per DR1391's /// [temp.deduct.call]p10. bool Sema::CheckNonDependentConversions( FunctionTemplateDecl *FunctionTemplate, ArrayRef ParamTypes, ArrayRef Args, OverloadCandidateSet &CandidateSet, ConversionSequenceList &Conversions, bool SuppressUserConversions, CXXRecordDecl *ActingContext, QualType ObjectType, Expr::Classification ObjectClassification, OverloadCandidateParamOrder PO) { // FIXME: The cases in which we allow explicit conversions for constructor // arguments never consider calling a constructor template. It's not clear // that is correct. const bool AllowExplicit = false; auto *FD = FunctionTemplate->getTemplatedDecl(); auto *Method = dyn_cast(FD); bool HasThisConversion = Method && !isa(Method); unsigned ThisConversions = HasThisConversion ? 1 : 0; Conversions = CandidateSet.allocateConversionSequences(ThisConversions + Args.size()); // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); // For a method call, check the 'this' conversion here too. DR1391 doesn't // require that, but this check should never result in a hard error, and // overload resolution is permitted to sidestep instantiations. if (HasThisConversion && !cast(FD)->isStatic() && !ObjectType.isNull()) { unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 1 : 0; Conversions[ConvIdx] = TryObjectArgumentInitialization( *this, CandidateSet.getLocation(), ObjectType, ObjectClassification, Method, ActingContext); if (Conversions[ConvIdx].isBad()) return true; } for (unsigned I = 0, N = std::min(ParamTypes.size(), Args.size()); I != N; ++I) { QualType ParamType = ParamTypes[I]; if (!ParamType->isDependentType()) { unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 0 : (ThisConversions + I); Conversions[ConvIdx] = TryCopyInitialization(*this, Args[I], ParamType, SuppressUserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, AllowExplicit); if (Conversions[ConvIdx].isBad()) return true; } } return false; } /// Determine whether this is an allowable conversion from the result /// of an explicit conversion operator to the expected type, per C++ /// [over.match.conv]p1 and [over.match.ref]p1. /// /// \param ConvType The return type of the conversion function. /// /// \param ToType The type we are converting to. /// /// \param AllowObjCPointerConversion Allow a conversion from one /// Objective-C pointer to another. /// /// \returns true if the conversion is allowable, false otherwise. static bool isAllowableExplicitConversion(Sema &S, QualType ConvType, QualType ToType, bool AllowObjCPointerConversion) { QualType ToNonRefType = ToType.getNonReferenceType(); // Easy case: the types are the same. if (S.Context.hasSameUnqualifiedType(ConvType, ToNonRefType)) return true; // Allow qualification conversions. bool ObjCLifetimeConversion; if (S.IsQualificationConversion(ConvType, ToNonRefType, /*CStyle*/false, ObjCLifetimeConversion)) return true; // If we're not allowed to consider Objective-C pointer conversions, // we're done. if (!AllowObjCPointerConversion) return false; // Is this an Objective-C pointer conversion? bool IncompatibleObjC = false; QualType ConvertedType; return S.isObjCPointerConversion(ConvType, ToNonRefType, ConvertedType, IncompatibleObjC); } /// AddConversionCandidate - Add a C++ conversion function as a /// candidate in the candidate set (C++ [over.match.conv], /// C++ [over.match.copy]). From is the expression we're converting from, /// and ToType is the type that we're eventually trying to convert to /// (which may or may not be the same type as the type that the /// conversion function produces). void Sema::AddConversionCandidate( CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, Expr *From, QualType ToType, OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, bool AllowExplicit, bool AllowResultConversion) { assert(!Conversion->getDescribedFunctionTemplate() && "Conversion function templates use AddTemplateConversionCandidate"); QualType ConvType = Conversion->getConversionType().getNonReferenceType(); if (!CandidateSet.isNewCandidate(Conversion)) return; // If the conversion function has an undeduced return type, trigger its // deduction now. if (getLangOpts().CPlusPlus14 && ConvType->isUndeducedType()) { if (DeduceReturnType(Conversion, From->getExprLoc())) return; ConvType = Conversion->getConversionType().getNonReferenceType(); } // If we don't allow any conversion of the result type, ignore conversion // functions that don't convert to exactly (possibly cv-qualified) T. if (!AllowResultConversion && !Context.hasSameUnqualifiedType(Conversion->getConversionType(), ToType)) return; // Per C++ [over.match.conv]p1, [over.match.ref]p1, an explicit conversion // operator is only a candidate if its return type is the target type or // can be converted to the target type with a qualification conversion. // // FIXME: Include such functions in the candidate list and explain why we // can't select them. if (Conversion->isExplicit() && !isAllowableExplicitConversion(*this, ConvType, ToType, AllowObjCConversionOnExplicit)) return; // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); // Add this candidate OverloadCandidate &Candidate = CandidateSet.addCandidate(1); Candidate.FoundDecl = FoundDecl; Candidate.Function = Conversion; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.FinalConversion.setAsIdentityConversion(); Candidate.FinalConversion.setFromType(ConvType); Candidate.FinalConversion.setAllToTypes(ToType); Candidate.Viable = true; Candidate.ExplicitCallArguments = 1; // Explicit functions are not actually candidates at all if we're not // allowing them in this context, but keep them around so we can point // to them in diagnostics. if (!AllowExplicit && Conversion->isExplicit()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_explicit; return; } // C++ [over.match.funcs]p4: // For conversion functions, the function is considered to be a member of // the class of the implicit implied object argument for the purpose of // defining the type of the implicit object parameter. // // Determine the implicit conversion sequence for the implicit // object parameter. QualType ImplicitParamType = From->getType(); if (const PointerType *FromPtrType = ImplicitParamType->getAs()) ImplicitParamType = FromPtrType->getPointeeType(); CXXRecordDecl *ConversionContext = cast(ImplicitParamType->castAs()->getDecl()); Candidate.Conversions[0] = TryObjectArgumentInitialization( *this, CandidateSet.getLocation(), From->getType(), From->Classify(Context), Conversion, ConversionContext); if (Candidate.Conversions[0].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; return; } if (Conversion->getTrailingRequiresClause()) { ConstraintSatisfaction Satisfaction; if (CheckFunctionConstraints(Conversion, Satisfaction) || !Satisfaction.IsSatisfied) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_constraints_not_satisfied; return; } } // We won't go through a user-defined type conversion function to convert a // derived to base as such conversions are given Conversion Rank. They only // go through a copy constructor. 13.3.3.1.2-p4 [over.ics.user] QualType FromCanon = Context.getCanonicalType(From->getType().getUnqualifiedType()); QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType(); if (FromCanon == ToCanon || IsDerivedFrom(CandidateSet.getLocation(), FromCanon, ToCanon)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_trivial_conversion; return; } // To determine what the conversion from the result of calling the // conversion function to the type we're eventually trying to // convert to (ToType), we need to synthesize a call to the // conversion function and attempt copy initialization from it. This // makes sure that we get the right semantics with respect to // lvalues/rvalues and the type. Fortunately, we can allocate this // call on the stack and we don't need its arguments to be // well-formed. DeclRefExpr ConversionRef(Context, Conversion, false, Conversion->getType(), VK_LValue, From->getBeginLoc()); ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack, Context.getPointerType(Conversion->getType()), CK_FunctionToPointerDecay, &ConversionRef, VK_RValue); QualType ConversionType = Conversion->getConversionType(); if (!isCompleteType(From->getBeginLoc(), ConversionType)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_final_conversion; return; } ExprValueKind VK = Expr::getValueKindForType(ConversionType); // Note that it is safe to allocate CallExpr on the stack here because // there are 0 arguments (i.e., nothing is allocated using ASTContext's // allocator). QualType CallResultType = ConversionType.getNonLValueExprType(Context); alignas(CallExpr) char Buffer[sizeof(CallExpr) + sizeof(Stmt *)]; CallExpr *TheTemporaryCall = CallExpr::CreateTemporary( Buffer, &ConversionFn, CallResultType, VK, From->getBeginLoc()); ImplicitConversionSequence ICS = TryCopyInitialization(*this, TheTemporaryCall, ToType, /*SuppressUserConversions=*/true, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/false); switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: Candidate.FinalConversion = ICS.Standard; // C++ [over.ics.user]p3: // If the user-defined conversion is specified by a specialization of a // conversion function template, the second standard conversion sequence // shall have exact match rank. if (Conversion->getPrimaryTemplate() && GetConversionRank(ICS.Standard.Second) != ICR_Exact_Match) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_final_conversion_not_exact; return; } // C++0x [dcl.init.ref]p5: // In the second case, if the reference is an rvalue reference and // the second standard conversion sequence of the user-defined // conversion sequence includes an lvalue-to-rvalue conversion, the // program is ill-formed. if (ToType->isRValueReferenceType() && ICS.Standard.First == ICK_Lvalue_To_Rvalue) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_final_conversion; return; } break; case ImplicitConversionSequence::BadConversion: Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_final_conversion; return; default: llvm_unreachable( "Can only end up with a standard conversion sequence or failure"); } if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, None)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; Candidate.DeductionFailure.Data = FailedAttr; return; } if (Conversion->isMultiVersion() && Conversion->hasAttr() && !Conversion->getAttr()->isDefaultVersion()) { Candidate.Viable = false; Candidate.FailureKind = ovl_non_default_multiversion_function; } } /// Adds a conversion function template specialization /// candidate to the overload set, using template argument deduction /// to deduce the template arguments of the conversion function /// template from the type that we are converting to (C++ /// [temp.deduct.conv]). void Sema::AddTemplateConversionCandidate( FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, CXXRecordDecl *ActingDC, Expr *From, QualType ToType, OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, bool AllowExplicit, bool AllowResultConversion) { assert(isa(FunctionTemplate->getTemplatedDecl()) && "Only conversion function templates permitted here"); if (!CandidateSet.isNewCandidate(FunctionTemplate)) return; // If the function template has a non-dependent explicit specification, // exclude it now if appropriate; we are not permitted to perform deduction // and substitution in this case. if (!AllowExplicit && isNonDependentlyExplicit(FunctionTemplate)) { OverloadCandidate &Candidate = CandidateSet.addCandidate(); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.FailureKind = ovl_fail_explicit; return; } TemplateDeductionInfo Info(CandidateSet.getLocation()); CXXConversionDecl *Specialization = nullptr; if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, ToType, Specialization, Info)) { OverloadCandidate &Candidate = CandidateSet.addCandidate(); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = 1; Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, Info); return; } // Add the conversion function template specialization produced by // template argument deduction as a candidate. assert(Specialization && "Missing function template specialization?"); AddConversionCandidate(Specialization, FoundDecl, ActingDC, From, ToType, CandidateSet, AllowObjCConversionOnExplicit, AllowExplicit, AllowResultConversion); } /// AddSurrogateCandidate - Adds a "surrogate" candidate function that /// converts the given @c Object to a function pointer via the /// conversion function @c Conversion, and then attempts to call it /// with the given arguments (C++ [over.call.object]p2-4). Proto is /// the type of function that we'll eventually be calling. void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, const FunctionProtoType *Proto, Expr *Object, ArrayRef Args, OverloadCandidateSet& CandidateSet) { if (!CandidateSet.isNewCandidate(Conversion)) return; // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1); Candidate.FoundDecl = FoundDecl; Candidate.Function = nullptr; Candidate.Surrogate = Conversion; Candidate.Viable = true; Candidate.IsSurrogate = true; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = Args.size(); // Determine the implicit conversion sequence for the implicit // object parameter. ImplicitConversionSequence ObjectInit = TryObjectArgumentInitialization( *this, CandidateSet.getLocation(), Object->getType(), Object->Classify(Context), Conversion, ActingContext); if (ObjectInit.isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; Candidate.Conversions[0] = ObjectInit; return; } // The first conversion is actually a user-defined conversion whose // first conversion is ObjectInit's standard conversion (which is // effectively a reference binding). Record it as such. Candidate.Conversions[0].setUserDefined(); Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard; Candidate.Conversions[0].UserDefined.EllipsisConversion = false; Candidate.Conversions[0].UserDefined.HadMultipleCandidates = false; Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion; Candidate.Conversions[0].UserDefined.FoundConversionFunction = FoundDecl; Candidate.Conversions[0].UserDefined.After = Candidate.Conversions[0].UserDefined.Before; Candidate.Conversions[0].UserDefined.After.setAsIdentityConversion(); // Find the unsigned NumParams = Proto->getNumParams(); // (C++ 13.3.2p2): A candidate function having fewer than m // parameters is viable only if it has an ellipsis in its parameter // list (8.3.5). if (Args.size() > NumParams && !Proto->isVariadic()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_many_arguments; return; } // Function types don't have any default arguments, so just check if // we have enough arguments. if (Args.size() < NumParams) { // Not enough arguments. Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_few_arguments; return; } // Determine the implicit conversion sequences for each of the // arguments. for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { if (ArgIdx < NumParams) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding // parameter of F. QualType ParamType = Proto->getParamType(ArgIdx); Candidate.Conversions[ArgIdx + 1] = TryCopyInitialization(*this, Args[ArgIdx], ParamType, /*SuppressUserConversions=*/false, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount); if (Candidate.Conversions[ArgIdx + 1].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; return; } } else { // (C++ 13.3.2p2): For the purposes of overload resolution, any // argument for which there is no corresponding parameter is // considered to ""match the ellipsis" (C+ 13.3.3.1.3). Candidate.Conversions[ArgIdx + 1].setEllipsis(); } } if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, None)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; Candidate.DeductionFailure.Data = FailedAttr; return; } } /// Add all of the non-member operator function declarations in the given /// function set to the overload candidate set. void Sema::AddNonMemberOperatorCandidates( const UnresolvedSetImpl &Fns, ArrayRef Args, OverloadCandidateSet &CandidateSet, TemplateArgumentListInfo *ExplicitTemplateArgs) { for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { NamedDecl *D = F.getDecl()->getUnderlyingDecl(); ArrayRef FunctionArgs = Args; FunctionTemplateDecl *FunTmpl = dyn_cast(D); FunctionDecl *FD = FunTmpl ? FunTmpl->getTemplatedDecl() : cast(D); // Don't consider rewritten functions if we're not rewriting. if (!CandidateSet.getRewriteInfo().isAcceptableCandidate(FD)) continue; assert(!isa(FD) && "unqualified operator lookup found a member function"); if (FunTmpl) { AddTemplateOverloadCandidate(FunTmpl, F.getPair(), ExplicitTemplateArgs, FunctionArgs, CandidateSet); if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) AddTemplateOverloadCandidate( FunTmpl, F.getPair(), ExplicitTemplateArgs, {FunctionArgs[1], FunctionArgs[0]}, CandidateSet, false, false, true, ADLCallKind::NotADL, OverloadCandidateParamOrder::Reversed); } else { if (ExplicitTemplateArgs) continue; AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet); if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) AddOverloadCandidate(FD, F.getPair(), {FunctionArgs[1], FunctionArgs[0]}, CandidateSet, false, false, true, false, ADLCallKind::NotADL, None, OverloadCandidateParamOrder::Reversed); } } } /// Add overload candidates for overloaded operators that are /// member functions. /// /// Add the overloaded operator candidates that are member functions /// for the operator Op that was used in an operator expression such /// as "x Op y". , Args/NumArgs provides the operator arguments, and /// CandidateSet will store the added overload candidates. (C++ /// [over.match.oper]). void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, SourceLocation OpLoc, ArrayRef Args, OverloadCandidateSet &CandidateSet, OverloadCandidateParamOrder PO) { DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); // C++ [over.match.oper]p3: // For a unary operator @ with an operand of a type whose // cv-unqualified version is T1, and for a binary operator @ with // a left operand of a type whose cv-unqualified version is T1 and // a right operand of a type whose cv-unqualified version is T2, // three sets of candidate functions, designated member // candidates, non-member candidates and built-in candidates, are // constructed as follows: QualType T1 = Args[0]->getType(); // -- If T1 is a complete class type or a class currently being // defined, the set of member candidates is the result of the // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, // the set of member candidates is empty. if (const RecordType *T1Rec = T1->getAs()) { // Complete the type if it can be completed. if (!isCompleteType(OpLoc, T1) && !T1Rec->isBeingDefined()) return; // If the type is neither complete nor being defined, bail out now. if (!T1Rec->getDecl()->getDefinition()) return; LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName); LookupQualifiedName(Operators, T1Rec->getDecl()); Operators.suppressDiagnostics(); for (LookupResult::iterator Oper = Operators.begin(), OperEnd = Operators.end(); Oper != OperEnd; ++Oper) AddMethodCandidate(Oper.getPair(), Args[0]->getType(), Args[0]->Classify(Context), Args.slice(1), CandidateSet, /*SuppressUserConversion=*/false, PO); } } /// AddBuiltinCandidate - Add a candidate for a built-in /// operator. ResultTy and ParamTys are the result and parameter types /// of the built-in candidate, respectively. Args and NumArgs are the /// arguments being passed to the candidate. IsAssignmentOperator /// should be true when this built-in candidate is an assignment /// operator. NumContextualBoolArguments is the number of arguments /// (at the beginning of the argument list) that will be contextually /// converted to bool. void Sema::AddBuiltinCandidate(QualType *ParamTys, ArrayRef Args, OverloadCandidateSet& CandidateSet, bool IsAssignmentOperator, unsigned NumContextualBoolArguments) { // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); // Add this candidate OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); Candidate.FoundDecl = DeclAccessPair::make(nullptr, AS_none); Candidate.Function = nullptr; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; std::copy(ParamTys, ParamTys + Args.size(), Candidate.BuiltinParamTypes); // Determine the implicit conversion sequences for each of the // arguments. Candidate.Viable = true; Candidate.ExplicitCallArguments = Args.size(); for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { // C++ [over.match.oper]p4: // For the built-in assignment operators, conversions of the // left operand are restricted as follows: // -- no temporaries are introduced to hold the left operand, and // -- no user-defined conversions are applied to the left // operand to achieve a type match with the left-most // parameter of a built-in candidate. // // We block these conversions by turning off user-defined // conversions, since that is the only way that initialization of // a reference to a non-class type can occur from something that // is not of the same type. if (ArgIdx < NumContextualBoolArguments) { assert(ParamTys[ArgIdx] == Context.BoolTy && "Contextual conversion to bool requires bool type"); Candidate.Conversions[ArgIdx] = TryContextuallyConvertToBool(*this, Args[ArgIdx]); } else { Candidate.Conversions[ArgIdx] = TryCopyInitialization(*this, Args[ArgIdx], ParamTys[ArgIdx], ArgIdx == 0 && IsAssignmentOperator, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount); } if (Candidate.Conversions[ArgIdx].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; break; } } } namespace { /// BuiltinCandidateTypeSet - A set of types that will be used for the /// candidate operator functions for built-in operators (C++ /// [over.built]). The types are separated into pointer types and /// enumeration types. class BuiltinCandidateTypeSet { /// TypeSet - A set of types. typedef llvm::SetVector, llvm::SmallPtrSet> TypeSet; /// PointerTypes - The set of pointer types that will be used in the /// built-in candidates. TypeSet PointerTypes; /// MemberPointerTypes - The set of member pointer types that will be /// used in the built-in candidates. TypeSet MemberPointerTypes; /// EnumerationTypes - The set of enumeration types that will be /// used in the built-in candidates. TypeSet EnumerationTypes; /// The set of vector types that will be used in the built-in /// candidates. TypeSet VectorTypes; /// A flag indicating non-record types are viable candidates bool HasNonRecordTypes; /// A flag indicating whether either arithmetic or enumeration types /// were present in the candidate set. bool HasArithmeticOrEnumeralTypes; /// A flag indicating whether the nullptr type was present in the /// candidate set. bool HasNullPtrType; /// Sema - The semantic analysis instance where we are building the /// candidate type set. Sema &SemaRef; /// Context - The AST context in which we will build the type sets. ASTContext &Context; bool AddPointerWithMoreQualifiedTypeVariants(QualType Ty, const Qualifiers &VisibleQuals); bool AddMemberPointerWithMoreQualifiedTypeVariants(QualType Ty); public: /// iterator - Iterates through the types that are part of the set. typedef TypeSet::iterator iterator; BuiltinCandidateTypeSet(Sema &SemaRef) : HasNonRecordTypes(false), HasArithmeticOrEnumeralTypes(false), HasNullPtrType(false), SemaRef(SemaRef), Context(SemaRef.Context) { } void AddTypesConvertedFrom(QualType Ty, SourceLocation Loc, bool AllowUserConversions, bool AllowExplicitConversions, const Qualifiers &VisibleTypeConversionsQuals); /// pointer_begin - First pointer type found; iterator pointer_begin() { return PointerTypes.begin(); } /// pointer_end - Past the last pointer type found; iterator pointer_end() { return PointerTypes.end(); } /// member_pointer_begin - First member pointer type found; iterator member_pointer_begin() { return MemberPointerTypes.begin(); } /// member_pointer_end - Past the last member pointer type found; iterator member_pointer_end() { return MemberPointerTypes.end(); } /// enumeration_begin - First enumeration type found; iterator enumeration_begin() { return EnumerationTypes.begin(); } /// enumeration_end - Past the last enumeration type found; iterator enumeration_end() { return EnumerationTypes.end(); } iterator vector_begin() { return VectorTypes.begin(); } iterator vector_end() { return VectorTypes.end(); } bool hasNonRecordTypes() { return HasNonRecordTypes; } bool hasArithmeticOrEnumeralTypes() { return HasArithmeticOrEnumeralTypes; } bool hasNullPtrType() const { return HasNullPtrType; } }; } // end anonymous namespace /// AddPointerWithMoreQualifiedTypeVariants - Add the pointer type @p Ty to /// the set of pointer types along with any more-qualified variants of /// that type. For example, if @p Ty is "int const *", this routine /// will add "int const *", "int const volatile *", "int const /// restrict *", and "int const volatile restrict *" to the set of /// pointer types. Returns true if the add of @p Ty itself succeeded, /// false otherwise. /// /// FIXME: what to do about extended qualifiers? bool BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty, const Qualifiers &VisibleQuals) { // Insert this type. if (!PointerTypes.insert(Ty)) return false; QualType PointeeTy; const PointerType *PointerTy = Ty->getAs(); bool buildObjCPtr = false; if (!PointerTy) { const ObjCObjectPointerType *PTy = Ty->castAs(); PointeeTy = PTy->getPointeeType(); buildObjCPtr = true; } else { PointeeTy = PointerTy->getPointeeType(); } // Don't add qualified variants of arrays. For one, they're not allowed // (the qualifier would sink to the element type), and for another, the // only overload situation where it matters is subscript or pointer +- int, // and those shouldn't have qualifier variants anyway. if (PointeeTy->isArrayType()) return true; unsigned BaseCVR = PointeeTy.getCVRQualifiers(); bool hasVolatile = VisibleQuals.hasVolatile(); bool hasRestrict = VisibleQuals.hasRestrict(); // Iterate through all strict supersets of BaseCVR. for (unsigned CVR = BaseCVR+1; CVR <= Qualifiers::CVRMask; ++CVR) { if ((CVR | BaseCVR) != CVR) continue; // Skip over volatile if no volatile found anywhere in the types. if ((CVR & Qualifiers::Volatile) && !hasVolatile) continue; // Skip over restrict if no restrict found anywhere in the types, or if // the type cannot be restrict-qualified. if ((CVR & Qualifiers::Restrict) && (!hasRestrict || (!(PointeeTy->isAnyPointerType() || PointeeTy->isReferenceType())))) continue; // Build qualified pointee type. QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR); // Build qualified pointer type. QualType QPointerTy; if (!buildObjCPtr) QPointerTy = Context.getPointerType(QPointeeTy); else QPointerTy = Context.getObjCObjectPointerType(QPointeeTy); // Insert qualified pointer type. PointerTypes.insert(QPointerTy); } return true; } /// AddMemberPointerWithMoreQualifiedTypeVariants - Add the pointer type @p Ty /// to the set of pointer types along with any more-qualified variants of /// that type. For example, if @p Ty is "int const *", this routine /// will add "int const *", "int const volatile *", "int const /// restrict *", and "int const volatile restrict *" to the set of /// pointer types. Returns true if the add of @p Ty itself succeeded, /// false otherwise. /// /// FIXME: what to do about extended qualifiers? bool BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants( QualType Ty) { // Insert this type. if (!MemberPointerTypes.insert(Ty)) return false; const MemberPointerType *PointerTy = Ty->getAs(); assert(PointerTy && "type was not a member pointer type!"); QualType PointeeTy = PointerTy->getPointeeType(); // Don't add qualified variants of arrays. For one, they're not allowed // (the qualifier would sink to the element type), and for another, the // only overload situation where it matters is subscript or pointer +- int, // and those shouldn't have qualifier variants anyway. if (PointeeTy->isArrayType()) return true; const Type *ClassTy = PointerTy->getClass(); // Iterate through all strict supersets of the pointee type's CVR // qualifiers. unsigned BaseCVR = PointeeTy.getCVRQualifiers(); for (unsigned CVR = BaseCVR+1; CVR <= Qualifiers::CVRMask; ++CVR) { if ((CVR | BaseCVR) != CVR) continue; QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR); MemberPointerTypes.insert( Context.getMemberPointerType(QPointeeTy, ClassTy)); } return true; } /// AddTypesConvertedFrom - Add each of the types to which the type @p /// Ty can be implicit converted to the given set of @p Types. We're /// primarily interested in pointer types and enumeration types. We also /// take member pointer types, for the conditional operator. /// AllowUserConversions is true if we should look at the conversion /// functions of a class type, and AllowExplicitConversions if we /// should also include the explicit conversion functions of a class /// type. void BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty, SourceLocation Loc, bool AllowUserConversions, bool AllowExplicitConversions, const Qualifiers &VisibleQuals) { // Only deal with canonical types. Ty = Context.getCanonicalType(Ty); // Look through reference types; they aren't part of the type of an // expression for the purposes of conversions. if (const ReferenceType *RefTy = Ty->getAs()) Ty = RefTy->getPointeeType(); // If we're dealing with an array type, decay to the pointer. if (Ty->isArrayType()) Ty = SemaRef.Context.getArrayDecayedType(Ty); // Otherwise, we don't care about qualifiers on the type. Ty = Ty.getLocalUnqualifiedType(); // Flag if we ever add a non-record type. const RecordType *TyRec = Ty->getAs(); HasNonRecordTypes = HasNonRecordTypes || !TyRec; // Flag if we encounter an arithmetic type. HasArithmeticOrEnumeralTypes = HasArithmeticOrEnumeralTypes || Ty->isArithmeticType(); if (Ty->isObjCIdType() || Ty->isObjCClassType()) PointerTypes.insert(Ty); else if (Ty->getAs() || Ty->getAs()) { // Insert our type, and its more-qualified variants, into the set // of types. if (!AddPointerWithMoreQualifiedTypeVariants(Ty, VisibleQuals)) return; } else if (Ty->isMemberPointerType()) { // Member pointers are far easier, since the pointee can't be converted. if (!AddMemberPointerWithMoreQualifiedTypeVariants(Ty)) return; } else if (Ty->isEnumeralType()) { HasArithmeticOrEnumeralTypes = true; EnumerationTypes.insert(Ty); } else if (Ty->isVectorType()) { // We treat vector types as arithmetic types in many contexts as an // extension. HasArithmeticOrEnumeralTypes = true; VectorTypes.insert(Ty); } else if (Ty->isNullPtrType()) { HasNullPtrType = true; } else if (AllowUserConversions && TyRec) { // No conversion functions in incomplete types. if (!SemaRef.isCompleteType(Loc, Ty)) return; CXXRecordDecl *ClassDecl = cast(TyRec->getDecl()); for (NamedDecl *D : ClassDecl->getVisibleConversionFunctions()) { if (isa(D)) D = cast(D)->getTargetDecl(); // Skip conversion function templates; they don't tell us anything // about which builtin types we can convert to. if (isa(D)) continue; CXXConversionDecl *Conv = cast(D); if (AllowExplicitConversions || !Conv->isExplicit()) { AddTypesConvertedFrom(Conv->getConversionType(), Loc, false, false, VisibleQuals); } } } } /// Helper function for adjusting address spaces for the pointer or reference /// operands of builtin operators depending on the argument. static QualType AdjustAddressSpaceForBuiltinOperandType(Sema &S, QualType T, Expr *Arg) { return S.Context.getAddrSpaceQualType(T, Arg->getType().getAddressSpace()); } /// Helper function for AddBuiltinOperatorCandidates() that adds /// the volatile- and non-volatile-qualified assignment operators for the /// given type to the candidate set. static void AddBuiltinAssignmentOperatorCandidates(Sema &S, QualType T, ArrayRef Args, OverloadCandidateSet &CandidateSet) { QualType ParamTypes[2]; // T& operator=(T&, T) ParamTypes[0] = S.Context.getLValueReferenceType( AdjustAddressSpaceForBuiltinOperandType(S, T, Args[0])); ParamTypes[1] = T; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); if (!S.Context.getCanonicalType(T).isVolatileQualified()) { // volatile T& operator=(volatile T&, T) ParamTypes[0] = S.Context.getLValueReferenceType( AdjustAddressSpaceForBuiltinOperandType(S, S.Context.getVolatileType(T), Args[0])); ParamTypes[1] = T; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); } } /// CollectVRQualifiers - This routine returns Volatile/Restrict qualifiers, /// if any, found in visible type conversion functions found in ArgExpr's type. static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) { Qualifiers VRQuals; const RecordType *TyRec; if (const MemberPointerType *RHSMPType = ArgExpr->getType()->getAs()) TyRec = RHSMPType->getClass()->getAs(); else TyRec = ArgExpr->getType()->getAs(); if (!TyRec) { // Just to be safe, assume the worst case. VRQuals.addVolatile(); VRQuals.addRestrict(); return VRQuals; } CXXRecordDecl *ClassDecl = cast(TyRec->getDecl()); if (!ClassDecl->hasDefinition()) return VRQuals; for (NamedDecl *D : ClassDecl->getVisibleConversionFunctions()) { if (isa(D)) D = cast(D)->getTargetDecl(); if (CXXConversionDecl *Conv = dyn_cast(D)) { QualType CanTy = Context.getCanonicalType(Conv->getConversionType()); if (const ReferenceType *ResTypeRef = CanTy->getAs()) CanTy = ResTypeRef->getPointeeType(); // Need to go down the pointer/mempointer chain and add qualifiers // as see them. bool done = false; while (!done) { if (CanTy.isRestrictQualified()) VRQuals.addRestrict(); if (const PointerType *ResTypePtr = CanTy->getAs()) CanTy = ResTypePtr->getPointeeType(); else if (const MemberPointerType *ResTypeMPtr = CanTy->getAs()) CanTy = ResTypeMPtr->getPointeeType(); else done = true; if (CanTy.isVolatileQualified()) VRQuals.addVolatile(); if (VRQuals.hasRestrict() && VRQuals.hasVolatile()) return VRQuals; } } } return VRQuals; } namespace { /// Helper class to manage the addition of builtin operator overload /// candidates. It provides shared state and utility methods used throughout /// the process, as well as a helper method to add each group of builtin /// operator overloads from the standard to a candidate set. class BuiltinOperatorOverloadBuilder { // Common instance state available to all overload candidate addition methods. Sema &S; ArrayRef Args; Qualifiers VisibleTypeConversionsQuals; bool HasArithmeticOrEnumeralCandidateType; SmallVectorImpl &CandidateTypes; OverloadCandidateSet &CandidateSet; static constexpr int ArithmeticTypesCap = 24; SmallVector ArithmeticTypes; // Define some indices used to iterate over the arithmetic types in // ArithmeticTypes. The "promoted arithmetic types" are the arithmetic // types are that preserved by promotion (C++ [over.built]p2). unsigned FirstIntegralType, LastIntegralType; unsigned FirstPromotedIntegralType, LastPromotedIntegralType; unsigned FirstPromotedArithmeticType, LastPromotedArithmeticType; unsigned NumArithmeticTypes; void InitArithmeticTypes() { // Start of promoted types. FirstPromotedArithmeticType = 0; ArithmeticTypes.push_back(S.Context.FloatTy); ArithmeticTypes.push_back(S.Context.DoubleTy); ArithmeticTypes.push_back(S.Context.LongDoubleTy); if (S.Context.getTargetInfo().hasFloat128Type()) ArithmeticTypes.push_back(S.Context.Float128Ty); // Start of integral types. FirstIntegralType = ArithmeticTypes.size(); FirstPromotedIntegralType = ArithmeticTypes.size(); ArithmeticTypes.push_back(S.Context.IntTy); ArithmeticTypes.push_back(S.Context.LongTy); ArithmeticTypes.push_back(S.Context.LongLongTy); if (S.Context.getTargetInfo().hasInt128Type()) ArithmeticTypes.push_back(S.Context.Int128Ty); ArithmeticTypes.push_back(S.Context.UnsignedIntTy); ArithmeticTypes.push_back(S.Context.UnsignedLongTy); ArithmeticTypes.push_back(S.Context.UnsignedLongLongTy); if (S.Context.getTargetInfo().hasInt128Type()) ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty); LastPromotedIntegralType = ArithmeticTypes.size(); LastPromotedArithmeticType = ArithmeticTypes.size(); // End of promoted types. ArithmeticTypes.push_back(S.Context.BoolTy); ArithmeticTypes.push_back(S.Context.CharTy); ArithmeticTypes.push_back(S.Context.WCharTy); if (S.Context.getLangOpts().Char8) ArithmeticTypes.push_back(S.Context.Char8Ty); ArithmeticTypes.push_back(S.Context.Char16Ty); ArithmeticTypes.push_back(S.Context.Char32Ty); ArithmeticTypes.push_back(S.Context.SignedCharTy); ArithmeticTypes.push_back(S.Context.ShortTy); ArithmeticTypes.push_back(S.Context.UnsignedCharTy); ArithmeticTypes.push_back(S.Context.UnsignedShortTy); LastIntegralType = ArithmeticTypes.size(); NumArithmeticTypes = ArithmeticTypes.size(); // End of integral types. // FIXME: What about complex? What about half? assert(ArithmeticTypes.size() <= ArithmeticTypesCap && "Enough inline storage for all arithmetic types."); } /// Helper method to factor out the common pattern of adding overloads /// for '++' and '--' builtin operators. void addPlusPlusMinusMinusStyleOverloads(QualType CandidateTy, bool HasVolatile, bool HasRestrict) { QualType ParamTypes[2] = { S.Context.getLValueReferenceType(CandidateTy), S.Context.IntTy }; // Non-volatile version. S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); // Use a heuristic to reduce number of builtin candidates in the set: // add volatile version only if there are conversions to a volatile type. if (HasVolatile) { ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getVolatileType(CandidateTy)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } // Add restrict version only if there are conversions to a restrict type // and our candidate type is a non-restrict-qualified pointer. if (HasRestrict && CandidateTy->isAnyPointerType() && !CandidateTy.isRestrictQualified()) { ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getCVRQualifiedType(CandidateTy, Qualifiers::Restrict)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); if (HasVolatile) { ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getCVRQualifiedType(CandidateTy, (Qualifiers::Volatile | Qualifiers::Restrict))); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } public: BuiltinOperatorOverloadBuilder( Sema &S, ArrayRef Args, Qualifiers VisibleTypeConversionsQuals, bool HasArithmeticOrEnumeralCandidateType, SmallVectorImpl &CandidateTypes, OverloadCandidateSet &CandidateSet) : S(S), Args(Args), VisibleTypeConversionsQuals(VisibleTypeConversionsQuals), HasArithmeticOrEnumeralCandidateType( HasArithmeticOrEnumeralCandidateType), CandidateTypes(CandidateTypes), CandidateSet(CandidateSet) { InitArithmeticTypes(); } // Increment is deprecated for bool since C++17. // // C++ [over.built]p3: // // For every pair (T, VQ), where T is an arithmetic type other // than bool, and VQ is either volatile or empty, there exist // candidate operator functions of the form // // VQ T& operator++(VQ T&); // T operator++(VQ T&, int); // // C++ [over.built]p4: // // For every pair (T, VQ), where T is an arithmetic type other // than bool, and VQ is either volatile or empty, there exist // candidate operator functions of the form // // VQ T& operator--(VQ T&); // T operator--(VQ T&, int); void addPlusPlusMinusMinusArithmeticOverloads(OverloadedOperatorKind Op) { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Arith = 0; Arith < NumArithmeticTypes; ++Arith) { const auto TypeOfT = ArithmeticTypes[Arith]; if (TypeOfT == S.Context.BoolTy) { if (Op == OO_MinusMinus) continue; if (Op == OO_PlusPlus && S.getLangOpts().CPlusPlus17) continue; } addPlusPlusMinusMinusStyleOverloads( TypeOfT, VisibleTypeConversionsQuals.hasVolatile(), VisibleTypeConversionsQuals.hasRestrict()); } } // C++ [over.built]p5: // // For every pair (T, VQ), where T is a cv-qualified or // cv-unqualified object type, and VQ is either volatile or // empty, there exist candidate operator functions of the form // // T*VQ& operator++(T*VQ&); // T*VQ& operator--(T*VQ&); // T* operator++(T*VQ&, int); // T* operator--(T*VQ&, int); void addPlusPlusMinusMinusPointerOverloads() { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { // Skip pointer types that aren't pointers to object types. if (!(*Ptr)->getPointeeType()->isObjectType()) continue; addPlusPlusMinusMinusStyleOverloads(*Ptr, (!(*Ptr).isVolatileQualified() && VisibleTypeConversionsQuals.hasVolatile()), (!(*Ptr).isRestrictQualified() && VisibleTypeConversionsQuals.hasRestrict())); } } // C++ [over.built]p6: // For every cv-qualified or cv-unqualified object type T, there // exist candidate operator functions of the form // // T& operator*(T*); // // C++ [over.built]p7: // For every function type T that does not have cv-qualifiers or a // ref-qualifier, there exist candidate operator functions of the form // T& operator*(T*); void addUnaryStarPointerOverloads() { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType ParamTy = *Ptr; QualType PointeeTy = ParamTy->getPointeeType(); if (!PointeeTy->isObjectType() && !PointeeTy->isFunctionType()) continue; if (const FunctionProtoType *Proto =PointeeTy->getAs()) if (Proto->getMethodQuals() || Proto->getRefQualifier()) continue; S.AddBuiltinCandidate(&ParamTy, Args, CandidateSet); } } // C++ [over.built]p9: // For every promoted arithmetic type T, there exist candidate // operator functions of the form // // T operator+(T); // T operator-(T); void addUnaryPlusOrMinusArithmeticOverloads() { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Arith = FirstPromotedArithmeticType; Arith < LastPromotedArithmeticType; ++Arith) { QualType ArithTy = ArithmeticTypes[Arith]; S.AddBuiltinCandidate(&ArithTy, Args, CandidateSet); } // Extension: We also add these operators for vector types. for (BuiltinCandidateTypeSet::iterator Vec = CandidateTypes[0].vector_begin(), VecEnd = CandidateTypes[0].vector_end(); Vec != VecEnd; ++Vec) { QualType VecTy = *Vec; S.AddBuiltinCandidate(&VecTy, Args, CandidateSet); } } // C++ [over.built]p8: // For every type T, there exist candidate operator functions of // the form // // T* operator+(T*); void addUnaryPlusPointerOverloads() { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType ParamTy = *Ptr; S.AddBuiltinCandidate(&ParamTy, Args, CandidateSet); } } // C++ [over.built]p10: // For every promoted integral type T, there exist candidate // operator functions of the form // // T operator~(T); void addUnaryTildePromotedIntegralOverloads() { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Int = FirstPromotedIntegralType; Int < LastPromotedIntegralType; ++Int) { QualType IntTy = ArithmeticTypes[Int]; S.AddBuiltinCandidate(&IntTy, Args, CandidateSet); } // Extension: We also add this operator for vector types. for (BuiltinCandidateTypeSet::iterator Vec = CandidateTypes[0].vector_begin(), VecEnd = CandidateTypes[0].vector_end(); Vec != VecEnd; ++Vec) { QualType VecTy = *Vec; S.AddBuiltinCandidate(&VecTy, Args, CandidateSet); } } // C++ [over.match.oper]p16: // For every pointer to member type T or type std::nullptr_t, there // exist candidate operator functions of the form // // bool operator==(T,T); // bool operator!=(T,T); void addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads() { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(), MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end(); MemPtr != MemPtrEnd; ++MemPtr) { // Don't add the same builtin candidate twice. if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)).second) continue; QualType ParamTypes[2] = { *MemPtr, *MemPtr }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } if (CandidateTypes[ArgIdx].hasNullPtrType()) { CanQualType NullPtrTy = S.Context.getCanonicalType(S.Context.NullPtrTy); if (AddedTypes.insert(NullPtrTy).second) { QualType ParamTypes[2] = { NullPtrTy, NullPtrTy }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } } // C++ [over.built]p15: // // For every T, where T is an enumeration type or a pointer type, // there exist candidate operator functions of the form // // bool operator<(T, T); // bool operator>(T, T); // bool operator<=(T, T); // bool operator>=(T, T); // bool operator==(T, T); // bool operator!=(T, T); // R operator<=>(T, T) void addGenericBinaryPointerOrEnumeralOverloads() { // C++ [over.match.oper]p3: // [...]the built-in candidates include all of the candidate operator // functions defined in 13.6 that, compared to the given operator, [...] // do not have the same parameter-type-list as any non-template non-member // candidate. // // Note that in practice, this only affects enumeration types because there // aren't any built-in candidates of record type, and a user-defined operator // must have an operand of record or enumeration type. Also, the only other // overloaded operator with enumeration arguments, operator=, // cannot be overloaded for enumeration types, so this is the only place // where we must suppress candidates like this. llvm::DenseSet > UserDefinedBinaryOperators; for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { if (CandidateTypes[ArgIdx].enumeration_begin() != CandidateTypes[ArgIdx].enumeration_end()) { for (OverloadCandidateSet::iterator C = CandidateSet.begin(), CEnd = CandidateSet.end(); C != CEnd; ++C) { if (!C->Viable || !C->Function || C->Function->getNumParams() != 2) continue; if (C->Function->isFunctionTemplateSpecialization()) continue; // We interpret "same parameter-type-list" as applying to the // "synthesized candidate, with the order of the two parameters // reversed", not to the original function. bool Reversed = C->RewriteKind & CRK_Reversed; QualType FirstParamType = C->Function->getParamDecl(Reversed ? 1 : 0) ->getType() .getUnqualifiedType(); QualType SecondParamType = C->Function->getParamDecl(Reversed ? 0 : 1) ->getType() .getUnqualifiedType(); // Skip if either parameter isn't of enumeral type. if (!FirstParamType->isEnumeralType() || !SecondParamType->isEnumeralType()) continue; // Add this operator to the set of known user-defined operators. UserDefinedBinaryOperators.insert( std::make_pair(S.Context.getCanonicalType(FirstParamType), S.Context.getCanonicalType(SecondParamType))); } } } /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[ArgIdx].pointer_begin(), PtrEnd = CandidateTypes[ArgIdx].pointer_end(); Ptr != PtrEnd; ++Ptr) { // Don't add the same builtin candidate twice. if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second) continue; QualType ParamTypes[2] = { *Ptr, *Ptr }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator Enum = CandidateTypes[ArgIdx].enumeration_begin(), EnumEnd = CandidateTypes[ArgIdx].enumeration_end(); Enum != EnumEnd; ++Enum) { CanQualType CanonType = S.Context.getCanonicalType(*Enum); // Don't add the same builtin candidate twice, or if a user defined // candidate exists. if (!AddedTypes.insert(CanonType).second || UserDefinedBinaryOperators.count(std::make_pair(CanonType, CanonType))) continue; QualType ParamTypes[2] = { *Enum, *Enum }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } // C++ [over.built]p13: // // For every cv-qualified or cv-unqualified object type T // there exist candidate operator functions of the form // // T* operator+(T*, ptrdiff_t); // T& operator[](T*, ptrdiff_t); [BELOW] // T* operator-(T*, ptrdiff_t); // T* operator+(ptrdiff_t, T*); // T& operator[](ptrdiff_t, T*); [BELOW] // // C++ [over.built]p14: // // For every T, where T is a pointer to object type, there // exist candidate operator functions of the form // // ptrdiff_t operator-(T, T); void addBinaryPlusOrMinusPointerOverloads(OverloadedOperatorKind Op) { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (int Arg = 0; Arg < 2; ++Arg) { QualType AsymmetricParamTypes[2] = { S.Context.getPointerDiffType(), S.Context.getPointerDiffType(), }; for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[Arg].pointer_begin(), PtrEnd = CandidateTypes[Arg].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType PointeeTy = (*Ptr)->getPointeeType(); if (!PointeeTy->isObjectType()) continue; AsymmetricParamTypes[Arg] = *Ptr; if (Arg == 0 || Op == OO_Plus) { // operator+(T*, ptrdiff_t) or operator-(T*, ptrdiff_t) // T* operator+(ptrdiff_t, T*); S.AddBuiltinCandidate(AsymmetricParamTypes, Args, CandidateSet); } if (Op == OO_Minus) { // ptrdiff_t operator-(T, T); if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second) continue; QualType ParamTypes[2] = { *Ptr, *Ptr }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } } // C++ [over.built]p12: // // For every pair of promoted arithmetic types L and R, there // exist candidate operator functions of the form // // LR operator*(L, R); // LR operator/(L, R); // LR operator+(L, R); // LR operator-(L, R); // bool operator<(L, R); // bool operator>(L, R); // bool operator<=(L, R); // bool operator>=(L, R); // bool operator==(L, R); // bool operator!=(L, R); // // where LR is the result of the usual arithmetic conversions // between types L and R. // // C++ [over.built]p24: // // For every pair of promoted arithmetic types L and R, there exist // candidate operator functions of the form // // LR operator?(bool, L, R); // // where LR is the result of the usual arithmetic conversions // between types L and R. // Our candidates ignore the first parameter. void addGenericBinaryArithmeticOverloads() { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Left = FirstPromotedArithmeticType; Left < LastPromotedArithmeticType; ++Left) { for (unsigned Right = FirstPromotedArithmeticType; Right < LastPromotedArithmeticType; ++Right) { QualType LandR[2] = { ArithmeticTypes[Left], ArithmeticTypes[Right] }; S.AddBuiltinCandidate(LandR, Args, CandidateSet); } } // Extension: Add the binary operators ==, !=, <, <=, >=, >, *, /, and the // conditional operator for vector types. for (BuiltinCandidateTypeSet::iterator Vec1 = CandidateTypes[0].vector_begin(), Vec1End = CandidateTypes[0].vector_end(); Vec1 != Vec1End; ++Vec1) { for (BuiltinCandidateTypeSet::iterator Vec2 = CandidateTypes[1].vector_begin(), Vec2End = CandidateTypes[1].vector_end(); Vec2 != Vec2End; ++Vec2) { QualType LandR[2] = { *Vec1, *Vec2 }; S.AddBuiltinCandidate(LandR, Args, CandidateSet); } } } // C++2a [over.built]p14: // // For every integral type T there exists a candidate operator function // of the form // // std::strong_ordering operator<=>(T, T) // // C++2a [over.built]p15: // // For every pair of floating-point types L and R, there exists a candidate // operator function of the form // // std::partial_ordering operator<=>(L, R); // // FIXME: The current specification for integral types doesn't play nice with // the direction of p0946r0, which allows mixed integral and unscoped-enum // comparisons. Under the current spec this can lead to ambiguity during // overload resolution. For example: // // enum A : int {a}; // auto x = (a <=> (long)42); // // error: call is ambiguous for arguments 'A' and 'long'. // note: candidate operator<=>(int, int) // note: candidate operator<=>(long, long) // // To avoid this error, this function deviates from the specification and adds // the mixed overloads `operator<=>(L, R)` where L and R are promoted // arithmetic types (the same as the generic relational overloads). // // For now this function acts as a placeholder. void addThreeWayArithmeticOverloads() { addGenericBinaryArithmeticOverloads(); } // C++ [over.built]p17: // // For every pair of promoted integral types L and R, there // exist candidate operator functions of the form // // LR operator%(L, R); // LR operator&(L, R); // LR operator^(L, R); // LR operator|(L, R); // L operator<<(L, R); // L operator>>(L, R); // // where LR is the result of the usual arithmetic conversions // between types L and R. void addBinaryBitwiseArithmeticOverloads(OverloadedOperatorKind Op) { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Left = FirstPromotedIntegralType; Left < LastPromotedIntegralType; ++Left) { for (unsigned Right = FirstPromotedIntegralType; Right < LastPromotedIntegralType; ++Right) { QualType LandR[2] = { ArithmeticTypes[Left], ArithmeticTypes[Right] }; S.AddBuiltinCandidate(LandR, Args, CandidateSet); } } } // C++ [over.built]p20: // // For every pair (T, VQ), where T is an enumeration or // pointer to member type and VQ is either volatile or // empty, there exist candidate operator functions of the form // // VQ T& operator=(VQ T&, T); void addAssignmentMemberPointerOrEnumeralOverloads() { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (unsigned ArgIdx = 0; ArgIdx < 2; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator Enum = CandidateTypes[ArgIdx].enumeration_begin(), EnumEnd = CandidateTypes[ArgIdx].enumeration_end(); Enum != EnumEnd; ++Enum) { if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum)).second) continue; AddBuiltinAssignmentOperatorCandidates(S, *Enum, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(), MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end(); MemPtr != MemPtrEnd; ++MemPtr) { if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)).second) continue; AddBuiltinAssignmentOperatorCandidates(S, *MemPtr, Args, CandidateSet); } } } // C++ [over.built]p19: // // For every pair (T, VQ), where T is any type and VQ is either // volatile or empty, there exist candidate operator functions // of the form // // T*VQ& operator=(T*VQ&, T*); // // C++ [over.built]p21: // // For every pair (T, VQ), where T is a cv-qualified or // cv-unqualified object type and VQ is either volatile or // empty, there exist candidate operator functions of the form // // T*VQ& operator+=(T*VQ&, ptrdiff_t); // T*VQ& operator-=(T*VQ&, ptrdiff_t); void addAssignmentPointerOverloads(bool isEqualOp) { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { // If this is operator=, keep track of the builtin candidates we added. if (isEqualOp) AddedTypes.insert(S.Context.getCanonicalType(*Ptr)); else if (!(*Ptr)->getPointeeType()->isObjectType()) continue; // non-volatile version QualType ParamTypes[2] = { S.Context.getLValueReferenceType(*Ptr), isEqualOp ? *Ptr : S.Context.getPointerDiffType(), }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/ isEqualOp); bool NeedVolatile = !(*Ptr).isVolatileQualified() && VisibleTypeConversionsQuals.hasVolatile(); if (NeedVolatile) { // volatile version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); } if (!(*Ptr).isRestrictQualified() && VisibleTypeConversionsQuals.hasRestrict()) { // restrict version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); if (NeedVolatile) { // volatile restrict version ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getCVRQualifiedType(*Ptr, (Qualifiers::Volatile | Qualifiers::Restrict))); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); } } } if (isEqualOp) { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[1].pointer_begin(), PtrEnd = CandidateTypes[1].pointer_end(); Ptr != PtrEnd; ++Ptr) { // Make sure we don't add the same candidate twice. if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second) continue; QualType ParamTypes[2] = { S.Context.getLValueReferenceType(*Ptr), *Ptr, }; // non-volatile version S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); bool NeedVolatile = !(*Ptr).isVolatileQualified() && VisibleTypeConversionsQuals.hasVolatile(); if (NeedVolatile) { // volatile version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); } if (!(*Ptr).isRestrictQualified() && VisibleTypeConversionsQuals.hasRestrict()) { // restrict version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); if (NeedVolatile) { // volatile restrict version ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getCVRQualifiedType(*Ptr, (Qualifiers::Volatile | Qualifiers::Restrict))); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); } } } } } // C++ [over.built]p18: // // For every triple (L, VQ, R), where L is an arithmetic type, // VQ is either volatile or empty, and R is a promoted // arithmetic type, there exist candidate operator functions of // the form // // VQ L& operator=(VQ L&, R); // VQ L& operator*=(VQ L&, R); // VQ L& operator/=(VQ L&, R); // VQ L& operator+=(VQ L&, R); // VQ L& operator-=(VQ L&, R); void addAssignmentArithmeticOverloads(bool isEqualOp) { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Left = 0; Left < NumArithmeticTypes; ++Left) { for (unsigned Right = FirstPromotedArithmeticType; Right < LastPromotedArithmeticType; ++Right) { QualType ParamTypes[2]; ParamTypes[1] = ArithmeticTypes[Right]; auto LeftBaseTy = AdjustAddressSpaceForBuiltinOperandType( S, ArithmeticTypes[Left], Args[0]); // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(LeftBaseTy); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { ParamTypes[0] = S.Context.getVolatileType(LeftBaseTy); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); } } } // Extension: Add the binary operators =, +=, -=, *=, /= for vector types. for (BuiltinCandidateTypeSet::iterator Vec1 = CandidateTypes[0].vector_begin(), Vec1End = CandidateTypes[0].vector_end(); Vec1 != Vec1End; ++Vec1) { for (BuiltinCandidateTypeSet::iterator Vec2 = CandidateTypes[1].vector_begin(), Vec2End = CandidateTypes[1].vector_end(); Vec2 != Vec2End; ++Vec2) { QualType ParamTypes[2]; ParamTypes[1] = *Vec2; // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(*Vec1); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { ParamTypes[0] = S.Context.getVolatileType(*Vec1); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); } } } } // C++ [over.built]p22: // // For every triple (L, VQ, R), where L is an integral type, VQ // is either volatile or empty, and R is a promoted integral // type, there exist candidate operator functions of the form // // VQ L& operator%=(VQ L&, R); // VQ L& operator<<=(VQ L&, R); // VQ L& operator>>=(VQ L&, R); // VQ L& operator&=(VQ L&, R); // VQ L& operator^=(VQ L&, R); // VQ L& operator|=(VQ L&, R); void addAssignmentIntegralOverloads() { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Left = FirstIntegralType; Left < LastIntegralType; ++Left) { for (unsigned Right = FirstPromotedIntegralType; Right < LastPromotedIntegralType; ++Right) { QualType ParamTypes[2]; ParamTypes[1] = ArithmeticTypes[Right]; auto LeftBaseTy = AdjustAddressSpaceForBuiltinOperandType( S, ArithmeticTypes[Left], Args[0]); // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(LeftBaseTy); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); if (VisibleTypeConversionsQuals.hasVolatile()) { // Add this built-in operator as a candidate (VQ is 'volatile'). ParamTypes[0] = LeftBaseTy; ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } } // C++ [over.operator]p23: // // There also exist candidate operator functions of the form // // bool operator!(bool); // bool operator&&(bool, bool); // bool operator||(bool, bool); void addExclaimOverload() { QualType ParamTy = S.Context.BoolTy; S.AddBuiltinCandidate(&ParamTy, Args, CandidateSet, /*IsAssignmentOperator=*/false, /*NumContextualBoolArguments=*/1); } void addAmpAmpOrPipePipeOverload() { QualType ParamTypes[2] = { S.Context.BoolTy, S.Context.BoolTy }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/false, /*NumContextualBoolArguments=*/2); } // C++ [over.built]p13: // // For every cv-qualified or cv-unqualified object type T there // exist candidate operator functions of the form // // T* operator+(T*, ptrdiff_t); [ABOVE] // T& operator[](T*, ptrdiff_t); // T* operator-(T*, ptrdiff_t); [ABOVE] // T* operator+(ptrdiff_t, T*); [ABOVE] // T& operator[](ptrdiff_t, T*); void addSubscriptOverloads() { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType ParamTypes[2] = { *Ptr, S.Context.getPointerDiffType() }; QualType PointeeType = (*Ptr)->getPointeeType(); if (!PointeeType->isObjectType()) continue; // T& operator[](T*, ptrdiff_t) S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[1].pointer_begin(), PtrEnd = CandidateTypes[1].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType ParamTypes[2] = { S.Context.getPointerDiffType(), *Ptr }; QualType PointeeType = (*Ptr)->getPointeeType(); if (!PointeeType->isObjectType()) continue; // T& operator[](ptrdiff_t, T*) S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } // C++ [over.built]p11: // For every quintuple (C1, C2, T, CV1, CV2), where C2 is a class type, // C1 is the same type as C2 or is a derived class of C2, T is an object // type or a function type, and CV1 and CV2 are cv-qualifier-seqs, // there exist candidate operator functions of the form // // CV12 T& operator->*(CV1 C1*, CV2 T C2::*); // // where CV12 is the union of CV1 and CV2. void addArrowStarOverloads() { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType C1Ty = (*Ptr); QualType C1; QualifierCollector Q1; C1 = QualType(Q1.strip(C1Ty->getPointeeType()), 0); if (!isa(C1)) continue; // heuristic to reduce number of builtin candidates in the set. // Add volatile/restrict version only if there are conversions to a // volatile/restrict type. if (!VisibleTypeConversionsQuals.hasVolatile() && Q1.hasVolatile()) continue; if (!VisibleTypeConversionsQuals.hasRestrict() && Q1.hasRestrict()) continue; for (BuiltinCandidateTypeSet::iterator MemPtr = CandidateTypes[1].member_pointer_begin(), MemPtrEnd = CandidateTypes[1].member_pointer_end(); MemPtr != MemPtrEnd; ++MemPtr) { const MemberPointerType *mptr = cast(*MemPtr); QualType C2 = QualType(mptr->getClass(), 0); C2 = C2.getUnqualifiedType(); if (C1 != C2 && !S.IsDerivedFrom(CandidateSet.getLocation(), C1, C2)) break; QualType ParamTypes[2] = { *Ptr, *MemPtr }; // build CV12 T& QualType T = mptr->getPointeeType(); if (!VisibleTypeConversionsQuals.hasVolatile() && T.isVolatileQualified()) continue; if (!VisibleTypeConversionsQuals.hasRestrict() && T.isRestrictQualified()) continue; T = Q1.apply(S.Context, T); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } // Note that we don't consider the first argument, since it has been // contextually converted to bool long ago. The candidates below are // therefore added as binary. // // C++ [over.built]p25: // For every type T, where T is a pointer, pointer-to-member, or scoped // enumeration type, there exist candidate operator functions of the form // // T operator?(bool, T, T); // void addConditionalOperatorOverloads() { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (unsigned ArgIdx = 0; ArgIdx < 2; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[ArgIdx].pointer_begin(), PtrEnd = CandidateTypes[ArgIdx].pointer_end(); Ptr != PtrEnd; ++Ptr) { if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second) continue; QualType ParamTypes[2] = { *Ptr, *Ptr }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(), MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end(); MemPtr != MemPtrEnd; ++MemPtr) { if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)).second) continue; QualType ParamTypes[2] = { *MemPtr, *MemPtr }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } if (S.getLangOpts().CPlusPlus11) { for (BuiltinCandidateTypeSet::iterator Enum = CandidateTypes[ArgIdx].enumeration_begin(), EnumEnd = CandidateTypes[ArgIdx].enumeration_end(); Enum != EnumEnd; ++Enum) { if (!(*Enum)->castAs()->getDecl()->isScoped()) continue; if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum)).second) continue; QualType ParamTypes[2] = { *Enum, *Enum }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } } }; } // end anonymous namespace /// AddBuiltinOperatorCandidates - Add the appropriate built-in /// operator overloads to the candidate set (C++ [over.built]), based /// on the operator @p Op and the arguments given. For example, if the /// operator is a binary '+', this routine might add "int /// operator+(int, int)" to cover integer addition. void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, SourceLocation OpLoc, ArrayRef Args, OverloadCandidateSet &CandidateSet) { // Find all of the types that the arguments can convert to, but only // if the operator we're looking at has built-in operator candidates // that make use of these types. Also record whether we encounter non-record // candidate types or either arithmetic or enumeral candidate types. Qualifiers VisibleTypeConversionsQuals; VisibleTypeConversionsQuals.addConst(); for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) VisibleTypeConversionsQuals += CollectVRQualifiers(Context, Args[ArgIdx]); bool HasNonRecordCandidateType = false; bool HasArithmeticOrEnumeralCandidateType = false; SmallVector CandidateTypes; for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { CandidateTypes.emplace_back(*this); CandidateTypes[ArgIdx].AddTypesConvertedFrom(Args[ArgIdx]->getType(), OpLoc, true, (Op == OO_Exclaim || Op == OO_AmpAmp || Op == OO_PipePipe), VisibleTypeConversionsQuals); HasNonRecordCandidateType = HasNonRecordCandidateType || CandidateTypes[ArgIdx].hasNonRecordTypes(); HasArithmeticOrEnumeralCandidateType = HasArithmeticOrEnumeralCandidateType || CandidateTypes[ArgIdx].hasArithmeticOrEnumeralTypes(); } // Exit early when no non-record types have been added to the candidate set // for any of the arguments to the operator. // // We can't exit early for !, ||, or &&, since there we have always have // 'bool' overloads. if (!HasNonRecordCandidateType && !(Op == OO_Exclaim || Op == OO_AmpAmp || Op == OO_PipePipe)) return; // Setup an object to manage the common state for building overloads. BuiltinOperatorOverloadBuilder OpBuilder(*this, Args, VisibleTypeConversionsQuals, HasArithmeticOrEnumeralCandidateType, CandidateTypes, CandidateSet); // Dispatch over the operation to add in only those overloads which apply. switch (Op) { case OO_None: case NUM_OVERLOADED_OPERATORS: llvm_unreachable("Expected an overloaded operator"); case OO_New: case OO_Delete: case OO_Array_New: case OO_Array_Delete: case OO_Call: llvm_unreachable( "Special operators don't use AddBuiltinOperatorCandidates"); case OO_Comma: case OO_Arrow: case OO_Coawait: // C++ [over.match.oper]p3: // -- For the operator ',', the unary operator '&', the // operator '->', or the operator 'co_await', the // built-in candidates set is empty. break; case OO_Plus: // '+' is either unary or binary if (Args.size() == 1) OpBuilder.addUnaryPlusPointerOverloads(); LLVM_FALLTHROUGH; case OO_Minus: // '-' is either unary or binary if (Args.size() == 1) { OpBuilder.addUnaryPlusOrMinusArithmeticOverloads(); } else { OpBuilder.addBinaryPlusOrMinusPointerOverloads(Op); OpBuilder.addGenericBinaryArithmeticOverloads(); } break; case OO_Star: // '*' is either unary or binary if (Args.size() == 1) OpBuilder.addUnaryStarPointerOverloads(); else OpBuilder.addGenericBinaryArithmeticOverloads(); break; case OO_Slash: OpBuilder.addGenericBinaryArithmeticOverloads(); break; case OO_PlusPlus: case OO_MinusMinus: OpBuilder.addPlusPlusMinusMinusArithmeticOverloads(Op); OpBuilder.addPlusPlusMinusMinusPointerOverloads(); break; case OO_EqualEqual: case OO_ExclaimEqual: OpBuilder.addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads(); LLVM_FALLTHROUGH; case OO_Less: case OO_Greater: case OO_LessEqual: case OO_GreaterEqual: OpBuilder.addGenericBinaryPointerOrEnumeralOverloads(); OpBuilder.addGenericBinaryArithmeticOverloads(); break; case OO_Spaceship: OpBuilder.addGenericBinaryPointerOrEnumeralOverloads(); OpBuilder.addThreeWayArithmeticOverloads(); break; case OO_Percent: case OO_Caret: case OO_Pipe: case OO_LessLess: case OO_GreaterGreater: OpBuilder.addBinaryBitwiseArithmeticOverloads(Op); break; case OO_Amp: // '&' is either unary or binary if (Args.size() == 1) // C++ [over.match.oper]p3: // -- For the operator ',', the unary operator '&', or the // operator '->', the built-in candidates set is empty. break; OpBuilder.addBinaryBitwiseArithmeticOverloads(Op); break; case OO_Tilde: OpBuilder.addUnaryTildePromotedIntegralOverloads(); break; case OO_Equal: OpBuilder.addAssignmentMemberPointerOrEnumeralOverloads(); LLVM_FALLTHROUGH; case OO_PlusEqual: case OO_MinusEqual: OpBuilder.addAssignmentPointerOverloads(Op == OO_Equal); LLVM_FALLTHROUGH; case OO_StarEqual: case OO_SlashEqual: OpBuilder.addAssignmentArithmeticOverloads(Op == OO_Equal); break; case OO_PercentEqual: case OO_LessLessEqual: case OO_GreaterGreaterEqual: case OO_AmpEqual: case OO_CaretEqual: case OO_PipeEqual: OpBuilder.addAssignmentIntegralOverloads(); break; case OO_Exclaim: OpBuilder.addExclaimOverload(); break; case OO_AmpAmp: case OO_PipePipe: OpBuilder.addAmpAmpOrPipePipeOverload(); break; case OO_Subscript: OpBuilder.addSubscriptOverloads(); break; case OO_ArrowStar: OpBuilder.addArrowStarOverloads(); break; case OO_Conditional: OpBuilder.addConditionalOperatorOverloads(); OpBuilder.addGenericBinaryArithmeticOverloads(); break; } } /// Add function candidates found via argument-dependent lookup /// to the set of overloading candidates. /// /// This routine performs argument-dependent name lookup based on the /// given function name (which may also be an operator name) and adds /// all of the overload candidates found by ADL to the overload /// candidate set (C++ [basic.lookup.argdep]). void Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, SourceLocation Loc, ArrayRef Args, TemplateArgumentListInfo *ExplicitTemplateArgs, OverloadCandidateSet& CandidateSet, bool PartialOverloading) { ADLResult Fns; // FIXME: This approach for uniquing ADL results (and removing // redundant candidates from the set) relies on pointer-equality, // which means we need to key off the canonical decl. However, // always going back to the canonical decl might not get us the // right set of default arguments. What default arguments are // we supposed to consider on ADL candidates, anyway? // FIXME: Pass in the explicit template arguments? ArgumentDependentLookup(Name, Loc, Args, Fns); // Erase all of the candidates we already knew about. for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(), CandEnd = CandidateSet.end(); Cand != CandEnd; ++Cand) if (Cand->Function) { Fns.erase(Cand->Function); if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate()) Fns.erase(FunTmpl); } // For each of the ADL candidates we found, add it to the overload // set. for (ADLResult::iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) { DeclAccessPair FoundDecl = DeclAccessPair::make(*I, AS_none); if (FunctionDecl *FD = dyn_cast(*I)) { if (ExplicitTemplateArgs) continue; AddOverloadCandidate( FD, FoundDecl, Args, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, /*AllowExplicit=*/true, /*AllowExplicitConversions=*/false, ADLCallKind::UsesADL); if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) { AddOverloadCandidate( FD, FoundDecl, {Args[1], Args[0]}, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, /*AllowExplicit=*/true, /*AllowExplicitConversions=*/false, ADLCallKind::UsesADL, None, OverloadCandidateParamOrder::Reversed); } } else { auto *FTD = cast(*I); AddTemplateOverloadCandidate( FTD, FoundDecl, ExplicitTemplateArgs, Args, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, /*AllowExplicit=*/true, ADLCallKind::UsesADL); if (CandidateSet.getRewriteInfo().shouldAddReversed( Context, FTD->getTemplatedDecl())) { AddTemplateOverloadCandidate( FTD, FoundDecl, ExplicitTemplateArgs, {Args[1], Args[0]}, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, /*AllowExplicit=*/true, ADLCallKind::UsesADL, OverloadCandidateParamOrder::Reversed); } } } } namespace { enum class Comparison { Equal, Better, Worse }; } /// Compares the enable_if attributes of two FunctionDecls, for the purposes of /// overload resolution. /// /// Cand1's set of enable_if attributes are said to be "better" than Cand2's iff /// Cand1's first N enable_if attributes have precisely the same conditions as /// Cand2's first N enable_if attributes (where N = the number of enable_if /// attributes on Cand2), and Cand1 has more than N enable_if attributes. /// /// Note that you can have a pair of candidates such that Cand1's enable_if /// attributes are worse than Cand2's, and Cand2's enable_if attributes are /// worse than Cand1's. static Comparison compareEnableIfAttrs(const Sema &S, const FunctionDecl *Cand1, const FunctionDecl *Cand2) { // Common case: One (or both) decls don't have enable_if attrs. bool Cand1Attr = Cand1->hasAttr(); bool Cand2Attr = Cand2->hasAttr(); if (!Cand1Attr || !Cand2Attr) { if (Cand1Attr == Cand2Attr) return Comparison::Equal; return Cand1Attr ? Comparison::Better : Comparison::Worse; } auto Cand1Attrs = Cand1->specific_attrs(); auto Cand2Attrs = Cand2->specific_attrs(); llvm::FoldingSetNodeID Cand1ID, Cand2ID; for (auto Pair : zip_longest(Cand1Attrs, Cand2Attrs)) { Optional Cand1A = std::get<0>(Pair); Optional Cand2A = std::get<1>(Pair); // It's impossible for Cand1 to be better than (or equal to) Cand2 if Cand1 // has fewer enable_if attributes than Cand2, and vice versa. if (!Cand1A) return Comparison::Worse; if (!Cand2A) return Comparison::Better; Cand1ID.clear(); Cand2ID.clear(); (*Cand1A)->getCond()->Profile(Cand1ID, S.getASTContext(), true); (*Cand2A)->getCond()->Profile(Cand2ID, S.getASTContext(), true); if (Cand1ID != Cand2ID) return Comparison::Worse; } return Comparison::Equal; } static bool isBetterMultiversionCandidate(const OverloadCandidate &Cand1, const OverloadCandidate &Cand2) { if (!Cand1.Function || !Cand1.Function->isMultiVersion() || !Cand2.Function || !Cand2.Function->isMultiVersion()) return false; // If Cand1 is invalid, it cannot be a better match, if Cand2 is invalid, this // is obviously better. if (Cand1.Function->isInvalidDecl()) return false; if (Cand2.Function->isInvalidDecl()) return true; // If this is a cpu_dispatch/cpu_specific multiversion situation, prefer // cpu_dispatch, else arbitrarily based on the identifiers. bool Cand1CPUDisp = Cand1.Function->hasAttr(); bool Cand2CPUDisp = Cand2.Function->hasAttr(); const auto *Cand1CPUSpec = Cand1.Function->getAttr(); const auto *Cand2CPUSpec = Cand2.Function->getAttr(); if (!Cand1CPUDisp && !Cand2CPUDisp && !Cand1CPUSpec && !Cand2CPUSpec) return false; if (Cand1CPUDisp && !Cand2CPUDisp) return true; if (Cand2CPUDisp && !Cand1CPUDisp) return false; if (Cand1CPUSpec && Cand2CPUSpec) { if (Cand1CPUSpec->cpus_size() != Cand2CPUSpec->cpus_size()) return Cand1CPUSpec->cpus_size() < Cand2CPUSpec->cpus_size(); std::pair FirstDiff = std::mismatch( Cand1CPUSpec->cpus_begin(), Cand1CPUSpec->cpus_end(), Cand2CPUSpec->cpus_begin(), [](const IdentifierInfo *LHS, const IdentifierInfo *RHS) { return LHS->getName() == RHS->getName(); }); assert(FirstDiff.first != Cand1CPUSpec->cpus_end() && "Two different cpu-specific versions should not have the same " "identifier list, otherwise they'd be the same decl!"); return (*FirstDiff.first)->getName() < (*FirstDiff.second)->getName(); } llvm_unreachable("No way to get here unless both had cpu_dispatch"); } /// isBetterOverloadCandidate - Determines whether the first overload /// candidate is a better candidate than the second (C++ 13.3.3p1). bool clang::isBetterOverloadCandidate( Sema &S, const OverloadCandidate &Cand1, const OverloadCandidate &Cand2, SourceLocation Loc, OverloadCandidateSet::CandidateSetKind Kind) { // Define viable functions to be better candidates than non-viable // functions. if (!Cand2.Viable) return Cand1.Viable; else if (!Cand1.Viable) return false; // C++ [over.match.best]p1: // // -- if F is a static member function, ICS1(F) is defined such // that ICS1(F) is neither better nor worse than ICS1(G) for // any function G, and, symmetrically, ICS1(G) is neither // better nor worse than ICS1(F). unsigned StartArg = 0; if (Cand1.IgnoreObjectArgument || Cand2.IgnoreObjectArgument) StartArg = 1; auto IsIllFormedConversion = [&](const ImplicitConversionSequence &ICS) { // We don't allow incompatible pointer conversions in C++. if (!S.getLangOpts().CPlusPlus) return ICS.isStandard() && ICS.Standard.Second == ICK_Incompatible_Pointer_Conversion; // The only ill-formed conversion we allow in C++ is the string literal to // char* conversion, which is only considered ill-formed after C++11. return S.getLangOpts().CPlusPlus11 && !S.getLangOpts().WritableStrings && hasDeprecatedStringLiteralToCharPtrConversion(ICS); }; // Define functions that don't require ill-formed conversions for a given // argument to be better candidates than functions that do. unsigned NumArgs = Cand1.Conversions.size(); assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch"); bool HasBetterConversion = false; for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) { bool Cand1Bad = IsIllFormedConversion(Cand1.Conversions[ArgIdx]); bool Cand2Bad = IsIllFormedConversion(Cand2.Conversions[ArgIdx]); if (Cand1Bad != Cand2Bad) { if (Cand1Bad) return false; HasBetterConversion = true; } } if (HasBetterConversion) return true; // C++ [over.match.best]p1: // A viable function F1 is defined to be a better function than another // viable function F2 if for all arguments i, ICSi(F1) is not a worse // conversion sequence than ICSi(F2), and then... bool HasWorseConversion = false; for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) { switch (CompareImplicitConversionSequences(S, Loc, Cand1.Conversions[ArgIdx], Cand2.Conversions[ArgIdx])) { case ImplicitConversionSequence::Better: // Cand1 has a better conversion sequence. HasBetterConversion = true; break; case ImplicitConversionSequence::Worse: if (Cand1.Function && Cand1.Function == Cand2.Function && (Cand2.RewriteKind & CRK_Reversed) != 0) { // Work around large-scale breakage caused by considering reversed // forms of operator== in C++20: // // When comparing a function against its reversed form, if we have a // better conversion for one argument and a worse conversion for the // other, we prefer the non-reversed form. // // This prevents a conversion function from being considered ambiguous // with its own reversed form in various where it's only incidentally // heterogeneous. // // We diagnose this as an extension from CreateOverloadedBinOp. HasWorseConversion = true; break; } // Cand1 can't be better than Cand2. return false; case ImplicitConversionSequence::Indistinguishable: // Do nothing. break; } } // -- for some argument j, ICSj(F1) is a better conversion sequence than // ICSj(F2), or, if not that, if (HasBetterConversion) return true; if (HasWorseConversion) return false; // -- the context is an initialization by user-defined conversion // (see 8.5, 13.3.1.5) and the standard conversion sequence // from the return type of F1 to the destination type (i.e., // the type of the entity being initialized) is a better // conversion sequence than the standard conversion sequence // from the return type of F2 to the destination type. if (Kind == OverloadCandidateSet::CSK_InitByUserDefinedConversion && Cand1.Function && Cand2.Function && isa(Cand1.Function) && isa(Cand2.Function)) { // First check whether we prefer one of the conversion functions over the // other. This only distinguishes the results in non-standard, extension // cases such as the conversion from a lambda closure type to a function // pointer or block. ImplicitConversionSequence::CompareKind Result = compareConversionFunctions(S, Cand1.Function, Cand2.Function); if (Result == ImplicitConversionSequence::Indistinguishable) Result = CompareStandardConversionSequences(S, Loc, Cand1.FinalConversion, Cand2.FinalConversion); if (Result != ImplicitConversionSequence::Indistinguishable) return Result == ImplicitConversionSequence::Better; // FIXME: Compare kind of reference binding if conversion functions // convert to a reference type used in direct reference binding, per // C++14 [over.match.best]p1 section 2 bullet 3. } // FIXME: Work around a defect in the C++17 guaranteed copy elision wording, // as combined with the resolution to CWG issue 243. // // When the context is initialization by constructor ([over.match.ctor] or // either phase of [over.match.list]), a constructor is preferred over // a conversion function. if (Kind == OverloadCandidateSet::CSK_InitByConstructor && NumArgs == 1 && Cand1.Function && Cand2.Function && isa(Cand1.Function) != isa(Cand2.Function)) return isa(Cand1.Function); // -- F1 is a non-template function and F2 is a function template // specialization, or, if not that, bool Cand1IsSpecialization = Cand1.Function && Cand1.Function->getPrimaryTemplate(); bool Cand2IsSpecialization = Cand2.Function && Cand2.Function->getPrimaryTemplate(); if (Cand1IsSpecialization != Cand2IsSpecialization) return Cand2IsSpecialization; // -- F1 and F2 are function template specializations, and the function // template for F1 is more specialized than the template for F2 // according to the partial ordering rules described in 14.5.5.2, or, // if not that, if (Cand1IsSpecialization && Cand2IsSpecialization) { if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(), Cand2.Function->getPrimaryTemplate(), Loc, isa(Cand1.Function)? TPOC_Conversion : TPOC_Call, Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments)) return BetterTemplate == Cand1.Function->getPrimaryTemplate(); } // -— F1 and F2 are non-template functions with the same // parameter-type-lists, and F1 is more constrained than F2 [...], if (Cand1.Function && Cand2.Function && !Cand1IsSpecialization && !Cand2IsSpecialization && Cand1.Function->hasPrototype() && Cand2.Function->hasPrototype()) { auto *PT1 = cast(Cand1.Function->getFunctionType()); auto *PT2 = cast(Cand2.Function->getFunctionType()); if (PT1->getNumParams() == PT2->getNumParams() && PT1->isVariadic() == PT2->isVariadic() && S.FunctionParamTypesAreEqual(PT1, PT2)) { Expr *RC1 = Cand1.Function->getTrailingRequiresClause(); Expr *RC2 = Cand2.Function->getTrailingRequiresClause(); if (RC1 && RC2) { bool AtLeastAsConstrained1, AtLeastAsConstrained2; if (S.IsAtLeastAsConstrained(Cand1.Function, {RC1}, Cand2.Function, {RC2}, AtLeastAsConstrained1) || S.IsAtLeastAsConstrained(Cand2.Function, {RC2}, Cand1.Function, {RC1}, AtLeastAsConstrained2)) return false; if (AtLeastAsConstrained1 != AtLeastAsConstrained2) return AtLeastAsConstrained1; } else if (RC1 || RC2) { return RC1 != nullptr; } } } // -- F1 is a constructor for a class D, F2 is a constructor for a base // class B of D, and for all arguments the corresponding parameters of // F1 and F2 have the same type. // FIXME: Implement the "all parameters have the same type" check. bool Cand1IsInherited = dyn_cast_or_null(Cand1.FoundDecl.getDecl()); bool Cand2IsInherited = dyn_cast_or_null(Cand2.FoundDecl.getDecl()); if (Cand1IsInherited != Cand2IsInherited) return Cand2IsInherited; else if (Cand1IsInherited) { assert(Cand2IsInherited); auto *Cand1Class = cast(Cand1.Function->getDeclContext()); auto *Cand2Class = cast(Cand2.Function->getDeclContext()); if (Cand1Class->isDerivedFrom(Cand2Class)) return true; if (Cand2Class->isDerivedFrom(Cand1Class)) return false; // Inherited from sibling base classes: still ambiguous. } // -- F2 is a rewritten candidate (12.4.1.2) and F1 is not // -- F1 and F2 are rewritten candidates, and F2 is a synthesized candidate // with reversed order of parameters and F1 is not // // We rank reversed + different operator as worse than just reversed, but // that comparison can never happen, because we only consider reversing for // the maximally-rewritten operator (== or <=>). if (Cand1.RewriteKind != Cand2.RewriteKind) return Cand1.RewriteKind < Cand2.RewriteKind; // Check C++17 tie-breakers for deduction guides. { auto *Guide1 = dyn_cast_or_null(Cand1.Function); auto *Guide2 = dyn_cast_or_null(Cand2.Function); if (Guide1 && Guide2) { // -- F1 is generated from a deduction-guide and F2 is not if (Guide1->isImplicit() != Guide2->isImplicit()) return Guide2->isImplicit(); // -- F1 is the copy deduction candidate(16.3.1.8) and F2 is not if (Guide1->isCopyDeductionCandidate()) return true; } } // Check for enable_if value-based overload resolution. if (Cand1.Function && Cand2.Function) { Comparison Cmp = compareEnableIfAttrs(S, Cand1.Function, Cand2.Function); if (Cmp != Comparison::Equal) return Cmp == Comparison::Better; } if (S.getLangOpts().CUDA && Cand1.Function && Cand2.Function) { FunctionDecl *Caller = dyn_cast(S.CurContext); return S.IdentifyCUDAPreference(Caller, Cand1.Function) > S.IdentifyCUDAPreference(Caller, Cand2.Function); } bool HasPS1 = Cand1.Function != nullptr && functionHasPassObjectSizeParams(Cand1.Function); bool HasPS2 = Cand2.Function != nullptr && functionHasPassObjectSizeParams(Cand2.Function); if (HasPS1 != HasPS2 && HasPS1) return true; return isBetterMultiversionCandidate(Cand1, Cand2); } /// Determine whether two declarations are "equivalent" for the purposes of /// name lookup and overload resolution. This applies when the same internal/no /// linkage entity is defined by two modules (probably by textually including /// the same header). In such a case, we don't consider the declarations to /// declare the same entity, but we also don't want lookups with both /// declarations visible to be ambiguous in some cases (this happens when using /// a modularized libstdc++). bool Sema::isEquivalentInternalLinkageDeclaration(const NamedDecl *A, const NamedDecl *B) { auto *VA = dyn_cast_or_null(A); auto *VB = dyn_cast_or_null(B); if (!VA || !VB) return false; // The declarations must be declaring the same name as an internal linkage // entity in different modules. if (!VA->getDeclContext()->getRedeclContext()->Equals( VB->getDeclContext()->getRedeclContext()) || getOwningModule(VA) == getOwningModule(VB) || VA->isExternallyVisible() || VB->isExternallyVisible()) return false; // Check that the declarations appear to be equivalent. // // FIXME: Checking the type isn't really enough to resolve the ambiguity. // For constants and functions, we should check the initializer or body is // the same. For non-constant variables, we shouldn't allow it at all. if (Context.hasSameType(VA->getType(), VB->getType())) return true; // Enum constants within unnamed enumerations will have different types, but // may still be similar enough to be interchangeable for our purposes. if (auto *EA = dyn_cast(VA)) { if (auto *EB = dyn_cast(VB)) { // Only handle anonymous enums. If the enumerations were named and // equivalent, they would have been merged to the same type. auto *EnumA = cast(EA->getDeclContext()); auto *EnumB = cast(EB->getDeclContext()); if (EnumA->hasNameForLinkage() || EnumB->hasNameForLinkage() || !Context.hasSameType(EnumA->getIntegerType(), EnumB->getIntegerType())) return false; // Allow this only if the value is the same for both enumerators. return llvm::APSInt::isSameValue(EA->getInitVal(), EB->getInitVal()); } } // Nothing else is sufficiently similar. return false; } void Sema::diagnoseEquivalentInternalLinkageDeclarations( SourceLocation Loc, const NamedDecl *D, ArrayRef Equiv) { Diag(Loc, diag::ext_equivalent_internal_linkage_decl_in_modules) << D; Module *M = getOwningModule(D); Diag(D->getLocation(), diag::note_equivalent_internal_linkage_decl) << !M << (M ? M->getFullModuleName() : ""); for (auto *E : Equiv) { Module *M = getOwningModule(E); Diag(E->getLocation(), diag::note_equivalent_internal_linkage_decl) << !M << (M ? M->getFullModuleName() : ""); } } /// Computes the best viable function (C++ 13.3.3) /// within an overload candidate set. /// /// \param Loc The location of the function name (or operator symbol) for /// which overload resolution occurs. /// /// \param Best If overload resolution was successful or found a deleted /// function, \p Best points to the candidate function found. /// /// \returns The result of overload resolution. OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, iterator &Best) { llvm::SmallVector Candidates; std::transform(begin(), end(), std::back_inserter(Candidates), [](OverloadCandidate &Cand) { return &Cand; }); // [CUDA] HD->H or HD->D calls are technically not allowed by CUDA but // are accepted by both clang and NVCC. However, during a particular // compilation mode only one call variant is viable. We need to // exclude non-viable overload candidates from consideration based // only on their host/device attributes. Specifically, if one // candidate call is WrongSide and the other is SameSide, we ignore // the WrongSide candidate. if (S.getLangOpts().CUDA) { const FunctionDecl *Caller = dyn_cast(S.CurContext); bool ContainsSameSideCandidate = llvm::any_of(Candidates, [&](OverloadCandidate *Cand) { // Check viable function only. return Cand->Viable && Cand->Function && S.IdentifyCUDAPreference(Caller, Cand->Function) == Sema::CFP_SameSide; }); if (ContainsSameSideCandidate) { auto IsWrongSideCandidate = [&](OverloadCandidate *Cand) { // Check viable function only to avoid unnecessary data copying/moving. return Cand->Viable && Cand->Function && S.IdentifyCUDAPreference(Caller, Cand->Function) == Sema::CFP_WrongSide; }; llvm::erase_if(Candidates, IsWrongSideCandidate); } } // Find the best viable function. Best = end(); for (auto *Cand : Candidates) { Cand->Best = false; if (Cand->Viable) if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc, Kind)) Best = Cand; } // If we didn't find any viable functions, abort. if (Best == end()) return OR_No_Viable_Function; llvm::SmallVector EquivalentCands; llvm::SmallVector PendingBest; PendingBest.push_back(&*Best); Best->Best = true; // Make sure that this function is better than every other viable // function. If not, we have an ambiguity. while (!PendingBest.empty()) { auto *Curr = PendingBest.pop_back_val(); for (auto *Cand : Candidates) { if (Cand->Viable && !Cand->Best && !isBetterOverloadCandidate(S, *Curr, *Cand, Loc, Kind)) { PendingBest.push_back(Cand); Cand->Best = true; if (S.isEquivalentInternalLinkageDeclaration(Cand->Function, Curr->Function)) EquivalentCands.push_back(Cand->Function); else Best = end(); } } } // If we found more than one best candidate, this is ambiguous. if (Best == end()) return OR_Ambiguous; // Best is the best viable function. if (Best->Function && Best->Function->isDeleted()) return OR_Deleted; if (!EquivalentCands.empty()) S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function, EquivalentCands); return OR_Success; } namespace { enum OverloadCandidateKind { oc_function, oc_method, oc_reversed_binary_operator, oc_constructor, oc_implicit_default_constructor, oc_implicit_copy_constructor, oc_implicit_move_constructor, oc_implicit_copy_assignment, oc_implicit_move_assignment, oc_implicit_equality_comparison, oc_inherited_constructor }; enum OverloadCandidateSelect { ocs_non_template, ocs_template, ocs_described_template, }; static std::pair ClassifyOverloadCandidate(Sema &S, NamedDecl *Found, FunctionDecl *Fn, OverloadCandidateRewriteKind CRK, std::string &Description) { bool isTemplate = Fn->isTemplateDecl() || Found->isTemplateDecl(); if (FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate()) { isTemplate = true; Description = S.getTemplateArgumentBindingsText( FunTmpl->getTemplateParameters(), *Fn->getTemplateSpecializationArgs()); } OverloadCandidateSelect Select = [&]() { if (!Description.empty()) return ocs_described_template; return isTemplate ? ocs_template : ocs_non_template; }(); OverloadCandidateKind Kind = [&]() { if (Fn->isImplicit() && Fn->getOverloadedOperator() == OO_EqualEqual) return oc_implicit_equality_comparison; if (CRK & CRK_Reversed) return oc_reversed_binary_operator; if (CXXConstructorDecl *Ctor = dyn_cast(Fn)) { if (!Ctor->isImplicit()) { if (isa(Found)) return oc_inherited_constructor; else return oc_constructor; } if (Ctor->isDefaultConstructor()) return oc_implicit_default_constructor; if (Ctor->isMoveConstructor()) return oc_implicit_move_constructor; assert(Ctor->isCopyConstructor() && "unexpected sort of implicit constructor"); return oc_implicit_copy_constructor; } if (CXXMethodDecl *Meth = dyn_cast(Fn)) { // This actually gets spelled 'candidate function' for now, but // it doesn't hurt to split it out. if (!Meth->isImplicit()) return oc_method; if (Meth->isMoveAssignmentOperator()) return oc_implicit_move_assignment; if (Meth->isCopyAssignmentOperator()) return oc_implicit_copy_assignment; assert(isa(Meth) && "expected conversion"); return oc_method; } return oc_function; }(); return std::make_pair(Kind, Select); } void MaybeEmitInheritedConstructorNote(Sema &S, Decl *FoundDecl) { // FIXME: It'd be nice to only emit a note once per using-decl per overload // set. if (auto *Shadow = dyn_cast(FoundDecl)) S.Diag(FoundDecl->getLocation(), diag::note_ovl_candidate_inherited_constructor) << Shadow->getNominatedBaseClass(); } } // end anonymous namespace static bool isFunctionAlwaysEnabled(const ASTContext &Ctx, const FunctionDecl *FD) { for (auto *EnableIf : FD->specific_attrs()) { bool AlwaysTrue; if (EnableIf->getCond()->isValueDependent() || !EnableIf->getCond()->EvaluateAsBooleanCondition(AlwaysTrue, Ctx)) return false; if (!AlwaysTrue) return false; } return true; } /// Returns true if we can take the address of the function. /// /// \param Complain - If true, we'll emit a diagnostic /// \param InOverloadResolution - For the purposes of emitting a diagnostic, are /// we in overload resolution? /// \param Loc - The location of the statement we're complaining about. Ignored /// if we're not complaining, or if we're in overload resolution. static bool checkAddressOfFunctionIsAvailable(Sema &S, const FunctionDecl *FD, bool Complain, bool InOverloadResolution, SourceLocation Loc) { if (!isFunctionAlwaysEnabled(S.Context, FD)) { if (Complain) { if (InOverloadResolution) S.Diag(FD->getBeginLoc(), diag::note_addrof_ovl_candidate_disabled_by_enable_if_attr); else S.Diag(Loc, diag::err_addrof_function_disabled_by_enable_if_attr) << FD; } return false; } if (FD->getTrailingRequiresClause()) { ConstraintSatisfaction Satisfaction; if (S.CheckFunctionConstraints(FD, Satisfaction, Loc)) return false; if (!Satisfaction.IsSatisfied) { if (Complain) { if (InOverloadResolution) S.Diag(FD->getBeginLoc(), diag::note_ovl_candidate_unsatisfied_constraints); else S.Diag(Loc, diag::err_addrof_function_constraints_not_satisfied) << FD; S.DiagnoseUnsatisfiedConstraint(Satisfaction); } return false; } } auto I = llvm::find_if(FD->parameters(), [](const ParmVarDecl *P) { return P->hasAttr(); }); if (I == FD->param_end()) return true; if (Complain) { // Add one to ParamNo because it's user-facing unsigned ParamNo = std::distance(FD->param_begin(), I) + 1; if (InOverloadResolution) S.Diag(FD->getLocation(), diag::note_ovl_candidate_has_pass_object_size_params) << ParamNo; else S.Diag(Loc, diag::err_address_of_function_with_pass_object_size_params) << FD << ParamNo; } return false; } static bool checkAddressOfCandidateIsAvailable(Sema &S, const FunctionDecl *FD) { return checkAddressOfFunctionIsAvailable(S, FD, /*Complain=*/true, /*InOverloadResolution=*/true, /*Loc=*/SourceLocation()); } bool Sema::checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain, SourceLocation Loc) { return ::checkAddressOfFunctionIsAvailable(*this, Function, Complain, /*InOverloadResolution=*/false, Loc); } // Notes the location of an overload candidate. void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn, OverloadCandidateRewriteKind RewriteKind, QualType DestType, bool TakingAddress) { if (TakingAddress && !checkAddressOfCandidateIsAvailable(*this, Fn)) return; if (Fn->isMultiVersion() && Fn->hasAttr() && !Fn->getAttr()->isDefaultVersion()) return; std::string FnDesc; std::pair KSPair = ClassifyOverloadCandidate(*this, Found, Fn, RewriteKind, FnDesc); PartialDiagnostic PD = PDiag(diag::note_ovl_candidate) << (unsigned)KSPair.first << (unsigned)KSPair.second << Fn << FnDesc; HandleFunctionTypeMismatch(PD, Fn->getType(), DestType); Diag(Fn->getLocation(), PD); MaybeEmitInheritedConstructorNote(*this, Found); } static void MaybeDiagnoseAmbiguousConstraints(Sema &S, ArrayRef Cands) { // Perhaps the ambiguity was caused by two atomic constraints that are // 'identical' but not equivalent: // // void foo() requires (sizeof(T) > 4) { } // #1 // void foo() requires (sizeof(T) > 4) && T::value { } // #2 // // The 'sizeof(T) > 4' constraints are seemingly equivalent and should cause // #2 to subsume #1, but these constraint are not considered equivalent // according to the subsumption rules because they are not the same // source-level construct. This behavior is quite confusing and we should try // to help the user figure out what happened. SmallVector FirstAC, SecondAC; FunctionDecl *FirstCand = nullptr, *SecondCand = nullptr; for (auto I = Cands.begin(), E = Cands.end(); I != E; ++I) { if (!I->Function) continue; SmallVector AC; if (auto *Template = I->Function->getPrimaryTemplate()) Template->getAssociatedConstraints(AC); else I->Function->getAssociatedConstraints(AC); if (AC.empty()) continue; if (FirstCand == nullptr) { FirstCand = I->Function; FirstAC = AC; } else if (SecondCand == nullptr) { SecondCand = I->Function; SecondAC = AC; } else { // We have more than one pair of constrained functions - this check is // expensive and we'd rather not try to diagnose it. return; } } if (!SecondCand) return; // The diagnostic can only happen if there are associated constraints on // both sides (there needs to be some identical atomic constraint). if (S.MaybeEmitAmbiguousAtomicConstraintsDiagnostic(FirstCand, FirstAC, SecondCand, SecondAC)) // Just show the user one diagnostic, they'll probably figure it out // from here. return; } // Notes the location of all overload candidates designated through // OverloadedExpr void Sema::NoteAllOverloadCandidates(Expr *OverloadedExpr, QualType DestType, bool TakingAddress) { assert(OverloadedExpr->getType() == Context.OverloadTy); OverloadExpr::FindResult Ovl = OverloadExpr::find(OverloadedExpr); OverloadExpr *OvlExpr = Ovl.Expression; for (UnresolvedSetIterator I = OvlExpr->decls_begin(), IEnd = OvlExpr->decls_end(); I != IEnd; ++I) { if (FunctionTemplateDecl *FunTmpl = dyn_cast((*I)->getUnderlyingDecl()) ) { NoteOverloadCandidate(*I, FunTmpl->getTemplatedDecl(), CRK_None, DestType, TakingAddress); } else if (FunctionDecl *Fun = dyn_cast((*I)->getUnderlyingDecl()) ) { NoteOverloadCandidate(*I, Fun, CRK_None, DestType, TakingAddress); } } } /// Diagnoses an ambiguous conversion. The partial diagnostic is the /// "lead" diagnostic; it will be given two arguments, the source and /// target types of the conversion. void ImplicitConversionSequence::DiagnoseAmbiguousConversion( Sema &S, SourceLocation CaretLoc, const PartialDiagnostic &PDiag) const { S.Diag(CaretLoc, PDiag) << Ambiguous.getFromType() << Ambiguous.getToType(); // FIXME: The note limiting machinery is borrowed from // OverloadCandidateSet::NoteCandidates; there's an opportunity for // refactoring here. const OverloadsShown ShowOverloads = S.Diags.getShowOverloads(); unsigned CandsShown = 0; AmbiguousConversionSequence::const_iterator I, E; for (I = Ambiguous.begin(), E = Ambiguous.end(); I != E; ++I) { if (CandsShown >= 4 && ShowOverloads == Ovl_Best) break; ++CandsShown; S.NoteOverloadCandidate(I->first, I->second); } if (I != E) S.Diag(SourceLocation(), diag::note_ovl_too_many_candidates) << int(E - I); } static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I, bool TakingCandidateAddress) { const ImplicitConversionSequence &Conv = Cand->Conversions[I]; assert(Conv.isBad()); assert(Cand->Function && "for now, candidate must be a function"); FunctionDecl *Fn = Cand->Function; // There's a conversion slot for the object argument if this is a // non-constructor method. Note that 'I' corresponds the // conversion-slot index. bool isObjectArgument = false; if (isa(Fn) && !isa(Fn)) { if (I == 0) isObjectArgument = true; else I--; } std::string FnDesc; std::pair FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, Cand->getRewriteKind(), FnDesc); Expr *FromExpr = Conv.Bad.FromExpr; QualType FromTy = Conv.Bad.getFromType(); QualType ToTy = Conv.Bad.getToType(); if (FromTy == S.Context.OverloadTy) { assert(FromExpr && "overload set argument came from implicit argument?"); Expr *E = FromExpr->IgnoreParens(); if (isa(E)) E = cast(E)->getSubExpr()->IgnoreParens(); DeclarationName Name = cast(E)->getName(); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_overload) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << ToTy << Name << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // Do some hand-waving analysis to see if the non-viability is due // to a qualifier mismatch. CanQualType CFromTy = S.Context.getCanonicalType(FromTy); CanQualType CToTy = S.Context.getCanonicalType(ToTy); if (CanQual RT = CToTy->getAs()) CToTy = RT->getPointeeType(); else { // TODO: detect and diagnose the full richness of const mismatches. if (CanQual FromPT = CFromTy->getAs()) if (CanQual ToPT = CToTy->getAs()) { CFromTy = FromPT->getPointeeType(); CToTy = ToPT->getPointeeType(); } } if (CToTy.getUnqualifiedType() == CFromTy.getUnqualifiedType() && !CToTy.isAtLeastAsQualifiedAs(CFromTy)) { Qualifiers FromQs = CFromTy.getQualifiers(); Qualifiers ToQs = CToTy.getQualifiers(); if (FromQs.getAddressSpace() != ToQs.getAddressSpace()) { if (isObjectArgument) S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_addrspace_this) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromQs.getAddressSpace() << ToQs.getAddressSpace(); else S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_addrspace) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromQs.getAddressSpace() << ToQs.getAddressSpace() << ToTy->isReferenceType() << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (FromQs.getObjCLifetime() != ToQs.getObjCLifetime()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_ownership) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << FromQs.getObjCLifetime() << ToQs.getObjCLifetime() << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (FromQs.getObjCGCAttr() != ToQs.getObjCGCAttr()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_gc) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << FromQs.getObjCGCAttr() << ToQs.getObjCGCAttr() << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (FromQs.hasUnaligned() != ToQs.hasUnaligned()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_unaligned) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << FromQs.hasUnaligned() << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } unsigned CVR = FromQs.getCVRQualifiers() & ~ToQs.getCVRQualifiers(); assert(CVR && "unexpected qualifiers mismatch"); if (isObjectArgument) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_cvr_this) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << (CVR - 1); } else { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_cvr) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << (CVR - 1) << I + 1; } MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // Special diagnostic for failure to convert an initializer list, since // telling the user that it has type void is not useful. if (FromExpr && isa(FromExpr)) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_list_argument) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << ToTy << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // Diagnose references or pointers to incomplete types differently, // since it's far from impossible that the incompleteness triggered // the failure. QualType TempFromTy = FromTy.getNonReferenceType(); if (const PointerType *PTy = TempFromTy->getAs()) TempFromTy = PTy->getPointeeType(); if (TempFromTy->isIncompleteType()) { // Emit the generic diagnostic and, optionally, add the hints to it. S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << ToTy << (unsigned)isObjectArgument << I + 1 << (unsigned)(Cand->Fix.Kind); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // Diagnose base -> derived pointer conversions. unsigned BaseToDerivedConversion = 0; if (const PointerType *FromPtrTy = FromTy->getAs()) { if (const PointerType *ToPtrTy = ToTy->getAs()) { if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs( FromPtrTy->getPointeeType()) && !FromPtrTy->getPointeeType()->isIncompleteType() && !ToPtrTy->getPointeeType()->isIncompleteType() && S.IsDerivedFrom(SourceLocation(), ToPtrTy->getPointeeType(), FromPtrTy->getPointeeType())) BaseToDerivedConversion = 1; } } else if (const ObjCObjectPointerType *FromPtrTy = FromTy->getAs()) { if (const ObjCObjectPointerType *ToPtrTy = ToTy->getAs()) if (const ObjCInterfaceDecl *FromIface = FromPtrTy->getInterfaceDecl()) if (const ObjCInterfaceDecl *ToIface = ToPtrTy->getInterfaceDecl()) if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs( FromPtrTy->getPointeeType()) && FromIface->isSuperClassOf(ToIface)) BaseToDerivedConversion = 2; } else if (const ReferenceType *ToRefTy = ToTy->getAs()) { if (ToRefTy->getPointeeType().isAtLeastAsQualifiedAs(FromTy) && !FromTy->isIncompleteType() && !ToRefTy->getPointeeType()->isIncompleteType() && S.IsDerivedFrom(SourceLocation(), ToRefTy->getPointeeType(), FromTy)) { BaseToDerivedConversion = 3; } else if (ToTy->isLValueReferenceType() && !FromExpr->isLValue() && ToTy.getNonReferenceType().getCanonicalType() == FromTy.getNonReferenceType().getCanonicalType()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_lvalue) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (unsigned)isObjectArgument << I + 1 << (FromExpr ? FromExpr->getSourceRange() : SourceRange()); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } } if (BaseToDerivedConversion) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_base_to_derived_conv) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << (BaseToDerivedConversion - 1) << FromTy << ToTy << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (isa(CFromTy) && isa(CToTy)) { Qualifiers FromQs = CFromTy.getQualifiers(); Qualifiers ToQs = CToTy.getQualifiers(); if (FromQs.getObjCLifetime() != ToQs.getObjCLifetime()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_arc_conv) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << ToTy << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } } if (TakingCandidateAddress && !checkAddressOfCandidateIsAvailable(S, Cand->Function)) return; // Emit the generic diagnostic and, optionally, add the hints to it. PartialDiagnostic FDiag = S.PDiag(diag::note_ovl_candidate_bad_conv); FDiag << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << ToTy << (unsigned)isObjectArgument << I + 1 << (unsigned)(Cand->Fix.Kind); // If we can fix the conversion, suggest the FixIts. for (std::vector::iterator HI = Cand->Fix.Hints.begin(), HE = Cand->Fix.Hints.end(); HI != HE; ++HI) FDiag << *HI; S.Diag(Fn->getLocation(), FDiag); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); } /// Additional arity mismatch diagnosis specific to a function overload /// candidates. This is not covered by the more general DiagnoseArityMismatch() /// over a candidate in any candidate set. static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand, unsigned NumArgs) { FunctionDecl *Fn = Cand->Function; unsigned MinParams = Fn->getMinRequiredArguments(); // With invalid overloaded operators, it's possible that we think we // have an arity mismatch when in fact it looks like we have the // right number of arguments, because only overloaded operators have // the weird behavior of overloading member and non-member functions. // Just don't report anything. if (Fn->isInvalidDecl() && Fn->getDeclName().getNameKind() == DeclarationName::CXXOperatorName) return true; if (NumArgs < MinParams) { assert((Cand->FailureKind == ovl_fail_too_few_arguments) || (Cand->FailureKind == ovl_fail_bad_deduction && Cand->DeductionFailure.Result == Sema::TDK_TooFewArguments)); } else { assert((Cand->FailureKind == ovl_fail_too_many_arguments) || (Cand->FailureKind == ovl_fail_bad_deduction && Cand->DeductionFailure.Result == Sema::TDK_TooManyArguments)); } return false; } /// General arity mismatch diagnosis over a candidate in a candidate set. static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D, unsigned NumFormalArgs) { assert(isa(D) && "The templated declaration should at least be a function" " when diagnosing bad template argument deduction due to too many" " or too few arguments"); FunctionDecl *Fn = cast(D); // TODO: treat calls to a missing default constructor as a special case const auto *FnTy = Fn->getType()->castAs(); unsigned MinParams = Fn->getMinRequiredArguments(); // at least / at most / exactly unsigned mode, modeCount; if (NumFormalArgs < MinParams) { if (MinParams != FnTy->getNumParams() || FnTy->isVariadic() || FnTy->isTemplateVariadic()) mode = 0; // "at least" else mode = 2; // "exactly" modeCount = MinParams; } else { if (MinParams != FnTy->getNumParams()) mode = 1; // "at most" else mode = 2; // "exactly" modeCount = FnTy->getNumParams(); } std::string Description; std::pair FnKindPair = ClassifyOverloadCandidate(S, Found, Fn, CRK_None, Description); if (modeCount == 1 && Fn->getParamDecl(0)->getDeclName()) S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity_one) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << Description << mode << Fn->getParamDecl(0) << NumFormalArgs; else S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << Description << mode << modeCount << NumFormalArgs; MaybeEmitInheritedConstructorNote(S, Found); } /// Arity mismatch diagnosis specific to a function overload candidate. static void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand, unsigned NumFormalArgs) { if (!CheckArityMismatch(S, Cand, NumFormalArgs)) DiagnoseArityMismatch(S, Cand->FoundDecl, Cand->Function, NumFormalArgs); } static TemplateDecl *getDescribedTemplate(Decl *Templated) { if (TemplateDecl *TD = Templated->getDescribedTemplate()) return TD; llvm_unreachable("Unsupported: Getting the described template declaration" " for bad deduction diagnosis"); } /// Diagnose a failed template-argument deduction. static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, DeductionFailureInfo &DeductionFailure, unsigned NumArgs, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); NamedDecl *ParamD; (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()); switch (DeductionFailure.Result) { case Sema::TDK_Success: llvm_unreachable("TDK_success while diagnosing bad deduction"); case Sema::TDK_Incomplete: { assert(ParamD && "no parameter found for incomplete deduction result"); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_incomplete_deduction) << ParamD->getDeclName(); MaybeEmitInheritedConstructorNote(S, Found); return; } case Sema::TDK_IncompletePack: { assert(ParamD && "no parameter found for incomplete deduction result"); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_incomplete_deduction_pack) << ParamD->getDeclName() << (DeductionFailure.getFirstArg()->pack_size() + 1) << *DeductionFailure.getFirstArg(); MaybeEmitInheritedConstructorNote(S, Found); return; } case Sema::TDK_Underqualified: { assert(ParamD && "no parameter found for bad qualifiers deduction result"); TemplateTypeParmDecl *TParam = cast(ParamD); QualType Param = DeductionFailure.getFirstArg()->getAsType(); // Param will have been canonicalized, but it should just be a // qualified version of ParamD, so move the qualifiers to that. QualifierCollector Qs; Qs.strip(Param); QualType NonCanonParam = Qs.apply(S.Context, TParam->getTypeForDecl()); assert(S.Context.hasSameType(Param, NonCanonParam)); // Arg has also been canonicalized, but there's nothing we can do // about that. It also doesn't matter as much, because it won't // have any template parameters in it (because deduction isn't // done on dependent types). QualType Arg = DeductionFailure.getSecondArg()->getAsType(); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_underqualified) << ParamD->getDeclName() << Arg << NonCanonParam; MaybeEmitInheritedConstructorNote(S, Found); return; } case Sema::TDK_Inconsistent: { assert(ParamD && "no parameter found for inconsistent deduction result"); int which = 0; if (isa(ParamD)) which = 0; else if (isa(ParamD)) { // Deduction might have failed because we deduced arguments of two // different types for a non-type template parameter. // FIXME: Use a different TDK value for this. QualType T1 = DeductionFailure.getFirstArg()->getNonTypeTemplateArgumentType(); QualType T2 = DeductionFailure.getSecondArg()->getNonTypeTemplateArgumentType(); if (!T1.isNull() && !T2.isNull() && !S.Context.hasSameType(T1, T2)) { S.Diag(Templated->getLocation(), diag::note_ovl_candidate_inconsistent_deduction_types) << ParamD->getDeclName() << *DeductionFailure.getFirstArg() << T1 << *DeductionFailure.getSecondArg() << T2; MaybeEmitInheritedConstructorNote(S, Found); return; } which = 1; } else { which = 2; } // Tweak the diagnostic if the problem is that we deduced packs of // different arities. We'll print the actual packs anyway in case that // includes additional useful information. if (DeductionFailure.getFirstArg()->getKind() == TemplateArgument::Pack && DeductionFailure.getSecondArg()->getKind() == TemplateArgument::Pack && DeductionFailure.getFirstArg()->pack_size() != DeductionFailure.getSecondArg()->pack_size()) { which = 3; } S.Diag(Templated->getLocation(), diag::note_ovl_candidate_inconsistent_deduction) << which << ParamD->getDeclName() << *DeductionFailure.getFirstArg() << *DeductionFailure.getSecondArg(); MaybeEmitInheritedConstructorNote(S, Found); return; } case Sema::TDK_InvalidExplicitArguments: assert(ParamD && "no parameter found for invalid explicit arguments"); if (ParamD->getDeclName()) S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named) << ParamD->getDeclName(); else { int index = 0; if (TemplateTypeParmDecl *TTP = dyn_cast(ParamD)) index = TTP->getIndex(); else if (NonTypeTemplateParmDecl *NTTP = dyn_cast(ParamD)) index = NTTP->getIndex(); else index = cast(ParamD)->getIndex(); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_unnamed) << (index + 1); } MaybeEmitInheritedConstructorNote(S, Found); return; case Sema::TDK_ConstraintsNotSatisfied: { // Format the template argument list into the argument string. SmallString<128> TemplateArgString; TemplateArgumentList *Args = DeductionFailure.getTemplateArgumentList(); TemplateArgString = " "; TemplateArgString += S.getTemplateArgumentBindingsText( getDescribedTemplate(Templated)->getTemplateParameters(), *Args); if (TemplateArgString.size() == 1) TemplateArgString.clear(); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_unsatisfied_constraints) << TemplateArgString; S.DiagnoseUnsatisfiedConstraint( static_cast(DeductionFailure.Data)->Satisfaction); return; } case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: DiagnoseArityMismatch(S, Found, Templated, NumArgs); return; case Sema::TDK_InstantiationDepth: S.Diag(Templated->getLocation(), diag::note_ovl_candidate_instantiation_depth); MaybeEmitInheritedConstructorNote(S, Found); return; case Sema::TDK_SubstitutionFailure: { // Format the template argument list into the argument string. SmallString<128> TemplateArgString; if (TemplateArgumentList *Args = DeductionFailure.getTemplateArgumentList()) { TemplateArgString = " "; TemplateArgString += S.getTemplateArgumentBindingsText( getDescribedTemplate(Templated)->getTemplateParameters(), *Args); if (TemplateArgString.size() == 1) TemplateArgString.clear(); } // If this candidate was disabled by enable_if, say so. PartialDiagnosticAt *PDiag = DeductionFailure.getSFINAEDiagnostic(); if (PDiag && PDiag->second.getDiagID() == diag::err_typename_nested_not_found_enable_if) { // FIXME: Use the source range of the condition, and the fully-qualified // name of the enable_if template. These are both present in PDiag. S.Diag(PDiag->first, diag::note_ovl_candidate_disabled_by_enable_if) << "'enable_if'" << TemplateArgString; return; } // We found a specific requirement that disabled the enable_if. if (PDiag && PDiag->second.getDiagID() == diag::err_typename_nested_not_found_requirement) { S.Diag(Templated->getLocation(), diag::note_ovl_candidate_disabled_by_requirement) << PDiag->second.getStringArg(0) << TemplateArgString; return; } // Format the SFINAE diagnostic into the argument string. // FIXME: Add a general mechanism to include a PartialDiagnostic *'s // formatted message in another diagnostic. SmallString<128> SFINAEArgString; SourceRange R; if (PDiag) { SFINAEArgString = ": "; R = SourceRange(PDiag->first, PDiag->first); PDiag->second.EmitToString(S.getDiagnostics(), SFINAEArgString); } S.Diag(Templated->getLocation(), diag::note_ovl_candidate_substitution_failure) << TemplateArgString << SFINAEArgString << R; MaybeEmitInheritedConstructorNote(S, Found); return; } case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: { // Format the template argument list into the argument string. SmallString<128> TemplateArgString; if (TemplateArgumentList *Args = DeductionFailure.getTemplateArgumentList()) { TemplateArgString = " "; TemplateArgString += S.getTemplateArgumentBindingsText( getDescribedTemplate(Templated)->getTemplateParameters(), *Args); if (TemplateArgString.size() == 1) TemplateArgString.clear(); } S.Diag(Templated->getLocation(), diag::note_ovl_candidate_deduced_mismatch) << (*DeductionFailure.getCallArgIndex() + 1) << *DeductionFailure.getFirstArg() << *DeductionFailure.getSecondArg() << TemplateArgString << (DeductionFailure.Result == Sema::TDK_DeducedMismatchNested); break; } case Sema::TDK_NonDeducedMismatch: { // FIXME: Provide a source location to indicate what we couldn't match. TemplateArgument FirstTA = *DeductionFailure.getFirstArg(); TemplateArgument SecondTA = *DeductionFailure.getSecondArg(); if (FirstTA.getKind() == TemplateArgument::Template && SecondTA.getKind() == TemplateArgument::Template) { TemplateName FirstTN = FirstTA.getAsTemplate(); TemplateName SecondTN = SecondTA.getAsTemplate(); if (FirstTN.getKind() == TemplateName::Template && SecondTN.getKind() == TemplateName::Template) { if (FirstTN.getAsTemplateDecl()->getName() == SecondTN.getAsTemplateDecl()->getName()) { // FIXME: This fixes a bad diagnostic where both templates are named // the same. This particular case is a bit difficult since: // 1) It is passed as a string to the diagnostic printer. // 2) The diagnostic printer only attempts to find a better // name for types, not decls. // Ideally, this should folded into the diagnostic printer. S.Diag(Templated->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch_qualified) << FirstTN.getAsTemplateDecl() << SecondTN.getAsTemplateDecl(); return; } } } if (TakingCandidateAddress && isa(Templated) && !checkAddressOfCandidateIsAvailable(S, cast(Templated))) return; // FIXME: For generic lambda parameters, check if the function is a lambda // call operator, and if so, emit a prettier and more informative // diagnostic that mentions 'auto' and lambda in addition to // (or instead of?) the canonical template type parameters. S.Diag(Templated->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch) << FirstTA << SecondTA; return; } // TODO: diagnose these individually, then kill off // note_ovl_candidate_bad_deduction, which is uselessly vague. case Sema::TDK_MiscellaneousDeductionFailure: S.Diag(Templated->getLocation(), diag::note_ovl_candidate_bad_deduction); MaybeEmitInheritedConstructorNote(S, Found); return; case Sema::TDK_CUDATargetMismatch: S.Diag(Templated->getLocation(), diag::note_cuda_ovl_candidate_target_mismatch); return; } } /// Diagnose a failed template-argument deduction, for function calls. static void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, unsigned NumArgs, bool TakingCandidateAddress) { unsigned TDK = Cand->DeductionFailure.Result; if (TDK == Sema::TDK_TooFewArguments || TDK == Sema::TDK_TooManyArguments) { if (CheckArityMismatch(S, Cand, NumArgs)) return; } DiagnoseBadDeduction(S, Cand->FoundDecl, Cand->Function, // pattern Cand->DeductionFailure, NumArgs, TakingCandidateAddress); } /// CUDA: diagnose an invalid call across targets. static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) { FunctionDecl *Caller = cast(S.CurContext); FunctionDecl *Callee = Cand->Function; Sema::CUDAFunctionTarget CallerTarget = S.IdentifyCUDATarget(Caller), CalleeTarget = S.IdentifyCUDATarget(Callee); std::string FnDesc; std::pair FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Callee, Cand->getRewriteKind(), FnDesc); S.Diag(Callee->getLocation(), diag::note_ovl_candidate_bad_target) << (unsigned)FnKindPair.first << (unsigned)ocs_non_template << FnDesc /* Ignored */ << CalleeTarget << CallerTarget; // This could be an implicit constructor for which we could not infer the // target due to a collsion. Diagnose that case. CXXMethodDecl *Meth = dyn_cast(Callee); if (Meth != nullptr && Meth->isImplicit()) { CXXRecordDecl *ParentClass = Meth->getParent(); Sema::CXXSpecialMember CSM; switch (FnKindPair.first) { default: return; case oc_implicit_default_constructor: CSM = Sema::CXXDefaultConstructor; break; case oc_implicit_copy_constructor: CSM = Sema::CXXCopyConstructor; break; case oc_implicit_move_constructor: CSM = Sema::CXXMoveConstructor; break; case oc_implicit_copy_assignment: CSM = Sema::CXXCopyAssignment; break; case oc_implicit_move_assignment: CSM = Sema::CXXMoveAssignment; break; }; bool ConstRHS = false; if (Meth->getNumParams()) { if (const ReferenceType *RT = Meth->getParamDecl(0)->getType()->getAs()) { ConstRHS = RT->getPointeeType().isConstQualified(); } } S.inferCUDATargetForImplicitSpecialMember(ParentClass, CSM, Meth, /* ConstRHS */ ConstRHS, /* Diagnose */ true); } } static void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) { FunctionDecl *Callee = Cand->Function; EnableIfAttr *Attr = static_cast(Cand->DeductionFailure.Data); S.Diag(Callee->getLocation(), diag::note_ovl_candidate_disabled_by_function_cond_attr) << Attr->getCond()->getSourceRange() << Attr->getMessage(); } static void DiagnoseFailedExplicitSpec(Sema &S, OverloadCandidate *Cand) { ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(Cand->Function); assert(ES.isExplicit() && "not an explicit candidate"); unsigned Kind; switch (Cand->Function->getDeclKind()) { case Decl::Kind::CXXConstructor: Kind = 0; break; case Decl::Kind::CXXConversion: Kind = 1; break; case Decl::Kind::CXXDeductionGuide: Kind = Cand->Function->isImplicit() ? 0 : 2; break; default: llvm_unreachable("invalid Decl"); } // Note the location of the first (in-class) declaration; a redeclaration // (particularly an out-of-class definition) will typically lack the // 'explicit' specifier. // FIXME: This is probably a good thing to do for all 'candidate' notes. FunctionDecl *First = Cand->Function->getFirstDecl(); if (FunctionDecl *Pattern = First->getTemplateInstantiationPattern()) First = Pattern->getFirstDecl(); S.Diag(First->getLocation(), diag::note_ovl_candidate_explicit) << Kind << (ES.getExpr() ? 1 : 0) << (ES.getExpr() ? ES.getExpr()->getSourceRange() : SourceRange()); } static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) { FunctionDecl *Callee = Cand->Function; S.Diag(Callee->getLocation(), diag::note_ovl_candidate_disabled_by_extension) << S.getOpenCLExtensionsFromDeclExtMap(Callee); } /// Generates a 'note' diagnostic for an overload candidate. We've /// already generated a primary error at the call site. /// /// It really does need to be a single diagnostic with its caret /// pointed at the candidate declaration. Yes, this creates some /// major challenges of technical writing. Yes, this makes pointing /// out problems with specific arguments quite awkward. It's still /// better than generating twenty screens of text for every failed /// overload. /// /// It would be great to be able to express per-candidate problems /// more richly for those diagnostic clients that cared, but we'd /// still have to be just as careful with the default diagnostics. /// \param CtorDestAS Addr space of object being constructed (for ctor /// candidates only). static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, unsigned NumArgs, bool TakingCandidateAddress, LangAS CtorDestAS = LangAS::Default) { FunctionDecl *Fn = Cand->Function; // Note deleted candidates, but only if they're viable. if (Cand->Viable) { if (Fn->isDeleted()) { std::string FnDesc; std::pair FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, Cand->getRewriteKind(), FnDesc); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (Fn->isDeleted() ? (Fn->isDeletedAsWritten() ? 1 : 2) : 0); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // We don't really have anything else to say about viable candidates. S.NoteOverloadCandidate(Cand->FoundDecl, Fn, Cand->getRewriteKind()); return; } switch (Cand->FailureKind) { case ovl_fail_too_many_arguments: case ovl_fail_too_few_arguments: return DiagnoseArityMismatch(S, Cand, NumArgs); case ovl_fail_bad_deduction: return DiagnoseBadDeduction(S, Cand, NumArgs, TakingCandidateAddress); case ovl_fail_illegal_constructor: { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_illegal_constructor) << (Fn->getPrimaryTemplate() ? 1 : 0); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } case ovl_fail_object_addrspace_mismatch: { Qualifiers QualsForPrinting; QualsForPrinting.setAddressSpace(CtorDestAS); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_illegal_constructor_adrspace_mismatch) << QualsForPrinting; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } case ovl_fail_trivial_conversion: case ovl_fail_bad_final_conversion: case ovl_fail_final_conversion_not_exact: return S.NoteOverloadCandidate(Cand->FoundDecl, Fn, Cand->getRewriteKind()); case ovl_fail_bad_conversion: { unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0); for (unsigned N = Cand->Conversions.size(); I != N; ++I) if (Cand->Conversions[I].isBad()) return DiagnoseBadConversion(S, Cand, I, TakingCandidateAddress); // FIXME: this currently happens when we're called from SemaInit // when user-conversion overload fails. Figure out how to handle // those conditions and diagnose them well. return S.NoteOverloadCandidate(Cand->FoundDecl, Fn, Cand->getRewriteKind()); } case ovl_fail_bad_target: return DiagnoseBadTarget(S, Cand); case ovl_fail_enable_if: return DiagnoseFailedEnableIfAttr(S, Cand); case ovl_fail_explicit: return DiagnoseFailedExplicitSpec(S, Cand); case ovl_fail_ext_disabled: return DiagnoseOpenCLExtensionDisabled(S, Cand); case ovl_fail_inhctor_slice: // It's generally not interesting to note copy/move constructors here. if (cast(Fn)->isCopyOrMoveConstructor()) return; S.Diag(Fn->getLocation(), diag::note_ovl_candidate_inherited_constructor_slice) << (Fn->getPrimaryTemplate() ? 1 : 0) << Fn->getParamDecl(0)->getType()->isRValueReferenceType(); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; case ovl_fail_addr_not_available: { bool Available = checkAddressOfCandidateIsAvailable(S, Cand->Function); (void)Available; assert(!Available); break; } case ovl_non_default_multiversion_function: // Do nothing, these should simply be ignored. break; case ovl_fail_constraints_not_satisfied: { std::string FnDesc; std::pair FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, Cand->getRewriteKind(), FnDesc); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_constraints_not_satisfied) << (unsigned)FnKindPair.first << (unsigned)ocs_non_template << FnDesc /* Ignored */; ConstraintSatisfaction Satisfaction; if (S.CheckFunctionConstraints(Fn, Satisfaction)) break; S.DiagnoseUnsatisfiedConstraint(Satisfaction); } } } static void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) { // Desugar the type of the surrogate down to a function type, // retaining as many typedefs as possible while still showing // the function type (and, therefore, its parameter types). QualType FnType = Cand->Surrogate->getConversionType(); bool isLValueReference = false; bool isRValueReference = false; bool isPointer = false; if (const LValueReferenceType *FnTypeRef = FnType->getAs()) { FnType = FnTypeRef->getPointeeType(); isLValueReference = true; } else if (const RValueReferenceType *FnTypeRef = FnType->getAs()) { FnType = FnTypeRef->getPointeeType(); isRValueReference = true; } if (const PointerType *FnTypePtr = FnType->getAs()) { FnType = FnTypePtr->getPointeeType(); isPointer = true; } // Desugar down to a function type. FnType = QualType(FnType->getAs(), 0); // Reconstruct the pointer/reference as appropriate. if (isPointer) FnType = S.Context.getPointerType(FnType); if (isRValueReference) FnType = S.Context.getRValueReferenceType(FnType); if (isLValueReference) FnType = S.Context.getLValueReferenceType(FnType); S.Diag(Cand->Surrogate->getLocation(), diag::note_ovl_surrogate_cand) << FnType; } static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc, SourceLocation OpLoc, OverloadCandidate *Cand) { assert(Cand->Conversions.size() <= 2 && "builtin operator is not binary"); std::string TypeStr("operator"); TypeStr += Opc; TypeStr += "("; TypeStr += Cand->BuiltinParamTypes[0].getAsString(); if (Cand->Conversions.size() == 1) { TypeStr += ")"; S.Diag(OpLoc, diag::note_ovl_builtin_candidate) << TypeStr; } else { TypeStr += ", "; TypeStr += Cand->BuiltinParamTypes[1].getAsString(); TypeStr += ")"; S.Diag(OpLoc, diag::note_ovl_builtin_candidate) << TypeStr; } } static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc, OverloadCandidate *Cand) { for (const ImplicitConversionSequence &ICS : Cand->Conversions) { if (ICS.isBad()) break; // all meaningless after first invalid if (!ICS.isAmbiguous()) continue; ICS.DiagnoseAmbiguousConversion( S, OpLoc, S.PDiag(diag::note_ambiguous_type_conversion)); } } static SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) { if (Cand->Function) return Cand->Function->getLocation(); if (Cand->IsSurrogate) return Cand->Surrogate->getLocation(); return SourceLocation(); } static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) { switch ((Sema::TemplateDeductionResult)DFI.Result) { case Sema::TDK_Success: case Sema::TDK_NonDependentConversionFailure: llvm_unreachable("non-deduction failure while diagnosing bad deduction"); case Sema::TDK_Invalid: case Sema::TDK_Incomplete: case Sema::TDK_IncompletePack: return 1; case Sema::TDK_Underqualified: case Sema::TDK_Inconsistent: return 2; case Sema::TDK_SubstitutionFailure: case Sema::TDK_DeducedMismatch: case Sema::TDK_ConstraintsNotSatisfied: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_MiscellaneousDeductionFailure: case Sema::TDK_CUDATargetMismatch: return 3; case Sema::TDK_InstantiationDepth: return 4; case Sema::TDK_InvalidExplicitArguments: return 5; case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: return 6; } llvm_unreachable("Unhandled deduction result"); } namespace { struct CompareOverloadCandidatesForDisplay { Sema &S; SourceLocation Loc; size_t NumArgs; OverloadCandidateSet::CandidateSetKind CSK; CompareOverloadCandidatesForDisplay( Sema &S, SourceLocation Loc, size_t NArgs, OverloadCandidateSet::CandidateSetKind CSK) : S(S), NumArgs(NArgs), CSK(CSK) {} OverloadFailureKind EffectiveFailureKind(const OverloadCandidate *C) const { // If there are too many or too few arguments, that's the high-order bit we // want to sort by, even if the immediate failure kind was something else. if (C->FailureKind == ovl_fail_too_many_arguments || C->FailureKind == ovl_fail_too_few_arguments) return static_cast(C->FailureKind); if (C->Function) { if (NumArgs > C->Function->getNumParams() && !C->Function->isVariadic()) return ovl_fail_too_many_arguments; if (NumArgs < C->Function->getMinRequiredArguments()) return ovl_fail_too_few_arguments; } return static_cast(C->FailureKind); } bool operator()(const OverloadCandidate *L, const OverloadCandidate *R) { // Fast-path this check. if (L == R) return false; // Order first by viability. if (L->Viable) { if (!R->Viable) return true; // TODO: introduce a tri-valued comparison for overload // candidates. Would be more worthwhile if we had a sort // that could exploit it. if (isBetterOverloadCandidate(S, *L, *R, SourceLocation(), CSK)) return true; if (isBetterOverloadCandidate(S, *R, *L, SourceLocation(), CSK)) return false; } else if (R->Viable) return false; assert(L->Viable == R->Viable); // Criteria by which we can sort non-viable candidates: if (!L->Viable) { OverloadFailureKind LFailureKind = EffectiveFailureKind(L); OverloadFailureKind RFailureKind = EffectiveFailureKind(R); // 1. Arity mismatches come after other candidates. if (LFailureKind == ovl_fail_too_many_arguments || LFailureKind == ovl_fail_too_few_arguments) { if (RFailureKind == ovl_fail_too_many_arguments || RFailureKind == ovl_fail_too_few_arguments) { int LDist = std::abs((int)L->getNumParams() - (int)NumArgs); int RDist = std::abs((int)R->getNumParams() - (int)NumArgs); if (LDist == RDist) { if (LFailureKind == RFailureKind) // Sort non-surrogates before surrogates. return !L->IsSurrogate && R->IsSurrogate; // Sort candidates requiring fewer parameters than there were // arguments given after candidates requiring more parameters // than there were arguments given. return LFailureKind == ovl_fail_too_many_arguments; } return LDist < RDist; } return false; } if (RFailureKind == ovl_fail_too_many_arguments || RFailureKind == ovl_fail_too_few_arguments) return true; // 2. Bad conversions come first and are ordered by the number // of bad conversions and quality of good conversions. if (LFailureKind == ovl_fail_bad_conversion) { if (RFailureKind != ovl_fail_bad_conversion) return true; // The conversion that can be fixed with a smaller number of changes, // comes first. unsigned numLFixes = L->Fix.NumConversionsFixed; unsigned numRFixes = R->Fix.NumConversionsFixed; numLFixes = (numLFixes == 0) ? UINT_MAX : numLFixes; numRFixes = (numRFixes == 0) ? UINT_MAX : numRFixes; if (numLFixes != numRFixes) { return numLFixes < numRFixes; } // If there's any ordering between the defined conversions... // FIXME: this might not be transitive. assert(L->Conversions.size() == R->Conversions.size()); int leftBetter = 0; unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument); for (unsigned E = L->Conversions.size(); I != E; ++I) { switch (CompareImplicitConversionSequences(S, Loc, L->Conversions[I], R->Conversions[I])) { case ImplicitConversionSequence::Better: leftBetter++; break; case ImplicitConversionSequence::Worse: leftBetter--; break; case ImplicitConversionSequence::Indistinguishable: break; } } if (leftBetter > 0) return true; if (leftBetter < 0) return false; } else if (RFailureKind == ovl_fail_bad_conversion) return false; if (LFailureKind == ovl_fail_bad_deduction) { if (RFailureKind != ovl_fail_bad_deduction) return true; if (L->DeductionFailure.Result != R->DeductionFailure.Result) return RankDeductionFailure(L->DeductionFailure) < RankDeductionFailure(R->DeductionFailure); } else if (RFailureKind == ovl_fail_bad_deduction) return false; // TODO: others? } // Sort everything else by location. SourceLocation LLoc = GetLocationForCandidate(L); SourceLocation RLoc = GetLocationForCandidate(R); // Put candidates without locations (e.g. builtins) at the end. if (LLoc.isInvalid()) return false; if (RLoc.isInvalid()) return true; return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc); } }; } /// CompleteNonViableCandidate - Normally, overload resolution only /// computes up to the first bad conversion. Produces the FixIt set if /// possible. static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, ArrayRef Args, OverloadCandidateSet::CandidateSetKind CSK) { assert(!Cand->Viable); // Don't do anything on failures other than bad conversion. if (Cand->FailureKind != ovl_fail_bad_conversion) return; // We only want the FixIts if all the arguments can be corrected. bool Unfixable = false; // Use a implicit copy initialization to check conversion fixes. Cand->Fix.setConversionChecker(TryCopyInitialization); // Attempt to fix the bad conversion. unsigned ConvCount = Cand->Conversions.size(); for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); /**/; ++ConvIdx) { assert(ConvIdx != ConvCount && "no bad conversion in candidate"); if (Cand->Conversions[ConvIdx].isInitialized() && Cand->Conversions[ConvIdx].isBad()) { Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S); break; } } // FIXME: this should probably be preserved from the overload // operation somehow. bool SuppressUserConversions = false; unsigned ConvIdx = 0; unsigned ArgIdx = 0; ArrayRef ParamTypes; bool Reversed = Cand->RewriteKind & CRK_Reversed; if (Cand->IsSurrogate) { QualType ConvType = Cand->Surrogate->getConversionType().getNonReferenceType(); if (const PointerType *ConvPtrType = ConvType->getAs()) ConvType = ConvPtrType->getPointeeType(); ParamTypes = ConvType->castAs()->getParamTypes(); // Conversion 0 is 'this', which doesn't have a corresponding parameter. ConvIdx = 1; } else if (Cand->Function) { ParamTypes = Cand->Function->getType()->castAs()->getParamTypes(); if (isa(Cand->Function) && !isa(Cand->Function) && !Reversed) { // Conversion 0 is 'this', which doesn't have a corresponding parameter. ConvIdx = 1; if (CSK == OverloadCandidateSet::CSK_Operator && Cand->Function->getDeclName().getCXXOverloadedOperator() != OO_Call) // Argument 0 is 'this', which doesn't have a corresponding parameter. ArgIdx = 1; } } else { // Builtin operator. assert(ConvCount <= 3); ParamTypes = Cand->BuiltinParamTypes; } // Fill in the rest of the conversions. for (unsigned ParamIdx = Reversed ? ParamTypes.size() - 1 : 0; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx, ParamIdx += (Reversed ? -1 : 1)) { assert(ArgIdx < Args.size() && "no argument for this arg conversion"); if (Cand->Conversions[ConvIdx].isInitialized()) { // We've already checked this conversion. } else if (ParamIdx < ParamTypes.size()) { if (ParamTypes[ParamIdx]->isDependentType()) Cand->Conversions[ConvIdx].setAsIdentityConversion( Args[ArgIdx]->getType()); else { Cand->Conversions[ConvIdx] = TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ParamIdx], SuppressUserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ S.getLangOpts().ObjCAutoRefCount); // Store the FixIt in the candidate if it exists. if (!Unfixable && Cand->Conversions[ConvIdx].isBad()) Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S); } } else Cand->Conversions[ConvIdx].setEllipsis(); } } SmallVector OverloadCandidateSet::CompleteCandidates( Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef Args, SourceLocation OpLoc, llvm::function_ref Filter) { // Sort the candidates by viability and position. Sorting directly would // be prohibitive, so we make a set of pointers and sort those. SmallVector Cands; if (OCD == OCD_AllCandidates) Cands.reserve(size()); for (iterator Cand = begin(), LastCand = end(); Cand != LastCand; ++Cand) { if (!Filter(*Cand)) continue; switch (OCD) { case OCD_AllCandidates: if (!Cand->Viable) { if (!Cand->Function && !Cand->IsSurrogate) { // This a non-viable builtin candidate. We do not, in general, // want to list every possible builtin candidate. continue; } CompleteNonViableCandidate(S, Cand, Args, Kind); } break; case OCD_ViableCandidates: if (!Cand->Viable) continue; break; case OCD_AmbiguousCandidates: if (!Cand->Best) continue; break; } Cands.push_back(Cand); } llvm::stable_sort( Cands, CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size(), Kind)); return Cands; } /// When overload resolution fails, prints diagnostic messages containing the /// candidates in the candidate set. void OverloadCandidateSet::NoteCandidates(PartialDiagnosticAt PD, Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef Args, StringRef Opc, SourceLocation OpLoc, llvm::function_ref Filter) { auto Cands = CompleteCandidates(S, OCD, Args, OpLoc, Filter); S.Diag(PD.first, PD.second); NoteCandidates(S, Args, Cands, Opc, OpLoc); if (OCD == OCD_AmbiguousCandidates) MaybeDiagnoseAmbiguousConstraints(S, {begin(), end()}); } void OverloadCandidateSet::NoteCandidates(Sema &S, ArrayRef Args, ArrayRef Cands, StringRef Opc, SourceLocation OpLoc) { bool ReportedAmbiguousConversions = false; const OverloadsShown ShowOverloads = S.Diags.getShowOverloads(); unsigned CandsShown = 0; auto I = Cands.begin(), E = Cands.end(); for (; I != E; ++I) { OverloadCandidate *Cand = *I; // Set an arbitrary limit on the number of candidate functions we'll spam // the user with. FIXME: This limit should depend on details of the // candidate list. if (CandsShown >= 4 && ShowOverloads == Ovl_Best) { break; } ++CandsShown; if (Cand->Function) NoteFunctionCandidate(S, Cand, Args.size(), /*TakingCandidateAddress=*/false, DestAS); else if (Cand->IsSurrogate) NoteSurrogateCandidate(S, Cand); else { assert(Cand->Viable && "Non-viable built-in candidates are not added to Cands."); // Generally we only see ambiguities including viable builtin // operators if overload resolution got screwed up by an // ambiguous user-defined conversion. // // FIXME: It's quite possible for different conversions to see // different ambiguities, though. if (!ReportedAmbiguousConversions) { NoteAmbiguousUserConversions(S, OpLoc, Cand); ReportedAmbiguousConversions = true; } // If this is a viable builtin, print it. NoteBuiltinOperatorCandidate(S, Opc, OpLoc, Cand); } } if (I != E) S.Diag(OpLoc, diag::note_ovl_too_many_candidates) << int(E - I); } static SourceLocation GetLocationForCandidate(const TemplateSpecCandidate *Cand) { return Cand->Specialization ? Cand->Specialization->getLocation() : SourceLocation(); } namespace { struct CompareTemplateSpecCandidatesForDisplay { Sema &S; CompareTemplateSpecCandidatesForDisplay(Sema &S) : S(S) {} bool operator()(const TemplateSpecCandidate *L, const TemplateSpecCandidate *R) { // Fast-path this check. if (L == R) return false; // Assuming that both candidates are not matches... // Sort by the ranking of deduction failures. if (L->DeductionFailure.Result != R->DeductionFailure.Result) return RankDeductionFailure(L->DeductionFailure) < RankDeductionFailure(R->DeductionFailure); // Sort everything else by location. SourceLocation LLoc = GetLocationForCandidate(L); SourceLocation RLoc = GetLocationForCandidate(R); // Put candidates without locations (e.g. builtins) at the end. if (LLoc.isInvalid()) return false; if (RLoc.isInvalid()) return true; return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc); } }; } /// Diagnose a template argument deduction failure. /// We are treating these failures as overload failures due to bad /// deductions. void TemplateSpecCandidate::NoteDeductionFailure(Sema &S, bool ForTakingAddress) { DiagnoseBadDeduction(S, FoundDecl, Specialization, // pattern DeductionFailure, /*NumArgs=*/0, ForTakingAddress); } void TemplateSpecCandidateSet::destroyCandidates() { for (iterator i = begin(), e = end(); i != e; ++i) { i->DeductionFailure.Destroy(); } } void TemplateSpecCandidateSet::clear() { destroyCandidates(); Candidates.clear(); } /// NoteCandidates - When no template specialization match is found, prints /// diagnostic messages containing the non-matching specializations that form /// the candidate set. /// This is analoguous to OverloadCandidateSet::NoteCandidates() with /// OCD == OCD_AllCandidates and Cand->Viable == false. void TemplateSpecCandidateSet::NoteCandidates(Sema &S, SourceLocation Loc) { // Sort the candidates by position (assuming no candidate is a match). // Sorting directly would be prohibitive, so we make a set of pointers // and sort those. SmallVector Cands; Cands.reserve(size()); for (iterator Cand = begin(), LastCand = end(); Cand != LastCand; ++Cand) { if (Cand->Specialization) Cands.push_back(Cand); // Otherwise, this is a non-matching builtin candidate. We do not, // in general, want to list every possible builtin candidate. } llvm::sort(Cands, CompareTemplateSpecCandidatesForDisplay(S)); // FIXME: Perhaps rename OverloadsShown and getShowOverloads() // for generalization purposes (?). const OverloadsShown ShowOverloads = S.Diags.getShowOverloads(); SmallVectorImpl::iterator I, E; unsigned CandsShown = 0; for (I = Cands.begin(), E = Cands.end(); I != E; ++I) { TemplateSpecCandidate *Cand = *I; // Set an arbitrary limit on the number of candidates we'll spam // the user with. FIXME: This limit should depend on details of the // candidate list. if (CandsShown >= 4 && ShowOverloads == Ovl_Best) break; ++CandsShown; assert(Cand->Specialization && "Non-matching built-in candidates are not added to Cands."); Cand->NoteDeductionFailure(S, ForTakingAddress); } if (I != E) S.Diag(Loc, diag::note_ovl_too_many_candidates) << int(E - I); } // [PossiblyAFunctionType] --> [Return] // NonFunctionType --> NonFunctionType // R (A) --> R(A) // R (*)(A) --> R (A) // R (&)(A) --> R (A) // R (S::*)(A) --> R (A) QualType Sema::ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType) { QualType Ret = PossiblyAFunctionType; if (const PointerType *ToTypePtr = PossiblyAFunctionType->getAs()) Ret = ToTypePtr->getPointeeType(); else if (const ReferenceType *ToTypeRef = PossiblyAFunctionType->getAs()) Ret = ToTypeRef->getPointeeType(); else if (const MemberPointerType *MemTypePtr = PossiblyAFunctionType->getAs()) Ret = MemTypePtr->getPointeeType(); Ret = Context.getCanonicalType(Ret).getUnqualifiedType(); return Ret; } static bool completeFunctionType(Sema &S, FunctionDecl *FD, SourceLocation Loc, bool Complain = true) { if (S.getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && S.DeduceReturnType(FD, Loc, Complain)) return true; auto *FPT = FD->getType()->castAs(); if (S.getLangOpts().CPlusPlus17 && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) && !S.ResolveExceptionSpec(Loc, FPT)) return true; return false; } namespace { // A helper class to help with address of function resolution // - allows us to avoid passing around all those ugly parameters class AddressOfFunctionResolver { Sema& S; Expr* SourceExpr; const QualType& TargetType; QualType TargetFunctionType; // Extracted function type from target type bool Complain; //DeclAccessPair& ResultFunctionAccessPair; ASTContext& Context; bool TargetTypeIsNonStaticMemberFunction; bool FoundNonTemplateFunction; bool StaticMemberFunctionFromBoundPointer; bool HasComplained; OverloadExpr::FindResult OvlExprInfo; OverloadExpr *OvlExpr; TemplateArgumentListInfo OvlExplicitTemplateArgs; SmallVector, 4> Matches; TemplateSpecCandidateSet FailedCandidates; public: AddressOfFunctionResolver(Sema &S, Expr *SourceExpr, const QualType &TargetType, bool Complain) : S(S), SourceExpr(SourceExpr), TargetType(TargetType), Complain(Complain), Context(S.getASTContext()), TargetTypeIsNonStaticMemberFunction( !!TargetType->getAs()), FoundNonTemplateFunction(false), StaticMemberFunctionFromBoundPointer(false), HasComplained(false), OvlExprInfo(OverloadExpr::find(SourceExpr)), OvlExpr(OvlExprInfo.Expression), FailedCandidates(OvlExpr->getNameLoc(), /*ForTakingAddress=*/true) { ExtractUnqualifiedFunctionTypeFromTargetType(); if (TargetFunctionType->isFunctionType()) { if (UnresolvedMemberExpr *UME = dyn_cast(OvlExpr)) if (!UME->isImplicitAccess() && !S.ResolveSingleFunctionTemplateSpecialization(UME)) StaticMemberFunctionFromBoundPointer = true; } else if (OvlExpr->hasExplicitTemplateArgs()) { DeclAccessPair dap; if (FunctionDecl *Fn = S.ResolveSingleFunctionTemplateSpecialization( OvlExpr, false, &dap)) { if (CXXMethodDecl *Method = dyn_cast(Fn)) if (!Method->isStatic()) { // If the target type is a non-function type and the function found // is a non-static member function, pretend as if that was the // target, it's the only possible type to end up with. TargetTypeIsNonStaticMemberFunction = true; // And skip adding the function if its not in the proper form. // We'll diagnose this due to an empty set of functions. if (!OvlExprInfo.HasFormOfMemberPointer) return; } Matches.push_back(std::make_pair(dap, Fn)); } return; } if (OvlExpr->hasExplicitTemplateArgs()) OvlExpr->copyTemplateArgumentsInto(OvlExplicitTemplateArgs); if (FindAllFunctionsThatMatchTargetTypeExactly()) { // C++ [over.over]p4: // If more than one function is selected, [...] if (Matches.size() > 1 && !eliminiateSuboptimalOverloadCandidates()) { if (FoundNonTemplateFunction) EliminateAllTemplateMatches(); else EliminateAllExceptMostSpecializedTemplate(); } } if (S.getLangOpts().CUDA && Matches.size() > 1) EliminateSuboptimalCudaMatches(); } bool hasComplained() const { return HasComplained; } private: bool candidateHasExactlyCorrectType(const FunctionDecl *FD) { QualType Discard; return Context.hasSameUnqualifiedType(TargetFunctionType, FD->getType()) || S.IsFunctionConversion(FD->getType(), TargetFunctionType, Discard); } /// \return true if A is considered a better overload candidate for the /// desired type than B. bool isBetterCandidate(const FunctionDecl *A, const FunctionDecl *B) { // If A doesn't have exactly the correct type, we don't want to classify it // as "better" than anything else. This way, the user is required to // disambiguate for us if there are multiple candidates and no exact match. return candidateHasExactlyCorrectType(A) && (!candidateHasExactlyCorrectType(B) || compareEnableIfAttrs(S, A, B) == Comparison::Better); } /// \return true if we were able to eliminate all but one overload candidate, /// false otherwise. bool eliminiateSuboptimalOverloadCandidates() { // Same algorithm as overload resolution -- one pass to pick the "best", // another pass to be sure that nothing is better than the best. auto Best = Matches.begin(); for (auto I = Matches.begin()+1, E = Matches.end(); I != E; ++I) if (isBetterCandidate(I->second, Best->second)) Best = I; const FunctionDecl *BestFn = Best->second; auto IsBestOrInferiorToBest = [this, BestFn]( const std::pair &Pair) { return BestFn == Pair.second || isBetterCandidate(BestFn, Pair.second); }; // Note: We explicitly leave Matches unmodified if there isn't a clear best // option, so we can potentially give the user a better error if (!llvm::all_of(Matches, IsBestOrInferiorToBest)) return false; Matches[0] = *Best; Matches.resize(1); return true; } bool isTargetTypeAFunction() const { return TargetFunctionType->isFunctionType(); } // [ToType] [Return] // R (*)(A) --> R (A), IsNonStaticMemberFunction = false // R (&)(A) --> R (A), IsNonStaticMemberFunction = false // R (S::*)(A) --> R (A), IsNonStaticMemberFunction = true void inline ExtractUnqualifiedFunctionTypeFromTargetType() { TargetFunctionType = S.ExtractUnqualifiedFunctionType(TargetType); } // return true if any matching specializations were found bool AddMatchingTemplateFunction(FunctionTemplateDecl* FunctionTemplate, const DeclAccessPair& CurAccessFunPair) { if (CXXMethodDecl *Method = dyn_cast(FunctionTemplate->getTemplatedDecl())) { // Skip non-static function templates when converting to pointer, and // static when converting to member pointer. if (Method->isStatic() == TargetTypeIsNonStaticMemberFunction) return false; } else if (TargetTypeIsNonStaticMemberFunction) return false; // C++ [over.over]p2: // If the name is a function template, template argument deduction is // done (14.8.2.2), and if the argument deduction succeeds, the // resulting template argument list is used to generate a single // function template specialization, which is added to the set of // overloaded functions considered. FunctionDecl *Specialization = nullptr; TemplateDeductionInfo Info(FailedCandidates.getLocation()); if (Sema::TemplateDeductionResult Result = S.DeduceTemplateArguments(FunctionTemplate, &OvlExplicitTemplateArgs, TargetFunctionType, Specialization, Info, /*IsAddressOfFunction*/true)) { // Make a note of the failed deduction for diagnostics. FailedCandidates.addCandidate() .set(CurAccessFunPair, FunctionTemplate->getTemplatedDecl(), MakeDeductionFailureInfo(Context, Result, Info)); return false; } // Template argument deduction ensures that we have an exact match or // compatible pointer-to-function arguments that would be adjusted by ICS. // This function template specicalization works. assert(S.isSameOrCompatibleFunctionType( Context.getCanonicalType(Specialization->getType()), Context.getCanonicalType(TargetFunctionType))); if (!S.checkAddressOfFunctionIsAvailable(Specialization)) return false; Matches.push_back(std::make_pair(CurAccessFunPair, Specialization)); return true; } bool AddMatchingNonTemplateFunction(NamedDecl* Fn, const DeclAccessPair& CurAccessFunPair) { if (CXXMethodDecl *Method = dyn_cast(Fn)) { // Skip non-static functions when converting to pointer, and static // when converting to member pointer. if (Method->isStatic() == TargetTypeIsNonStaticMemberFunction) return false; } else if (TargetTypeIsNonStaticMemberFunction) return false; if (FunctionDecl *FunDecl = dyn_cast(Fn)) { if (S.getLangOpts().CUDA) if (FunctionDecl *Caller = dyn_cast(S.CurContext)) if (!Caller->isImplicit() && !S.IsAllowedCUDACall(Caller, FunDecl)) return false; if (FunDecl->isMultiVersion()) { const auto *TA = FunDecl->getAttr(); if (TA && !TA->isDefaultVersion()) return false; } // If any candidate has a placeholder return type, trigger its deduction // now. if (completeFunctionType(S, FunDecl, SourceExpr->getBeginLoc(), Complain)) { HasComplained |= Complain; return false; } if (!S.checkAddressOfFunctionIsAvailable(FunDecl)) return false; // If we're in C, we need to support types that aren't exactly identical. if (!S.getLangOpts().CPlusPlus || candidateHasExactlyCorrectType(FunDecl)) { Matches.push_back(std::make_pair( CurAccessFunPair, cast(FunDecl->getCanonicalDecl()))); FoundNonTemplateFunction = true; return true; } } return false; } bool FindAllFunctionsThatMatchTargetTypeExactly() { bool Ret = false; // If the overload expression doesn't have the form of a pointer to // member, don't try to convert it to a pointer-to-member type. if (IsInvalidFormOfPointerToMemberFunction()) return false; for (UnresolvedSetIterator I = OvlExpr->decls_begin(), E = OvlExpr->decls_end(); I != E; ++I) { // Look through any using declarations to find the underlying function. NamedDecl *Fn = (*I)->getUnderlyingDecl(); // C++ [over.over]p3: // Non-member functions and static member functions match // targets of type "pointer-to-function" or "reference-to-function." // Nonstatic member functions match targets of // type "pointer-to-member-function." // Note that according to DR 247, the containing class does not matter. if (FunctionTemplateDecl *FunctionTemplate = dyn_cast(Fn)) { if (AddMatchingTemplateFunction(FunctionTemplate, I.getPair())) Ret = true; } // If we have explicit template arguments supplied, skip non-templates. else if (!OvlExpr->hasExplicitTemplateArgs() && AddMatchingNonTemplateFunction(Fn, I.getPair())) Ret = true; } assert(Ret || Matches.empty()); return Ret; } void EliminateAllExceptMostSpecializedTemplate() { // [...] and any given function template specialization F1 is // eliminated if the set contains a second function template // specialization whose function template is more specialized // than the function template of F1 according to the partial // ordering rules of 14.5.5.2. // The algorithm specified above is quadratic. We instead use a // two-pass algorithm (similar to the one used to identify the // best viable function in an overload set) that identifies the // best function template (if it exists). UnresolvedSet<4> MatchesCopy; // TODO: avoid! for (unsigned I = 0, E = Matches.size(); I != E; ++I) MatchesCopy.addDecl(Matches[I].second, Matches[I].first.getAccess()); // TODO: It looks like FailedCandidates does not serve much purpose // here, since the no_viable diagnostic has index 0. UnresolvedSetIterator Result = S.getMostSpecialized( MatchesCopy.begin(), MatchesCopy.end(), FailedCandidates, SourceExpr->getBeginLoc(), S.PDiag(), S.PDiag(diag::err_addr_ovl_ambiguous) << Matches[0].second->getDeclName(), S.PDiag(diag::note_ovl_candidate) << (unsigned)oc_function << (unsigned)ocs_described_template, Complain, TargetFunctionType); if (Result != MatchesCopy.end()) { // Make it the first and only element Matches[0].first = Matches[Result - MatchesCopy.begin()].first; Matches[0].second = cast(*Result); Matches.resize(1); } else HasComplained |= Complain; } void EliminateAllTemplateMatches() { // [...] any function template specializations in the set are // eliminated if the set also contains a non-template function, [...] for (unsigned I = 0, N = Matches.size(); I != N; ) { if (Matches[I].second->getPrimaryTemplate() == nullptr) ++I; else { Matches[I] = Matches[--N]; Matches.resize(N); } } } void EliminateSuboptimalCudaMatches() { S.EraseUnwantedCUDAMatches(dyn_cast(S.CurContext), Matches); } public: void ComplainNoMatchesFound() const { assert(Matches.empty()); S.Diag(OvlExpr->getBeginLoc(), diag::err_addr_ovl_no_viable) << OvlExpr->getName() << TargetFunctionType << OvlExpr->getSourceRange(); if (FailedCandidates.empty()) S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType, /*TakingAddress=*/true); else { // We have some deduction failure messages. Use them to diagnose // the function templates, and diagnose the non-template candidates // normally. for (UnresolvedSetIterator I = OvlExpr->decls_begin(), IEnd = OvlExpr->decls_end(); I != IEnd; ++I) if (FunctionDecl *Fun = dyn_cast((*I)->getUnderlyingDecl())) if (!functionHasPassObjectSizeParams(Fun)) S.NoteOverloadCandidate(*I, Fun, CRK_None, TargetFunctionType, /*TakingAddress=*/true); FailedCandidates.NoteCandidates(S, OvlExpr->getBeginLoc()); } } bool IsInvalidFormOfPointerToMemberFunction() const { return TargetTypeIsNonStaticMemberFunction && !OvlExprInfo.HasFormOfMemberPointer; } void ComplainIsInvalidFormOfPointerToMemberFunction() const { // TODO: Should we condition this on whether any functions might // have matched, or is it more appropriate to do that in callers? // TODO: a fixit wouldn't hurt. S.Diag(OvlExpr->getNameLoc(), diag::err_addr_ovl_no_qualifier) << TargetType << OvlExpr->getSourceRange(); } bool IsStaticMemberFunctionFromBoundPointer() const { return StaticMemberFunctionFromBoundPointer; } void ComplainIsStaticMemberFunctionFromBoundPointer() const { S.Diag(OvlExpr->getBeginLoc(), diag::err_invalid_form_pointer_member_function) << OvlExpr->getSourceRange(); } void ComplainOfInvalidConversion() const { S.Diag(OvlExpr->getBeginLoc(), diag::err_addr_ovl_not_func_ptrref) << OvlExpr->getName() << TargetType; } void ComplainMultipleMatchesFound() const { assert(Matches.size() > 1); S.Diag(OvlExpr->getBeginLoc(), diag::err_addr_ovl_ambiguous) << OvlExpr->getName() << OvlExpr->getSourceRange(); S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType, /*TakingAddress=*/true); } bool hadMultipleCandidates() const { return (OvlExpr->getNumDecls() > 1); } int getNumMatches() const { return Matches.size(); } FunctionDecl* getMatchingFunctionDecl() const { if (Matches.size() != 1) return nullptr; return Matches[0].second; } const DeclAccessPair* getMatchingFunctionAccessPair() const { if (Matches.size() != 1) return nullptr; return &Matches[0].first; } }; } /// ResolveAddressOfOverloadedFunction - Try to resolve the address of /// an overloaded function (C++ [over.over]), where @p From is an /// expression with overloaded function type and @p ToType is the type /// we're trying to resolve to. For example: /// /// @code /// int f(double); /// int f(int); /// /// int (*pfd)(double) = f; // selects f(double) /// @endcode /// /// This routine returns the resulting FunctionDecl if it could be /// resolved, and NULL otherwise. When @p Complain is true, this /// routine will emit diagnostics if there is an error. FunctionDecl * Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, QualType TargetType, bool Complain, DeclAccessPair &FoundResult, bool *pHadMultipleCandidates) { assert(AddressOfExpr->getType() == Context.OverloadTy); AddressOfFunctionResolver Resolver(*this, AddressOfExpr, TargetType, Complain); int NumMatches = Resolver.getNumMatches(); FunctionDecl *Fn = nullptr; bool ShouldComplain = Complain && !Resolver.hasComplained(); if (NumMatches == 0 && ShouldComplain) { if (Resolver.IsInvalidFormOfPointerToMemberFunction()) Resolver.ComplainIsInvalidFormOfPointerToMemberFunction(); else Resolver.ComplainNoMatchesFound(); } else if (NumMatches > 1 && ShouldComplain) Resolver.ComplainMultipleMatchesFound(); else if (NumMatches == 1) { Fn = Resolver.getMatchingFunctionDecl(); assert(Fn); if (auto *FPT = Fn->getType()->getAs()) ResolveExceptionSpec(AddressOfExpr->getExprLoc(), FPT); FoundResult = *Resolver.getMatchingFunctionAccessPair(); if (Complain) { if (Resolver.IsStaticMemberFunctionFromBoundPointer()) Resolver.ComplainIsStaticMemberFunctionFromBoundPointer(); else CheckAddressOfMemberAccess(AddressOfExpr, FoundResult); } } if (pHadMultipleCandidates) *pHadMultipleCandidates = Resolver.hadMultipleCandidates(); return Fn; } /// Given an expression that refers to an overloaded function, try to /// resolve that function to a single function that can have its address taken. /// This will modify `Pair` iff it returns non-null. /// /// This routine can only succeed if from all of the candidates in the overload /// set for SrcExpr that can have their addresses taken, there is one candidate /// that is more constrained than the rest. FunctionDecl * Sema::resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &Pair) { OverloadExpr::FindResult R = OverloadExpr::find(E); OverloadExpr *Ovl = R.Expression; bool IsResultAmbiguous = false; FunctionDecl *Result = nullptr; DeclAccessPair DAP; SmallVector AmbiguousDecls; auto CheckMoreConstrained = [&] (FunctionDecl *FD1, FunctionDecl *FD2) -> Optional { SmallVector AC1, AC2; FD1->getAssociatedConstraints(AC1); FD2->getAssociatedConstraints(AC2); bool AtLeastAsConstrained1, AtLeastAsConstrained2; if (IsAtLeastAsConstrained(FD1, AC1, FD2, AC2, AtLeastAsConstrained1)) return None; if (IsAtLeastAsConstrained(FD2, AC2, FD1, AC1, AtLeastAsConstrained2)) return None; if (AtLeastAsConstrained1 == AtLeastAsConstrained2) return None; return AtLeastAsConstrained1; }; // Don't use the AddressOfResolver because we're specifically looking for // cases where we have one overload candidate that lacks // enable_if/pass_object_size/... for (auto I = Ovl->decls_begin(), E = Ovl->decls_end(); I != E; ++I) { auto *FD = dyn_cast(I->getUnderlyingDecl()); if (!FD) return nullptr; if (!checkAddressOfFunctionIsAvailable(FD)) continue; // We have more than one result - see if it is more constrained than the // previous one. if (Result) { Optional MoreConstrainedThanPrevious = CheckMoreConstrained(FD, Result); if (!MoreConstrainedThanPrevious) { IsResultAmbiguous = true; AmbiguousDecls.push_back(FD); continue; } if (!*MoreConstrainedThanPrevious) continue; // FD is more constrained - replace Result with it. } IsResultAmbiguous = false; DAP = I.getPair(); Result = FD; } if (IsResultAmbiguous) return nullptr; if (Result) { SmallVector ResultAC; // We skipped over some ambiguous declarations which might be ambiguous with // the selected result. for (FunctionDecl *Skipped : AmbiguousDecls) if (!CheckMoreConstrained(Skipped, Result).hasValue()) return nullptr; Pair = DAP; } return Result; } /// Given an overloaded function, tries to turn it into a non-overloaded /// function reference using resolveAddressOfSingleOverloadCandidate. This /// will perform access checks, diagnose the use of the resultant decl, and, if /// requested, potentially perform a function-to-pointer decay. /// /// Returns false if resolveAddressOfSingleOverloadCandidate fails. /// Otherwise, returns true. This may emit diagnostics and return true. bool Sema::resolveAndFixAddressOfSingleOverloadCandidate( ExprResult &SrcExpr, bool DoFunctionPointerConverion) { Expr *E = SrcExpr.get(); assert(E->getType() == Context.OverloadTy && "SrcExpr must be an overload"); DeclAccessPair DAP; FunctionDecl *Found = resolveAddressOfSingleOverloadCandidate(E, DAP); if (!Found || Found->isCPUDispatchMultiVersion() || Found->isCPUSpecificMultiVersion()) return false; // Emitting multiple diagnostics for a function that is both inaccessible and // unavailable is consistent with our behavior elsewhere. So, always check // for both. DiagnoseUseOfDecl(Found, E->getExprLoc()); CheckAddressOfMemberAccess(E, DAP); Expr *Fixed = FixOverloadedFunctionReference(E, DAP, Found); if (DoFunctionPointerConverion && Fixed->getType()->isFunctionType()) SrcExpr = DefaultFunctionArrayConversion(Fixed, /*Diagnose=*/false); else SrcExpr = Fixed; return true; } /// Given an expression that refers to an overloaded function, try to /// resolve that overloaded function expression down to a single function. /// /// This routine can only resolve template-ids that refer to a single function /// template, where that template-id refers to a single template whose template /// arguments are either provided by the template-id or have defaults, /// as described in C++0x [temp.arg.explicit]p3. /// /// If no template-ids are found, no diagnostics are emitted and NULL is /// returned. FunctionDecl * Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain, DeclAccessPair *FoundResult) { // C++ [over.over]p1: // [...] [Note: any redundant set of parentheses surrounding the // overloaded function name is ignored (5.1). ] // C++ [over.over]p1: // [...] The overloaded function name can be preceded by the & // operator. // If we didn't actually find any template-ids, we're done. if (!ovl->hasExplicitTemplateArgs()) return nullptr; TemplateArgumentListInfo ExplicitTemplateArgs; ovl->copyTemplateArgumentsInto(ExplicitTemplateArgs); TemplateSpecCandidateSet FailedCandidates(ovl->getNameLoc()); // Look through all of the overloaded functions, searching for one // whose type matches exactly. FunctionDecl *Matched = nullptr; for (UnresolvedSetIterator I = ovl->decls_begin(), E = ovl->decls_end(); I != E; ++I) { // C++0x [temp.arg.explicit]p3: // [...] In contexts where deduction is done and fails, or in contexts // where deduction is not done, if a template argument list is // specified and it, along with any default template arguments, // identifies a single function template specialization, then the // template-id is an lvalue for the function template specialization. FunctionTemplateDecl *FunctionTemplate = cast((*I)->getUnderlyingDecl()); // C++ [over.over]p2: // If the name is a function template, template argument deduction is // done (14.8.2.2), and if the argument deduction succeeds, the // resulting template argument list is used to generate a single // function template specialization, which is added to the set of // overloaded functions considered. FunctionDecl *Specialization = nullptr; TemplateDeductionInfo Info(FailedCandidates.getLocation()); if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs, Specialization, Info, /*IsAddressOfFunction*/true)) { // Make a note of the failed deduction for diagnostics. // TODO: Actually use the failed-deduction info? FailedCandidates.addCandidate() .set(I.getPair(), FunctionTemplate->getTemplatedDecl(), MakeDeductionFailureInfo(Context, Result, Info)); continue; } assert(Specialization && "no specialization and no error?"); // Multiple matches; we can't resolve to a single declaration. if (Matched) { if (Complain) { Diag(ovl->getExprLoc(), diag::err_addr_ovl_ambiguous) << ovl->getName(); NoteAllOverloadCandidates(ovl); } return nullptr; } Matched = Specialization; if (FoundResult) *FoundResult = I.getPair(); } if (Matched && completeFunctionType(*this, Matched, ovl->getExprLoc(), Complain)) return nullptr; return Matched; } // Resolve and fix an overloaded expression that can be resolved // because it identifies a single function template specialization. // // Last three arguments should only be supplied if Complain = true // // Return true if it was logically possible to so resolve the // expression, regardless of whether or not it succeeded. Always // returns true if 'complain' is set. bool Sema::ResolveAndFixSingleFunctionTemplateSpecialization( ExprResult &SrcExpr, bool doFunctionPointerConverion, bool complain, SourceRange OpRangeForComplaining, QualType DestTypeForComplaining, unsigned DiagIDForComplaining) { assert(SrcExpr.get()->getType() == Context.OverloadTy); OverloadExpr::FindResult ovl = OverloadExpr::find(SrcExpr.get()); DeclAccessPair found; ExprResult SingleFunctionExpression; if (FunctionDecl *fn = ResolveSingleFunctionTemplateSpecialization( ovl.Expression, /*complain*/ false, &found)) { if (DiagnoseUseOfDecl(fn, SrcExpr.get()->getBeginLoc())) { SrcExpr = ExprError(); return true; } // It is only correct to resolve to an instance method if we're // resolving a form that's permitted to be a pointer to member. // Otherwise we'll end up making a bound member expression, which // is illegal in all the contexts we resolve like this. if (!ovl.HasFormOfMemberPointer && isa(fn) && cast(fn)->isInstance()) { if (!complain) return false; Diag(ovl.Expression->getExprLoc(), diag::err_bound_member_function) << 0 << ovl.Expression->getSourceRange(); // TODO: I believe we only end up here if there's a mix of // static and non-static candidates (otherwise the expression // would have 'bound member' type, not 'overload' type). // Ideally we would note which candidate was chosen and why // the static candidates were rejected. SrcExpr = ExprError(); return true; } // Fix the expression to refer to 'fn'. SingleFunctionExpression = FixOverloadedFunctionReference(SrcExpr.get(), found, fn); // If desired, do function-to-pointer decay. if (doFunctionPointerConverion) { SingleFunctionExpression = DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.get()); if (SingleFunctionExpression.isInvalid()) { SrcExpr = ExprError(); return true; } } } if (!SingleFunctionExpression.isUsable()) { if (complain) { Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining) << ovl.Expression->getName() << DestTypeForComplaining << OpRangeForComplaining << ovl.Expression->getQualifierLoc().getSourceRange(); NoteAllOverloadCandidates(SrcExpr.get()); SrcExpr = ExprError(); return true; } return false; } SrcExpr = SingleFunctionExpression; return true; } /// Add a single candidate to the overload set. static void AddOverloadedCallCandidate(Sema &S, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool PartialOverloading, bool KnownValid) { NamedDecl *Callee = FoundDecl.getDecl(); if (isa(Callee)) Callee = cast(Callee)->getTargetDecl(); if (FunctionDecl *Func = dyn_cast(Callee)) { if (ExplicitTemplateArgs) { assert(!KnownValid && "Explicit template arguments?"); return; } // Prevent ill-formed function decls to be added as overload candidates. if (!dyn_cast(Func->getType()->getAs())) return; S.AddOverloadCandidate(Func, FoundDecl, Args, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading); return; } if (FunctionTemplateDecl *FuncTemplate = dyn_cast(Callee)) { S.AddTemplateOverloadCandidate(FuncTemplate, FoundDecl, ExplicitTemplateArgs, Args, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading); return; } assert(!KnownValid && "unhandled case in overloaded call candidate"); } /// Add the overload candidates named by callee and/or found by argument /// dependent lookup to the given overload set. void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool PartialOverloading) { #ifndef NDEBUG // Verify that ArgumentDependentLookup is consistent with the rules // in C++0x [basic.lookup.argdep]p3: // // Let X be the lookup set produced by unqualified lookup (3.4.1) // and let Y be the lookup set produced by argument dependent // lookup (defined as follows). If X contains // // -- a declaration of a class member, or // // -- a block-scope function declaration that is not a // using-declaration, or // // -- a declaration that is neither a function or a function // template // // then Y is empty. if (ULE->requiresADL()) { for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(), E = ULE->decls_end(); I != E; ++I) { assert(!(*I)->getDeclContext()->isRecord()); assert(isa(*I) || !(*I)->getDeclContext()->isFunctionOrMethod()); assert((*I)->getUnderlyingDecl()->isFunctionOrFunctionTemplate()); } } #endif // It would be nice to avoid this copy. TemplateArgumentListInfo TABuffer; TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr; if (ULE->hasExplicitTemplateArgs()) { ULE->copyTemplateArgumentsInto(TABuffer); ExplicitTemplateArgs = &TABuffer; } for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(), E = ULE->decls_end(); I != E; ++I) AddOverloadedCallCandidate(*this, I.getPair(), ExplicitTemplateArgs, Args, CandidateSet, PartialOverloading, /*KnownValid*/ true); if (ULE->requiresADL()) AddArgumentDependentLookupCandidates(ULE->getName(), ULE->getExprLoc(), Args, ExplicitTemplateArgs, CandidateSet, PartialOverloading); } /// Determine whether a declaration with the specified name could be moved into /// a different namespace. static bool canBeDeclaredInNamespace(const DeclarationName &Name) { switch (Name.getCXXOverloadedOperator()) { case OO_New: case OO_Array_New: case OO_Delete: case OO_Array_Delete: return false; default: return true; } } /// Attempt to recover from an ill-formed use of a non-dependent name in a /// template, where the non-dependent name was declared after the template /// was defined. This is common in code written for a compilers which do not /// correctly implement two-stage name lookup. /// /// Returns true if a viable candidate was found and a diagnostic was issued. static bool DiagnoseTwoPhaseLookup(Sema &SemaRef, SourceLocation FnLoc, const CXXScopeSpec &SS, LookupResult &R, OverloadCandidateSet::CandidateSetKind CSK, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef Args, bool *DoDiagnoseEmptyLookup = nullptr) { if (!SemaRef.inTemplateInstantiation() || !SS.isEmpty()) return false; for (DeclContext *DC = SemaRef.CurContext; DC; DC = DC->getParent()) { if (DC->isTransparentContext()) continue; SemaRef.LookupQualifiedName(R, DC); if (!R.empty()) { R.suppressDiagnostics(); if (isa(DC)) { // Don't diagnose names we find in classes; we get much better // diagnostics for these from DiagnoseEmptyLookup. R.clear(); if (DoDiagnoseEmptyLookup) *DoDiagnoseEmptyLookup = true; return false; } OverloadCandidateSet Candidates(FnLoc, CSK); for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) AddOverloadedCallCandidate(SemaRef, I.getPair(), ExplicitTemplateArgs, Args, Candidates, false, /*KnownValid*/ false); OverloadCandidateSet::iterator Best; if (Candidates.BestViableFunction(SemaRef, FnLoc, Best) != OR_Success) { // No viable functions. Don't bother the user with notes for functions // which don't work and shouldn't be found anyway. R.clear(); return false; } // Find the namespaces where ADL would have looked, and suggest // declaring the function there instead. Sema::AssociatedNamespaceSet AssociatedNamespaces; Sema::AssociatedClassSet AssociatedClasses; SemaRef.FindAssociatedClassesAndNamespaces(FnLoc, Args, AssociatedNamespaces, AssociatedClasses); Sema::AssociatedNamespaceSet SuggestedNamespaces; if (canBeDeclaredInNamespace(R.getLookupName())) { DeclContext *Std = SemaRef.getStdNamespace(); for (Sema::AssociatedNamespaceSet::iterator it = AssociatedNamespaces.begin(), end = AssociatedNamespaces.end(); it != end; ++it) { // Never suggest declaring a function within namespace 'std'. if (Std && Std->Encloses(*it)) continue; // Never suggest declaring a function within a namespace with a // reserved name, like __gnu_cxx. NamespaceDecl *NS = dyn_cast(*it); if (NS && NS->getQualifiedNameAsString().find("__") != std::string::npos) continue; SuggestedNamespaces.insert(*it); } } SemaRef.Diag(R.getNameLoc(), diag::err_not_found_by_two_phase_lookup) << R.getLookupName(); if (SuggestedNamespaces.empty()) { SemaRef.Diag(Best->Function->getLocation(), diag::note_not_found_by_two_phase_lookup) << R.getLookupName() << 0; } else if (SuggestedNamespaces.size() == 1) { SemaRef.Diag(Best->Function->getLocation(), diag::note_not_found_by_two_phase_lookup) << R.getLookupName() << 1 << *SuggestedNamespaces.begin(); } else { // FIXME: It would be useful to list the associated namespaces here, // but the diagnostics infrastructure doesn't provide a way to produce // a localized representation of a list of items. SemaRef.Diag(Best->Function->getLocation(), diag::note_not_found_by_two_phase_lookup) << R.getLookupName() << 2; } // Try to recover by calling this function. return true; } R.clear(); } return false; } /// Attempt to recover from ill-formed use of a non-dependent operator in a /// template, where the non-dependent operator was declared after the template /// was defined. /// /// Returns true if a viable candidate was found and a diagnostic was issued. static bool DiagnoseTwoPhaseOperatorLookup(Sema &SemaRef, OverloadedOperatorKind Op, SourceLocation OpLoc, ArrayRef Args) { DeclarationName OpName = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op); LookupResult R(SemaRef, OpName, OpLoc, Sema::LookupOperatorName); return DiagnoseTwoPhaseLookup(SemaRef, OpLoc, CXXScopeSpec(), R, OverloadCandidateSet::CSK_Operator, /*ExplicitTemplateArgs=*/nullptr, Args); } namespace { class BuildRecoveryCallExprRAII { Sema &SemaRef; public: BuildRecoveryCallExprRAII(Sema &S) : SemaRef(S) { assert(SemaRef.IsBuildingRecoveryCallExpr == false); SemaRef.IsBuildingRecoveryCallExpr = true; } ~BuildRecoveryCallExprRAII() { SemaRef.IsBuildingRecoveryCallExpr = false; } }; } /// Attempts to recover from a call where no functions were found. /// /// Returns true if new candidates were found. static ExprResult BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, MutableArrayRef Args, SourceLocation RParenLoc, bool EmptyLookup, bool AllowTypoCorrection) { // Do not try to recover if it is already building a recovery call. // This stops infinite loops for template instantiations like // // template auto foo(T t) -> decltype(foo(t)) {} // template auto foo(T t) -> decltype(foo(&t)) {} // if (SemaRef.IsBuildingRecoveryCallExpr) return ExprError(); BuildRecoveryCallExprRAII RCE(SemaRef); CXXScopeSpec SS; SS.Adopt(ULE->getQualifierLoc()); SourceLocation TemplateKWLoc = ULE->getTemplateKeywordLoc(); TemplateArgumentListInfo TABuffer; TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr; if (ULE->hasExplicitTemplateArgs()) { ULE->copyTemplateArgumentsInto(TABuffer); ExplicitTemplateArgs = &TABuffer; } LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(), Sema::LookupOrdinaryName); bool DoDiagnoseEmptyLookup = EmptyLookup; if (!DiagnoseTwoPhaseLookup( SemaRef, Fn->getExprLoc(), SS, R, OverloadCandidateSet::CSK_Normal, ExplicitTemplateArgs, Args, &DoDiagnoseEmptyLookup)) { NoTypoCorrectionCCC NoTypoValidator{}; FunctionCallFilterCCC FunctionCallValidator(SemaRef, Args.size(), ExplicitTemplateArgs != nullptr, dyn_cast(Fn)); CorrectionCandidateCallback &Validator = AllowTypoCorrection ? static_cast(FunctionCallValidator) : static_cast(NoTypoValidator); if (!DoDiagnoseEmptyLookup || SemaRef.DiagnoseEmptyLookup(S, SS, R, Validator, ExplicitTemplateArgs, Args)) return ExprError(); } assert(!R.empty() && "lookup results empty despite recovery"); // If recovery created an ambiguity, just bail out. if (R.isAmbiguous()) { R.suppressDiagnostics(); return ExprError(); } // Build an implicit member call if appropriate. Just drop the // casts and such from the call, we don't really care. ExprResult NewFn = ExprError(); if ((*R.begin())->isCXXClassMember()) NewFn = SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R, ExplicitTemplateArgs, S); else if (ExplicitTemplateArgs || TemplateKWLoc.isValid()) NewFn = SemaRef.BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, ExplicitTemplateArgs); else NewFn = SemaRef.BuildDeclarationNameExpr(SS, R, false); if (NewFn.isInvalid()) return ExprError(); // This shouldn't cause an infinite loop because we're giving it // an expression with viable lookup results, which should never // end up here. return SemaRef.BuildCallExpr(/*Scope*/ nullptr, NewFn.get(), LParenLoc, MultiExprArg(Args.data(), Args.size()), RParenLoc); } /// Constructs and populates an OverloadedCandidateSet from /// the given function. /// \returns true when an the ExprResult output parameter has been set. bool Sema::buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, MultiExprArg Args, SourceLocation RParenLoc, OverloadCandidateSet *CandidateSet, ExprResult *Result) { #ifndef NDEBUG if (ULE->requiresADL()) { // To do ADL, we must have found an unqualified name. assert(!ULE->getQualifier() && "qualified name with ADL"); // We don't perform ADL for implicit declarations of builtins. // Verify that this was correctly set up. FunctionDecl *F; if (ULE->decls_begin() != ULE->decls_end() && ULE->decls_begin() + 1 == ULE->decls_end() && (F = dyn_cast(*ULE->decls_begin())) && F->getBuiltinID() && F->isImplicit()) llvm_unreachable("performing ADL for builtin"); // We don't perform ADL in C. assert(getLangOpts().CPlusPlus && "ADL enabled in C"); } #endif UnbridgedCastsSet UnbridgedCasts; if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts)) { *Result = ExprError(); return true; } // Add the functions denoted by the callee to the set of candidate // functions, including those from argument-dependent lookup. AddOverloadedCallCandidates(ULE, Args, *CandidateSet); if (getLangOpts().MSVCCompat && CurContext->isDependentContext() && !isSFINAEContext() && (isa(CurContext) || isa(CurContext))) { OverloadCandidateSet::iterator Best; if (CandidateSet->empty() || CandidateSet->BestViableFunction(*this, Fn->getBeginLoc(), Best) == OR_No_Viable_Function) { // In Microsoft mode, if we are inside a template class member function // then create a type dependent CallExpr. The goal is to postpone name // lookup to instantiation time to be able to search into type dependent // base classes. CallExpr *CE = CallExpr::Create(Context, Fn, Args, Context.DependentTy, VK_RValue, RParenLoc); CE->setTypeDependent(true); CE->setValueDependent(true); CE->setInstantiationDependent(true); *Result = CE; return true; } } if (CandidateSet->empty()) return false; UnbridgedCasts.restore(); return false; } /// FinishOverloadedCallExpr - given an OverloadCandidateSet, builds and returns /// the completed call expression. If overload resolution fails, emits /// diagnostics and returns ExprError() static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig, OverloadCandidateSet *CandidateSet, OverloadCandidateSet::iterator *Best, OverloadingResult OverloadResult, bool AllowTypoCorrection) { if (CandidateSet->empty()) return BuildRecoveryCallExpr(SemaRef, S, Fn, ULE, LParenLoc, Args, RParenLoc, /*EmptyLookup=*/true, AllowTypoCorrection); switch (OverloadResult) { case OR_Success: { FunctionDecl *FDecl = (*Best)->Function; SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl); if (SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc())) return ExprError(); Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl); return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, RParenLoc, ExecConfig, /*IsExecConfig=*/false, (*Best)->IsADLCandidate); } case OR_No_Viable_Function: { // Try to recover by looking for viable functions which the user might // have meant to call. ExprResult Recovery = BuildRecoveryCallExpr(SemaRef, S, Fn, ULE, LParenLoc, Args, RParenLoc, /*EmptyLookup=*/false, AllowTypoCorrection); if (!Recovery.isInvalid()) return Recovery; // If the user passes in a function that we can't take the address of, we // generally end up emitting really bad error messages. Here, we attempt to // emit better ones. for (const Expr *Arg : Args) { if (!Arg->getType()->isFunctionType()) continue; if (auto *DRE = dyn_cast(Arg->IgnoreParenImpCasts())) { auto *FD = dyn_cast(DRE->getDecl()); if (FD && !SemaRef.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, Arg->getExprLoc())) return ExprError(); } } CandidateSet->NoteCandidates( PartialDiagnosticAt( Fn->getBeginLoc(), SemaRef.PDiag(diag::err_ovl_no_viable_function_in_call) << ULE->getName() << Fn->getSourceRange()), SemaRef, OCD_AllCandidates, Args); break; } case OR_Ambiguous: CandidateSet->NoteCandidates( PartialDiagnosticAt(Fn->getBeginLoc(), SemaRef.PDiag(diag::err_ovl_ambiguous_call) << ULE->getName() << Fn->getSourceRange()), SemaRef, OCD_AmbiguousCandidates, Args); break; case OR_Deleted: { CandidateSet->NoteCandidates( PartialDiagnosticAt(Fn->getBeginLoc(), SemaRef.PDiag(diag::err_ovl_deleted_call) << ULE->getName() << Fn->getSourceRange()), SemaRef, OCD_AllCandidates, Args); // We emitted an error for the unavailable/deleted function call but keep // the call in the AST. FunctionDecl *FDecl = (*Best)->Function; Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl); return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, RParenLoc, ExecConfig, /*IsExecConfig=*/false, (*Best)->IsADLCandidate); } } // Overload resolution failed. return ExprError(); } static void markUnaddressableCandidatesUnviable(Sema &S, OverloadCandidateSet &CS) { for (auto I = CS.begin(), E = CS.end(); I != E; ++I) { if (I->Viable && !S.checkAddressOfFunctionIsAvailable(I->Function, /*Complain=*/false)) { I->Viable = false; I->FailureKind = ovl_fail_addr_not_available; } } } /// BuildOverloadedCallExpr - Given the call expression that calls Fn /// (which eventually refers to the declaration Func) and the call /// arguments Args/NumArgs, attempt to resolve the function call down /// to a specific function. If overload resolution succeeds, returns /// the call expression produced by overload resolution. /// Otherwise, emits diagnostics and returns ExprError. ExprResult Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig, bool AllowTypoCorrection, bool CalleesAddressIsTaken) { OverloadCandidateSet CandidateSet(Fn->getExprLoc(), OverloadCandidateSet::CSK_Normal); ExprResult result; if (buildOverloadedCallSet(S, Fn, ULE, Args, LParenLoc, &CandidateSet, &result)) return result; // If the user handed us something like `(&Foo)(Bar)`, we need to ensure that // functions that aren't addressible are considered unviable. if (CalleesAddressIsTaken) markUnaddressableCandidatesUnviable(*this, CandidateSet); OverloadCandidateSet::iterator Best; OverloadingResult OverloadResult = CandidateSet.BestViableFunction(*this, Fn->getBeginLoc(), Best); return FinishOverloadedCallExpr(*this, S, Fn, ULE, LParenLoc, Args, RParenLoc, ExecConfig, &CandidateSet, &Best, OverloadResult, AllowTypoCorrection); } static bool IsOverloaded(const UnresolvedSetImpl &Functions) { return Functions.size() > 1 || (Functions.size() == 1 && isa(*Functions.begin())); } /// Create a unary operation that may resolve to an overloaded /// operator. /// /// \param OpLoc The location of the operator itself (e.g., '*'). /// /// \param Opc The UnaryOperatorKind that describes this operator. /// /// \param Fns The set of non-member functions that will be /// considered by overload resolution. The caller needs to build this /// set based on the context using, e.g., /// LookupOverloadedOperatorName() and ArgumentDependentLookup(). This /// set should not contain any member functions; those will be added /// by CreateOverloadedUnaryOp(). /// /// \param Input The input argument. ExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *Input, bool PerformADL) { OverloadedOperatorKind Op = UnaryOperator::getOverloadedOperator(Opc); assert(Op != OO_None && "Invalid opcode for overloaded unary operator"); DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); // TODO: provide better source location info. DeclarationNameInfo OpNameInfo(OpName, OpLoc); if (checkPlaceholderForOverload(*this, Input)) return ExprError(); Expr *Args[2] = { Input, nullptr }; unsigned NumArgs = 1; // For post-increment and post-decrement, add the implicit '0' as // the second argument, so that we know this is a post-increment or // post-decrement. if (Opc == UO_PostInc || Opc == UO_PostDec) { llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false); Args[1] = IntegerLiteral::Create(Context, Zero, Context.IntTy, SourceLocation()); NumArgs = 2; } ArrayRef ArgsArray(Args, NumArgs); if (Input->isTypeDependent()) { if (Fns.empty()) return new (Context) UnaryOperator(Input, Opc, Context.DependentTy, VK_RValue, OK_Ordinary, OpLoc, false); CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create( Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); return CXXOperatorCallExpr::Create(Context, Op, Fn, ArgsArray, Context.DependentTy, VK_RValue, OpLoc, FPOptions()); } // Build an empty overload set. OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator); // Add the candidates from the given function set. AddNonMemberOperatorCandidates(Fns, ArgsArray, CandidateSet); // Add operator candidates that are member functions. AddMemberOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); // Add candidates from ADL. if (PerformADL) { AddArgumentDependentLookupCandidates(OpName, OpLoc, ArgsArray, /*ExplicitTemplateArgs*/nullptr, CandidateSet); } // Add builtin operator candidates. AddBuiltinOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) { case OR_Success: { // We found a built-in operator or an overloaded operator. FunctionDecl *FnDecl = Best->Function; if (FnDecl) { Expr *Base = nullptr; // We matched an overloaded operator. Build a call to that // operator. // Convert the arguments. if (CXXMethodDecl *Method = dyn_cast(FnDecl)) { CheckMemberOperatorAccess(OpLoc, Args[0], nullptr, Best->FoundDecl); ExprResult InputRes = PerformObjectArgumentInitialization(Input, /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (InputRes.isInvalid()) return ExprError(); Base = Input = InputRes.get(); } else { // Convert the arguments. ExprResult InputInit = PerformCopyInitialization(InitializedEntity::InitializeParameter( Context, FnDecl->getParamDecl(0)), SourceLocation(), Input); if (InputInit.isInvalid()) return ExprError(); Input = InputInit.get(); } // Build the actual expression node. ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, Best->FoundDecl, Base, HadMultipleCandidates, OpLoc); if (FnExpr.isInvalid()) return ExprError(); // Determine the result type. QualType ResultTy = FnDecl->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); Args[0] = Input; CallExpr *TheCall = CXXOperatorCallExpr::Create( Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc, FPOptions(), Best->IsADLCandidate); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) return ExprError(); if (CheckFunctionCall(FnDecl, TheCall, FnDecl->getType()->castAs())) return ExprError(); return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in // operator node. ExprResult InputRes = PerformImplicitConversion( Input, Best->BuiltinParamTypes[0], Best->Conversions[0], AA_Passing, CCK_ForBuiltinOverloadedOp); if (InputRes.isInvalid()) return ExprError(); Input = InputRes.get(); break; } } case OR_No_Viable_Function: // This is an erroneous use of an operator which can be overloaded by // a non-member function. Check for non-member operators which were // defined too late to be candidates. if (DiagnoseTwoPhaseOperatorLookup(*this, Op, OpLoc, ArgsArray)) // FIXME: Recover by calling the found function. return ExprError(); // No viable function; fall through to handling this as a // built-in operator, which will produce an error message for us. break; case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_unary) << UnaryOperator::getOpcodeStr(Opc) << Input->getType() << Input->getSourceRange()), *this, OCD_AmbiguousCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper) << UnaryOperator::getOpcodeStr(Opc) << Input->getSourceRange()), *this, OCD_AllCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); } // Either we found no viable overloaded operator or we matched a // built-in operator. In either case, fall through to trying to // build a built-in operation. return CreateBuiltinUnaryOp(OpLoc, Opc, Input); } /// Perform lookup for an overloaded binary operator. void Sema::LookupOverloadedBinOp(OverloadCandidateSet &CandidateSet, OverloadedOperatorKind Op, const UnresolvedSetImpl &Fns, ArrayRef Args, bool PerformADL) { SourceLocation OpLoc = CandidateSet.getLocation(); OverloadedOperatorKind ExtraOp = CandidateSet.getRewriteInfo().AllowRewrittenCandidates ? getRewrittenOverloadedOperator(Op) : OO_None; // Add the candidates from the given function set. This also adds the // rewritten candidates using these functions if necessary. AddNonMemberOperatorCandidates(Fns, Args, CandidateSet); // Add operator candidates that are member functions. AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet); if (CandidateSet.getRewriteInfo().shouldAddReversed(Op)) AddMemberOperatorCandidates(Op, OpLoc, {Args[1], Args[0]}, CandidateSet, OverloadCandidateParamOrder::Reversed); // In C++20, also add any rewritten member candidates. if (ExtraOp) { AddMemberOperatorCandidates(ExtraOp, OpLoc, Args, CandidateSet); if (CandidateSet.getRewriteInfo().shouldAddReversed(ExtraOp)) AddMemberOperatorCandidates(ExtraOp, OpLoc, {Args[1], Args[0]}, CandidateSet, OverloadCandidateParamOrder::Reversed); } // Add candidates from ADL. Per [over.match.oper]p2, this lookup is not // performed for an assignment operator (nor for operator[] nor operator->, // which don't get here). if (Op != OO_Equal && PerformADL) { DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); AddArgumentDependentLookupCandidates(OpName, OpLoc, Args, /*ExplicitTemplateArgs*/ nullptr, CandidateSet); if (ExtraOp) { DeclarationName ExtraOpName = Context.DeclarationNames.getCXXOperatorName(ExtraOp); AddArgumentDependentLookupCandidates(ExtraOpName, OpLoc, Args, /*ExplicitTemplateArgs*/ nullptr, CandidateSet); } } // Add builtin operator candidates. // // FIXME: We don't add any rewritten candidates here. This is strictly // incorrect; a builtin candidate could be hidden by a non-viable candidate, // resulting in our selecting a rewritten builtin candidate. For example: // // enum class E { e }; // bool operator!=(E, E) requires false; // bool k = E::e != E::e; // // ... should select the rewritten builtin candidate 'operator==(E, E)'. But // it seems unreasonable to consider rewritten builtin candidates. A core // issue has been filed proposing to removed this requirement. AddBuiltinOperatorCandidates(Op, OpLoc, Args, CandidateSet); } /// Create a binary operation that may resolve to an overloaded /// operator. /// /// \param OpLoc The location of the operator itself (e.g., '+'). /// /// \param Opc The BinaryOperatorKind that describes this operator. /// /// \param Fns The set of non-member functions that will be /// considered by overload resolution. The caller needs to build this /// set based on the context using, e.g., /// LookupOverloadedOperatorName() and ArgumentDependentLookup(). This /// set should not contain any member functions; those will be added /// by CreateOverloadedBinOp(). /// /// \param LHS Left-hand argument. /// \param RHS Right-hand argument. /// \param PerformADL Whether to consider operator candidates found by ADL. /// \param AllowRewrittenCandidates Whether to consider candidates found by /// C++20 operator rewrites. /// \param DefaultedFn If we are synthesizing a defaulted operator function, /// the function in question. Such a function is never a candidate in /// our overload resolution. This also enables synthesizing a three-way /// comparison from < and == as described in C++20 [class.spaceship]p1. ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *LHS, Expr *RHS, bool PerformADL, bool AllowRewrittenCandidates, FunctionDecl *DefaultedFn) { Expr *Args[2] = { LHS, RHS }; LHS=RHS=nullptr; // Please use only Args instead of LHS/RHS couple if (!getLangOpts().CPlusPlus2a) AllowRewrittenCandidates = false; OverloadedOperatorKind Op = BinaryOperator::getOverloadedOperator(Opc); // If either side is type-dependent, create an appropriate dependent // expression. if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) { if (Fns.empty()) { // If there are no functions to store, just build a dependent // BinaryOperator or CompoundAssignment. if (Opc <= BO_Assign || Opc > BO_OrAssign) return new (Context) BinaryOperator( Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary, OpLoc, FPFeatures); return new (Context) CompoundAssignOperator( Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, OK_Ordinary, Context.DependentTy, Context.DependentTy, OpLoc, FPFeatures); } // FIXME: save results of ADL from here? CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators // TODO: provide better source location info in DNLoc component. DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); DeclarationNameInfo OpNameInfo(OpName, OpLoc); UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create( Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ PerformADL, IsOverloaded(Fns), Fns.begin(), Fns.end()); return CXXOperatorCallExpr::Create(Context, Op, Fn, Args, Context.DependentTy, VK_RValue, OpLoc, FPFeatures); } // Always do placeholder-like conversions on the RHS. if (checkPlaceholderForOverload(*this, Args[1])) return ExprError(); // Do placeholder-like conversion on the LHS; note that we should // not get here with a PseudoObject LHS. assert(Args[0]->getObjectKind() != OK_ObjCProperty); if (checkPlaceholderForOverload(*this, Args[0])) return ExprError(); // If this is the assignment operator, we only perform overload resolution // if the left-hand side is a class or enumeration type. This is actually // a hack. The standard requires that we do overload resolution between the // various built-in candidates, but as DR507 points out, this can lead to // problems. So we do it this way, which pretty much follows what GCC does. // Note that we go the traditional code path for compound assignment forms. if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType()) return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); // If this is the .* operator, which is not overloadable, just // create a built-in binary operator. if (Opc == BO_PtrMemD) return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); // Build the overload set. OverloadCandidateSet CandidateSet( OpLoc, OverloadCandidateSet::CSK_Operator, OverloadCandidateSet::OperatorRewriteInfo(Op, AllowRewrittenCandidates)); if (DefaultedFn) CandidateSet.exclude(DefaultedFn); LookupOverloadedBinOp(CandidateSet, Op, Fns, Args, PerformADL); bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) { case OR_Success: { // We found a built-in operator or an overloaded operator. FunctionDecl *FnDecl = Best->Function; bool IsReversed = (Best->RewriteKind & CRK_Reversed); if (IsReversed) std::swap(Args[0], Args[1]); if (FnDecl) { Expr *Base = nullptr; // We matched an overloaded operator. Build a call to that // operator. OverloadedOperatorKind ChosenOp = FnDecl->getDeclName().getCXXOverloadedOperator(); // C++2a [over.match.oper]p9: // If a rewritten operator== candidate is selected by overload // resolution for an operator@, its return type shall be cv bool if (Best->RewriteKind && ChosenOp == OO_EqualEqual && !FnDecl->getReturnType()->isBooleanType()) { Diag(OpLoc, diag::err_ovl_rewrite_equalequal_not_bool) << FnDecl->getReturnType() << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getSourceRange() << Args[1]->getSourceRange(); Diag(FnDecl->getLocation(), diag::note_declared_at); return ExprError(); } if (AllowRewrittenCandidates && !IsReversed && CandidateSet.getRewriteInfo().shouldAddReversed(ChosenOp)) { // We could have reversed this operator, but didn't. Check if the // reversed form was a viable candidate, and if so, if it had a // better conversion for either parameter. If so, this call is // formally ambiguous, and allowing it is an extension. for (OverloadCandidate &Cand : CandidateSet) { if (Cand.Viable && Cand.Function == FnDecl && Cand.RewriteKind & CRK_Reversed) { for (unsigned ArgIdx = 0; ArgIdx < 2; ++ArgIdx) { if (CompareImplicitConversionSequences( *this, OpLoc, Cand.Conversions[ArgIdx], Best->Conversions[ArgIdx]) == ImplicitConversionSequence::Better) { Diag(OpLoc, diag::ext_ovl_ambiguous_oper_binary_reversed) << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getType() << Args[1]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange(); Diag(FnDecl->getLocation(), diag::note_ovl_ambiguous_oper_binary_reversed_candidate); } } break; } } } // Convert the arguments. if (CXXMethodDecl *Method = dyn_cast(FnDecl)) { // Best->Access is only meaningful for class members. CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Best->FoundDecl); ExprResult Arg1 = PerformCopyInitialization( InitializedEntity::InitializeParameter(Context, FnDecl->getParamDecl(0)), SourceLocation(), Args[1]); if (Arg1.isInvalid()) return ExprError(); ExprResult Arg0 = PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (Arg0.isInvalid()) return ExprError(); Base = Args[0] = Arg0.getAs(); Args[1] = RHS = Arg1.getAs(); } else { // Convert the arguments. ExprResult Arg0 = PerformCopyInitialization( InitializedEntity::InitializeParameter(Context, FnDecl->getParamDecl(0)), SourceLocation(), Args[0]); if (Arg0.isInvalid()) return ExprError(); ExprResult Arg1 = PerformCopyInitialization( InitializedEntity::InitializeParameter(Context, FnDecl->getParamDecl(1)), SourceLocation(), Args[1]); if (Arg1.isInvalid()) return ExprError(); Args[0] = LHS = Arg0.getAs(); Args[1] = RHS = Arg1.getAs(); } // Build the actual expression node. ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, Best->FoundDecl, Base, HadMultipleCandidates, OpLoc); if (FnExpr.isInvalid()) return ExprError(); // Determine the result type. QualType ResultTy = FnDecl->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( Context, ChosenOp, FnExpr.get(), Args, ResultTy, VK, OpLoc, FPFeatures, Best->IsADLCandidate); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) return ExprError(); ArrayRef ArgsArray(Args, 2); const Expr *ImplicitThis = nullptr; // Cut off the implicit 'this'. if (isa(FnDecl)) { ImplicitThis = ArgsArray[0]; ArgsArray = ArgsArray.slice(1); } // Check for a self move. if (Op == OO_Equal) DiagnoseSelfMove(Args[0], Args[1], OpLoc); checkCall(FnDecl, nullptr, ImplicitThis, ArgsArray, isa(FnDecl), OpLoc, TheCall->getSourceRange(), VariadicDoesNotApply); ExprResult R = MaybeBindToTemporary(TheCall); if (R.isInvalid()) return ExprError(); // For a rewritten candidate, we've already reversed the arguments // if needed. Perform the rest of the rewrite now. if ((Best->RewriteKind & CRK_DifferentOperator) || (Op == OO_Spaceship && IsReversed)) { if (Op == OO_ExclaimEqual) { assert(ChosenOp == OO_EqualEqual && "unexpected operator name"); R = CreateBuiltinUnaryOp(OpLoc, UO_LNot, R.get()); } else { assert(ChosenOp == OO_Spaceship && "unexpected operator name"); llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false); Expr *ZeroLiteral = IntegerLiteral::Create(Context, Zero, Context.IntTy, OpLoc); Sema::CodeSynthesisContext Ctx; Ctx.Kind = Sema::CodeSynthesisContext::RewritingOperatorAsSpaceship; Ctx.Entity = FnDecl; pushCodeSynthesisContext(Ctx); R = CreateOverloadedBinOp( OpLoc, Opc, Fns, IsReversed ? ZeroLiteral : R.get(), IsReversed ? R.get() : ZeroLiteral, PerformADL, /*AllowRewrittenCandidates=*/false); popCodeSynthesisContext(); } if (R.isInvalid()) return ExprError(); } else { assert(ChosenOp == Op && "unexpected operator name"); } // Make a note in the AST if we did any rewriting. if (Best->RewriteKind != CRK_None) R = new (Context) CXXRewrittenBinaryOperator(R.get(), IsReversed); return R; } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in // operator node. ExprResult ArgsRes0 = PerformImplicitConversion( Args[0], Best->BuiltinParamTypes[0], Best->Conversions[0], AA_Passing, CCK_ForBuiltinOverloadedOp); if (ArgsRes0.isInvalid()) return ExprError(); Args[0] = ArgsRes0.get(); ExprResult ArgsRes1 = PerformImplicitConversion( Args[1], Best->BuiltinParamTypes[1], Best->Conversions[1], AA_Passing, CCK_ForBuiltinOverloadedOp); if (ArgsRes1.isInvalid()) return ExprError(); Args[1] = ArgsRes1.get(); break; } } case OR_No_Viable_Function: { // C++ [over.match.oper]p9: // If the operator is the operator , [...] and there are no // viable functions, then the operator is assumed to be the // built-in operator and interpreted according to clause 5. if (Opc == BO_Comma) break; // When defaulting an 'operator<=>', we can try to synthesize a three-way // compare result using '==' and '<'. if (DefaultedFn && Opc == BO_Cmp) { ExprResult E = BuildSynthesizedThreeWayComparison(OpLoc, Fns, Args[0], Args[1], DefaultedFn); if (E.isInvalid() || E.isUsable()) return E; } // For class as left operand for assignment or compound assignment // operator do not fall through to handling in built-in, but report that // no overloaded assignment operator found ExprResult Result = ExprError(); StringRef OpcStr = BinaryOperator::getOpcodeStr(Opc); auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates, Args, OpLoc); if (Args[0]->getType()->isRecordType() && Opc >= BO_Assign && Opc <= BO_OrAssign) { Diag(OpLoc, diag::err_ovl_no_viable_oper) << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getSourceRange() << Args[1]->getSourceRange(); if (Args[0]->getType()->isIncompleteType()) { Diag(OpLoc, diag::note_assign_lhs_incomplete) << Args[0]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange(); } } else { // This is an erroneous use of an operator which can be overloaded by // a non-member function. Check for non-member operators which were // defined too late to be candidates. if (DiagnoseTwoPhaseOperatorLookup(*this, Op, OpLoc, Args)) // FIXME: Recover by calling the found function. return ExprError(); // No viable function; try to create a built-in operation, which will // produce an error. Then, show the non-viable candidates. Result = CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); } assert(Result.isInvalid() && "C++ binary operator overloading is missing candidates!"); CandidateSet.NoteCandidates(*this, Args, Cands, OpcStr, OpLoc); return Result; } case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_binary) << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getType() << Args[1]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange()), *this, OCD_AmbiguousCandidates, Args, BinaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); case OR_Deleted: if (isImplicitlyDeleted(Best->Function)) { FunctionDecl *DeletedFD = Best->Function; DefaultedFunctionKind DFK = getDefaultedFunctionKind(DeletedFD); if (DFK.isSpecialMember()) { Diag(OpLoc, diag::err_ovl_deleted_special_oper) << Args[0]->getType() << DFK.asSpecialMember(); } else { assert(DFK.isComparison()); Diag(OpLoc, diag::err_ovl_deleted_comparison) << Args[0]->getType() << DeletedFD; } // The user probably meant to call this special member. Just // explain why it's deleted. NoteDeletedFunction(DeletedFD); return ExprError(); } CandidateSet.NoteCandidates( PartialDiagnosticAt( OpLoc, PDiag(diag::err_ovl_deleted_oper) << getOperatorSpelling(Best->Function->getDeclName() .getCXXOverloadedOperator()) << Args[0]->getSourceRange() << Args[1]->getSourceRange()), *this, OCD_AllCandidates, Args, BinaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); } // We matched a built-in operator; build it. return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); } ExprResult Sema::BuildSynthesizedThreeWayComparison( SourceLocation OpLoc, const UnresolvedSetImpl &Fns, Expr *LHS, Expr *RHS, FunctionDecl *DefaultedFn) { const ComparisonCategoryInfo *Info = Context.CompCategories.lookupInfoForType(DefaultedFn->getReturnType()); // If we're not producing a known comparison category type, we can't // synthesize a three-way comparison. Let the caller diagnose this. if (!Info) return ExprResult((Expr*)nullptr); // If we ever want to perform this synthesis more generally, we will need to // apply the temporary materialization conversion to the operands. assert(LHS->isGLValue() && RHS->isGLValue() && "cannot use prvalue expressions more than once"); Expr *OrigLHS = LHS; Expr *OrigRHS = RHS; // Replace the LHS and RHS with OpaqueValueExprs; we're going to refer to // each of them multiple times below. LHS = new (Context) OpaqueValueExpr(LHS->getExprLoc(), LHS->getType(), LHS->getValueKind(), LHS->getObjectKind(), LHS); RHS = new (Context) OpaqueValueExpr(RHS->getExprLoc(), RHS->getType(), RHS->getValueKind(), RHS->getObjectKind(), RHS); ExprResult Eq = CreateOverloadedBinOp(OpLoc, BO_EQ, Fns, LHS, RHS, true, true, DefaultedFn); if (Eq.isInvalid()) return ExprError(); ExprResult Less = CreateOverloadedBinOp(OpLoc, BO_LT, Fns, LHS, RHS, true, true, DefaultedFn); if (Less.isInvalid()) return ExprError(); ExprResult Greater; if (Info->isPartial()) { Greater = CreateOverloadedBinOp(OpLoc, BO_LT, Fns, RHS, LHS, true, true, DefaultedFn); if (Greater.isInvalid()) return ExprError(); } // Form the list of comparisons we're going to perform. struct Comparison { ExprResult Cmp; ComparisonCategoryResult Result; } Comparisons[4] = { {Eq, Info->isStrong() ? ComparisonCategoryResult::Equal : ComparisonCategoryResult::Equivalent}, {Less, ComparisonCategoryResult::Less}, {Greater, ComparisonCategoryResult::Greater}, {ExprResult(), ComparisonCategoryResult::Unordered}, }; int I = Info->isPartial() ? 3 : 2; // Combine the comparisons with suitable conditional expressions. ExprResult Result; for (; I >= 0; --I) { // Build a reference to the comparison category constant. auto *VI = Info->lookupValueInfo(Comparisons[I].Result); // FIXME: Missing a constant for a comparison category. Diagnose this? if (!VI) return ExprResult((Expr*)nullptr); ExprResult ThisResult = BuildDeclarationNameExpr(CXXScopeSpec(), DeclarationNameInfo(), VI->VD); if (ThisResult.isInvalid()) return ExprError(); // Build a conditional unless this is the final case. if (Result.get()) { Result = ActOnConditionalOp(OpLoc, OpLoc, Comparisons[I].Cmp.get(), ThisResult.get(), Result.get()); if (Result.isInvalid()) return ExprError(); } else { Result = ThisResult; } } // Build a PseudoObjectExpr to model the rewriting of an <=> operator, and to // bind the OpaqueValueExprs before they're (repeatedly) used. Expr *SyntacticForm = new (Context) BinaryOperator(OrigLHS, OrigRHS, BO_Cmp, Result.get()->getType(), Result.get()->getValueKind(), Result.get()->getObjectKind(), OpLoc, FPFeatures); Expr *SemanticForm[] = {LHS, RHS, Result.get()}; return PseudoObjectExpr::Create(Context, SyntacticForm, SemanticForm, 2); } ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, SourceLocation RLoc, Expr *Base, Expr *Idx) { Expr *Args[2] = { Base, Idx }; DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Subscript); // If either side is type-dependent, create an appropriate dependent // expression. if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) { CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators // CHECKME: no 'operator' keyword? DeclarationNameInfo OpNameInfo(OpName, LLoc); OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc)); UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create(Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ true, /*Overloaded*/ false, UnresolvedSetIterator(), UnresolvedSetIterator()); // Can't add any actual overloads yet return CXXOperatorCallExpr::Create(Context, OO_Subscript, Fn, Args, Context.DependentTy, VK_RValue, RLoc, FPOptions()); } // Handle placeholders on both operands. if (checkPlaceholderForOverload(*this, Args[0])) return ExprError(); if (checkPlaceholderForOverload(*this, Args[1])) return ExprError(); // Build an empty overload set. OverloadCandidateSet CandidateSet(LLoc, OverloadCandidateSet::CSK_Operator); // Subscript can only be overloaded as a member function. // Add operator candidates that are member functions. AddMemberOperatorCandidates(OO_Subscript, LLoc, Args, CandidateSet); // Add builtin operator candidates. AddBuiltinOperatorCandidates(OO_Subscript, LLoc, Args, CandidateSet); bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, LLoc, Best)) { case OR_Success: { // We found a built-in operator or an overloaded operator. FunctionDecl *FnDecl = Best->Function; if (FnDecl) { // We matched an overloaded operator. Build a call to that // operator. CheckMemberOperatorAccess(LLoc, Args[0], Args[1], Best->FoundDecl); // Convert the arguments. CXXMethodDecl *Method = cast(FnDecl); ExprResult Arg0 = PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (Arg0.isInvalid()) return ExprError(); Args[0] = Arg0.get(); // Convert the arguments. ExprResult InputInit = PerformCopyInitialization(InitializedEntity::InitializeParameter( Context, FnDecl->getParamDecl(0)), SourceLocation(), Args[1]); if (InputInit.isInvalid()) return ExprError(); Args[1] = InputInit.getAs(); // Build the actual expression node. DeclarationNameInfo OpLocInfo(OpName, LLoc); OpLocInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc)); ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, Best->FoundDecl, Base, HadMultipleCandidates, OpLocInfo.getLoc(), OpLocInfo.getInfo()); if (FnExpr.isInvalid()) return ExprError(); // Determine the result type QualType ResultTy = FnDecl->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(Context, OO_Subscript, FnExpr.get(), Args, ResultTy, VK, RLoc, FPOptions()); if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl)) return ExprError(); if (CheckFunctionCall(Method, TheCall, Method->getType()->castAs())) return ExprError(); return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in // operator node. ExprResult ArgsRes0 = PerformImplicitConversion( Args[0], Best->BuiltinParamTypes[0], Best->Conversions[0], AA_Passing, CCK_ForBuiltinOverloadedOp); if (ArgsRes0.isInvalid()) return ExprError(); Args[0] = ArgsRes0.get(); ExprResult ArgsRes1 = PerformImplicitConversion( Args[1], Best->BuiltinParamTypes[1], Best->Conversions[1], AA_Passing, CCK_ForBuiltinOverloadedOp); if (ArgsRes1.isInvalid()) return ExprError(); Args[1] = ArgsRes1.get(); break; } } case OR_No_Viable_Function: { PartialDiagnostic PD = CandidateSet.empty() ? (PDiag(diag::err_ovl_no_oper) << Args[0]->getType() << /*subscript*/ 0 << Args[0]->getSourceRange() << Args[1]->getSourceRange()) : (PDiag(diag::err_ovl_no_viable_subscript) << Args[0]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange()); CandidateSet.NoteCandidates(PartialDiagnosticAt(LLoc, PD), *this, OCD_AllCandidates, Args, "[]", LLoc); return ExprError(); } case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(LLoc, PDiag(diag::err_ovl_ambiguous_oper_binary) << "[]" << Args[0]->getType() << Args[1]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange()), *this, OCD_AmbiguousCandidates, Args, "[]", LLoc); return ExprError(); case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(LLoc, PDiag(diag::err_ovl_deleted_oper) << "[]" << Args[0]->getSourceRange() << Args[1]->getSourceRange()), *this, OCD_AllCandidates, Args, "[]", LLoc); return ExprError(); } // We matched a built-in operator; build it. return CreateBuiltinArraySubscriptExpr(Args[0], LLoc, Args[1], RLoc); } /// BuildCallToMemberFunction - Build a call to a member /// function. MemExpr is the expression that refers to the member /// function (and includes the object parameter), Args/NumArgs are the /// arguments to the function call (not including the object /// parameter). The caller needs to validate that the member /// expression refers to a non-static member function or an overloaded /// member function. ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc) { assert(MemExprE->getType() == Context.BoundMemberTy || MemExprE->getType() == Context.OverloadTy); // Dig out the member expression. This holds both the object // argument and the member function we're referring to. Expr *NakedMemExpr = MemExprE->IgnoreParens(); // Determine whether this is a call to a pointer-to-member function. if (BinaryOperator *op = dyn_cast(NakedMemExpr)) { assert(op->getType() == Context.BoundMemberTy); assert(op->getOpcode() == BO_PtrMemD || op->getOpcode() == BO_PtrMemI); QualType fnType = op->getRHS()->getType()->castAs()->getPointeeType(); const FunctionProtoType *proto = fnType->castAs(); QualType resultType = proto->getCallResultType(Context); ExprValueKind valueKind = Expr::getValueKindForType(proto->getReturnType()); // Check that the object type isn't more qualified than the // member function we're calling. Qualifiers funcQuals = proto->getMethodQuals(); QualType objectType = op->getLHS()->getType(); if (op->getOpcode() == BO_PtrMemI) objectType = objectType->castAs()->getPointeeType(); Qualifiers objectQuals = objectType.getQualifiers(); Qualifiers difference = objectQuals - funcQuals; difference.removeObjCGCAttr(); difference.removeAddressSpace(); if (difference) { std::string qualsString = difference.getAsString(); Diag(LParenLoc, diag::err_pointer_to_member_call_drops_quals) << fnType.getUnqualifiedType() << qualsString << (qualsString.find(' ') == std::string::npos ? 1 : 2); } CXXMemberCallExpr *call = CXXMemberCallExpr::Create(Context, MemExprE, Args, resultType, valueKind, RParenLoc, proto->getNumParams()); if (CheckCallReturnType(proto->getReturnType(), op->getRHS()->getBeginLoc(), call, nullptr)) return ExprError(); if (ConvertArgumentsForCall(call, op, nullptr, proto, Args, RParenLoc)) return ExprError(); if (CheckOtherCall(call, proto)) return ExprError(); return MaybeBindToTemporary(call); } if (isa(NakedMemExpr)) return CallExpr::Create(Context, MemExprE, Args, Context.VoidTy, VK_RValue, RParenLoc); UnbridgedCastsSet UnbridgedCasts; if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts)) return ExprError(); MemberExpr *MemExpr; CXXMethodDecl *Method = nullptr; DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_public); NestedNameSpecifier *Qualifier = nullptr; if (isa(NakedMemExpr)) { MemExpr = cast(NakedMemExpr); Method = cast(MemExpr->getMemberDecl()); FoundDecl = MemExpr->getFoundDecl(); Qualifier = MemExpr->getQualifier(); UnbridgedCasts.restore(); } else { UnresolvedMemberExpr *UnresExpr = cast(NakedMemExpr); Qualifier = UnresExpr->getQualifier(); QualType ObjectType = UnresExpr->getBaseType(); Expr::Classification ObjectClassification = UnresExpr->isArrow()? Expr::Classification::makeSimpleLValue() : UnresExpr->getBase()->Classify(Context); // Add overload candidates OverloadCandidateSet CandidateSet(UnresExpr->getMemberLoc(), OverloadCandidateSet::CSK_Normal); // FIXME: avoid copy. TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr; if (UnresExpr->hasExplicitTemplateArgs()) { UnresExpr->copyTemplateArgumentsInto(TemplateArgsBuffer); TemplateArgs = &TemplateArgsBuffer; } for (UnresolvedMemberExpr::decls_iterator I = UnresExpr->decls_begin(), E = UnresExpr->decls_end(); I != E; ++I) { NamedDecl *Func = *I; CXXRecordDecl *ActingDC = cast(Func->getDeclContext()); if (isa(Func)) Func = cast(Func)->getTargetDecl(); // Microsoft supports direct constructor calls. if (getLangOpts().MicrosoftExt && isa(Func)) { AddOverloadCandidate(cast(Func), I.getPair(), Args, CandidateSet, /*SuppressUserConversions*/ false); } else if ((Method = dyn_cast(Func))) { // If explicit template arguments were provided, we can't call a // non-template member function. if (TemplateArgs) continue; AddMethodCandidate(Method, I.getPair(), ActingDC, ObjectType, ObjectClassification, Args, CandidateSet, /*SuppressUserConversions=*/false); } else { AddMethodTemplateCandidate( cast(Func), I.getPair(), ActingDC, TemplateArgs, ObjectType, ObjectClassification, Args, CandidateSet, /*SuppressUserConversions=*/false); } } DeclarationName DeclName = UnresExpr->getMemberName(); UnbridgedCasts.restore(); OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, UnresExpr->getBeginLoc(), Best)) { case OR_Success: Method = cast(Best->Function); FoundDecl = Best->FoundDecl; CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl); if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc())) return ExprError(); // If FoundDecl is different from Method (such as if one is a template // and the other a specialization), make sure DiagnoseUseOfDecl is // called on both. // FIXME: This would be more comprehensively addressed by modifying // DiagnoseUseOfDecl to accept both the FoundDecl and the decl // being used. if (Method != FoundDecl.getDecl() && DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc())) return ExprError(); break; case OR_No_Viable_Function: CandidateSet.NoteCandidates( PartialDiagnosticAt( UnresExpr->getMemberLoc(), PDiag(diag::err_ovl_no_viable_member_function_in_call) << DeclName << MemExprE->getSourceRange()), *this, OCD_AllCandidates, Args); // FIXME: Leaking incoming expressions! return ExprError(); case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(UnresExpr->getMemberLoc(), PDiag(diag::err_ovl_ambiguous_member_call) << DeclName << MemExprE->getSourceRange()), *this, OCD_AmbiguousCandidates, Args); // FIXME: Leaking incoming expressions! return ExprError(); case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(UnresExpr->getMemberLoc(), PDiag(diag::err_ovl_deleted_member_call) << DeclName << MemExprE->getSourceRange()), *this, OCD_AllCandidates, Args); // FIXME: Leaking incoming expressions! return ExprError(); } MemExprE = FixOverloadedFunctionReference(MemExprE, FoundDecl, Method); // If overload resolution picked a static member, build a // non-member call based on that function. if (Method->isStatic()) { return BuildResolvedCallExpr(MemExprE, Method, LParenLoc, Args, RParenLoc); } MemExpr = cast(MemExprE->IgnoreParens()); } QualType ResultType = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultType); ResultType = ResultType.getNonLValueExprType(Context); assert(Method && "Member call to something that isn't a method?"); const auto *Proto = Method->getType()->castAs(); CXXMemberCallExpr *TheCall = CXXMemberCallExpr::Create(Context, MemExprE, Args, ResultType, VK, RParenLoc, Proto->getNumParams()); // Check for a valid return type. if (CheckCallReturnType(Method->getReturnType(), MemExpr->getMemberLoc(), TheCall, Method)) return ExprError(); // Convert the object argument (for a non-static member function call). // We only need to do this if there was actually an overload; otherwise // it was done at lookup. if (!Method->isStatic()) { ExprResult ObjectArg = PerformObjectArgumentInitialization(MemExpr->getBase(), Qualifier, FoundDecl, Method); if (ObjectArg.isInvalid()) return ExprError(); MemExpr->setBase(ObjectArg.get()); } // Convert the rest of the arguments if (ConvertArgumentsForCall(TheCall, MemExpr, Method, Proto, Args, RParenLoc)) return ExprError(); DiagnoseSentinelCalls(Method, LParenLoc, Args); if (CheckFunctionCall(Method, TheCall, Proto)) return ExprError(); // In the case the method to call was not selected by the overloading // resolution process, we still need to handle the enable_if attribute. Do // that here, so it will not hide previous -- and more relevant -- errors. if (auto *MemE = dyn_cast(NakedMemExpr)) { if (const EnableIfAttr *Attr = CheckEnableIf(Method, Args, true)) { Diag(MemE->getMemberLoc(), diag::err_ovl_no_viable_member_function_in_call) << Method << Method->getSourceRange(); Diag(Method->getLocation(), diag::note_ovl_candidate_disabled_by_function_cond_attr) << Attr->getCond()->getSourceRange() << Attr->getMessage(); return ExprError(); } } if ((isa(CurContext) || isa(CurContext)) && TheCall->getMethodDecl()->isPure()) { const CXXMethodDecl *MD = TheCall->getMethodDecl(); if (isa(MemExpr->getBase()->IgnoreParenCasts()) && MemExpr->performsVirtualDispatch(getLangOpts())) { Diag(MemExpr->getBeginLoc(), diag::warn_call_to_pure_virtual_member_function_from_ctor_dtor) << MD->getDeclName() << isa(CurContext) << MD->getParent()->getDeclName(); Diag(MD->getBeginLoc(), diag::note_previous_decl) << MD->getDeclName(); if (getLangOpts().AppleKext) Diag(MemExpr->getBeginLoc(), diag::note_pure_qualified_call_kext) << MD->getParent()->getDeclName() << MD->getDeclName(); } } if (CXXDestructorDecl *DD = dyn_cast(TheCall->getMethodDecl())) { // a->A::f() doesn't go through the vtable, except in AppleKext mode. bool CallCanBeVirtual = !MemExpr->hasQualifier() || getLangOpts().AppleKext; CheckVirtualDtorCall(DD, MemExpr->getBeginLoc(), /*IsDelete=*/false, CallCanBeVirtual, /*WarnOnNonAbstractTypes=*/true, MemExpr->getMemberLoc()); } return MaybeBindToTemporary(TheCall); } /// BuildCallToObjectOfClassType - Build a call to an object of class /// type (C++ [over.call.object]), which can end up invoking an /// overloaded function call operator (@c operator()) or performing a /// user-defined conversion on the object argument. ExprResult Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc) { if (checkPlaceholderForOverload(*this, Obj)) return ExprError(); ExprResult Object = Obj; UnbridgedCastsSet UnbridgedCasts; if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts)) return ExprError(); assert(Object.get()->getType()->isRecordType() && "Requires object type argument"); // C++ [over.call.object]p1: // If the primary-expression E in the function call syntax // evaluates to a class object of type "cv T", then the set of // candidate functions includes at least the function call // operators of T. The function call operators of T are obtained by // ordinary lookup of the name operator() in the context of // (E).operator(). OverloadCandidateSet CandidateSet(LParenLoc, OverloadCandidateSet::CSK_Operator); DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call); if (RequireCompleteType(LParenLoc, Object.get()->getType(), diag::err_incomplete_object_call, Object.get())) return true; const auto *Record = Object.get()->getType()->castAs(); LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName); LookupQualifiedName(R, Record->getDecl()); R.suppressDiagnostics(); for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Object.get()->getType(), Object.get()->Classify(Context), Args, CandidateSet, /*SuppressUserConversion=*/false); } // C++ [over.call.object]p2: // In addition, for each (non-explicit in C++0x) conversion function // declared in T of the form // // operator conversion-type-id () cv-qualifier; // // where cv-qualifier is the same cv-qualification as, or a // greater cv-qualification than, cv, and where conversion-type-id // denotes the type "pointer to function of (P1,...,Pn) returning // R", or the type "reference to pointer to function of // (P1,...,Pn) returning R", or the type "reference to function // of (P1,...,Pn) returning R", a surrogate call function [...] // is also considered as a candidate function. Similarly, // surrogate call functions are added to the set of candidate // functions for each conversion function declared in an // accessible base class provided the function is not hidden // within T by another intervening declaration. const auto &Conversions = cast(Record->getDecl())->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { NamedDecl *D = *I; CXXRecordDecl *ActingContext = cast(D->getDeclContext()); if (isa(D)) D = cast(D)->getTargetDecl(); // Skip over templated conversion functions; they aren't // surrogates. if (isa(D)) continue; CXXConversionDecl *Conv = cast(D); if (!Conv->isExplicit()) { // Strip the reference type (if any) and then the pointer type (if // any) to get down to what might be a function type. QualType ConvType = Conv->getConversionType().getNonReferenceType(); if (const PointerType *ConvPtrType = ConvType->getAs()) ConvType = ConvPtrType->getPointeeType(); if (const FunctionProtoType *Proto = ConvType->getAs()) { AddSurrogateCandidate(Conv, I.getPair(), ActingContext, Proto, Object.get(), Args, CandidateSet); } } } bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, Object.get()->getBeginLoc(), Best)) { case OR_Success: // Overload resolution succeeded; we'll build the appropriate call // below. break; case OR_No_Viable_Function: { PartialDiagnostic PD = CandidateSet.empty() ? (PDiag(diag::err_ovl_no_oper) << Object.get()->getType() << /*call*/ 1 << Object.get()->getSourceRange()) : (PDiag(diag::err_ovl_no_viable_object_call) << Object.get()->getType() << Object.get()->getSourceRange()); CandidateSet.NoteCandidates( PartialDiagnosticAt(Object.get()->getBeginLoc(), PD), *this, OCD_AllCandidates, Args); break; } case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(Object.get()->getBeginLoc(), PDiag(diag::err_ovl_ambiguous_object_call) << Object.get()->getType() << Object.get()->getSourceRange()), *this, OCD_AmbiguousCandidates, Args); break; case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(Object.get()->getBeginLoc(), PDiag(diag::err_ovl_deleted_object_call) << Object.get()->getType() << Object.get()->getSourceRange()), *this, OCD_AllCandidates, Args); break; } if (Best == CandidateSet.end()) return true; UnbridgedCasts.restore(); if (Best->Function == nullptr) { // Since there is no function declaration, this is one of the // surrogate candidates. Dig out the conversion function. CXXConversionDecl *Conv = cast( Best->Conversions[0].UserDefined.ConversionFunction); CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr, Best->FoundDecl); if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc)) return ExprError(); assert(Conv == Best->FoundDecl.getDecl() && "Found Decl & conversion-to-functionptr should be same, right?!"); // We selected one of the surrogate functions that converts the // object parameter to a function pointer. Perform the conversion // on the object argument, then let BuildCallExpr finish the job. // Create an implicit member expr to refer to the conversion operator. // and then call it. ExprResult Call = BuildCXXMemberCallExpr(Object.get(), Best->FoundDecl, Conv, HadMultipleCandidates); if (Call.isInvalid()) return ExprError(); // Record usage of conversion in an implicit cast. Call = ImplicitCastExpr::Create(Context, Call.get()->getType(), CK_UserDefinedConversion, Call.get(), nullptr, VK_RValue); return BuildCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc); } CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr, Best->FoundDecl); // We found an overloaded operator(). Build a CXXOperatorCallExpr // that calls this method, using Object for the implicit object // parameter and passing along the remaining arguments. CXXMethodDecl *Method = cast(Best->Function); // An error diagnostic has already been printed when parsing the declaration. if (Method->isInvalidDecl()) return ExprError(); const auto *Proto = Method->getType()->castAs(); unsigned NumParams = Proto->getNumParams(); DeclarationNameInfo OpLocInfo( Context.DeclarationNames.getCXXOperatorName(OO_Call), LParenLoc); OpLocInfo.setCXXOperatorNameRange(SourceRange(LParenLoc, RParenLoc)); ExprResult NewFn = CreateFunctionRefExpr(*this, Method, Best->FoundDecl, Obj, HadMultipleCandidates, OpLocInfo.getLoc(), OpLocInfo.getInfo()); if (NewFn.isInvalid()) return true; // The number of argument slots to allocate in the call. If we have default // arguments we need to allocate space for them as well. We additionally // need one more slot for the object parameter. unsigned NumArgsSlots = 1 + std::max(Args.size(), NumParams); // Build the full argument list for the method call (the implicit object // parameter is placed at the beginning of the list). SmallVector MethodArgs(NumArgsSlots); bool IsError = false; // Initialize the implicit object parameter. ExprResult ObjRes = PerformObjectArgumentInitialization(Object.get(), /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (ObjRes.isInvalid()) IsError = true; else Object = ObjRes; MethodArgs[0] = Object.get(); // Check the argument types. for (unsigned i = 0; i != NumParams; i++) { Expr *Arg; if (i < Args.size()) { Arg = Args[i]; // Pass the argument. ExprResult InputInit = PerformCopyInitialization(InitializedEntity::InitializeParameter( Context, Method->getParamDecl(i)), SourceLocation(), Arg); IsError |= InputInit.isInvalid(); Arg = InputInit.getAs(); } else { ExprResult DefArg = BuildCXXDefaultArgExpr(LParenLoc, Method, Method->getParamDecl(i)); if (DefArg.isInvalid()) { IsError = true; break; } Arg = DefArg.getAs(); } MethodArgs[i + 1] = Arg; } // If this is a variadic call, handle args passed through "...". if (Proto->isVariadic()) { // Promote the arguments (C99 6.5.2.2p7). for (unsigned i = NumParams, e = Args.size(); i < e; i++) { ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, nullptr); IsError |= Arg.isInvalid(); MethodArgs[i + 1] = Arg.get(); } } if (IsError) return true; DiagnoseSentinelCalls(Method, LParenLoc, Args); // Once we've built TheCall, all of the expressions are properly owned. QualType ResultTy = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy, VK, RParenLoc, FPOptions()); if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method)) return true; if (CheckFunctionCall(Method, TheCall, Proto)) return true; return MaybeBindToTemporary(TheCall); } /// BuildOverloadedArrowExpr - Build a call to an overloaded @c operator-> /// (if one exists), where @c Base is an expression of class type and /// @c Member is the name of the member we're trying to find. ExprResult Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, bool *NoArrowOperatorFound) { assert(Base->getType()->isRecordType() && "left-hand side must have class type"); if (checkPlaceholderForOverload(*this, Base)) return ExprError(); SourceLocation Loc = Base->getExprLoc(); // C++ [over.ref]p1: // // [...] An expression x->m is interpreted as (x.operator->())->m // for a class object x of type T if T::operator->() exists and if // the operator is selected as the best match function by the // overload resolution mechanism (13.3). DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Arrow); OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Operator); if (RequireCompleteType(Loc, Base->getType(), diag::err_typecheck_incomplete_tag, Base)) return ExprError(); LookupResult R(*this, OpName, OpLoc, LookupOrdinaryName); LookupQualifiedName(R, Base->getType()->castAs()->getDecl()); R.suppressDiagnostics(); for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Base->getType(), Base->Classify(Context), None, CandidateSet, /*SuppressUserConversion=*/false); } bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) { case OR_Success: // Overload resolution succeeded; we'll build the call below. break; case OR_No_Viable_Function: { auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates, Base); if (CandidateSet.empty()) { QualType BaseType = Base->getType(); if (NoArrowOperatorFound) { // Report this specific error to the caller instead of emitting a // diagnostic, as requested. *NoArrowOperatorFound = true; return ExprError(); } Diag(OpLoc, diag::err_typecheck_member_reference_arrow) << BaseType << Base->getSourceRange(); if (BaseType->isRecordType() && !BaseType->isPointerType()) { Diag(OpLoc, diag::note_typecheck_member_reference_suggestion) << FixItHint::CreateReplacement(OpLoc, "."); } } else Diag(OpLoc, diag::err_ovl_no_viable_oper) << "operator->" << Base->getSourceRange(); CandidateSet.NoteCandidates(*this, Base, Cands); return ExprError(); } case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_unary) << "->" << Base->getType() << Base->getSourceRange()), *this, OCD_AmbiguousCandidates, Base); return ExprError(); case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper) << "->" << Base->getSourceRange()), *this, OCD_AllCandidates, Base); return ExprError(); } CheckMemberOperatorAccess(OpLoc, Base, nullptr, Best->FoundDecl); // Convert the object parameter. CXXMethodDecl *Method = cast(Best->Function); ExprResult BaseResult = PerformObjectArgumentInitialization(Base, /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (BaseResult.isInvalid()) return ExprError(); Base = BaseResult.get(); // Build the operator call. ExprResult FnExpr = CreateFunctionRefExpr(*this, Method, Best->FoundDecl, Base, HadMultipleCandidates, OpLoc); if (FnExpr.isInvalid()) return ExprError(); QualType ResultTy = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( Context, OO_Arrow, FnExpr.get(), Base, ResultTy, VK, OpLoc, FPOptions()); if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method)) return ExprError(); if (CheckFunctionCall(Method, TheCall, Method->getType()->castAs())) return ExprError(); return MaybeBindToTemporary(TheCall); } /// BuildLiteralOperatorCall - Build a UserDefinedLiteral by creating a call to /// a literal operator described by the provided lookup results. ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R, DeclarationNameInfo &SuffixInfo, ArrayRef Args, SourceLocation LitEndLoc, TemplateArgumentListInfo *TemplateArgs) { SourceLocation UDSuffixLoc = SuffixInfo.getCXXLiteralOperatorNameLoc(); OverloadCandidateSet CandidateSet(UDSuffixLoc, OverloadCandidateSet::CSK_Normal); AddNonMemberOperatorCandidates(R.asUnresolvedSet(), Args, CandidateSet, TemplateArgs); bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. This will usually be trivial, but might need // to perform substitutions for a literal operator template. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, UDSuffixLoc, Best)) { case OR_Success: case OR_Deleted: break; case OR_No_Viable_Function: CandidateSet.NoteCandidates( PartialDiagnosticAt(UDSuffixLoc, PDiag(diag::err_ovl_no_viable_function_in_call) << R.getLookupName()), *this, OCD_AllCandidates, Args); return ExprError(); case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), PDiag(diag::err_ovl_ambiguous_call) << R.getLookupName()), *this, OCD_AmbiguousCandidates, Args); return ExprError(); } FunctionDecl *FD = Best->Function; ExprResult Fn = CreateFunctionRefExpr(*this, FD, Best->FoundDecl, nullptr, HadMultipleCandidates, SuffixInfo.getLoc(), SuffixInfo.getInfo()); if (Fn.isInvalid()) return true; // Check the argument types. This should almost always be a no-op, except // that array-to-pointer decay is applied to string literals. Expr *ConvArgs[2]; for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { ExprResult InputInit = PerformCopyInitialization( InitializedEntity::InitializeParameter(Context, FD->getParamDecl(ArgIdx)), SourceLocation(), Args[ArgIdx]); if (InputInit.isInvalid()) return true; ConvArgs[ArgIdx] = InputInit.get(); } QualType ResultTy = FD->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); UserDefinedLiteral *UDL = UserDefinedLiteral::Create( Context, Fn.get(), llvm::makeArrayRef(ConvArgs, Args.size()), ResultTy, VK, LitEndLoc, UDSuffixLoc); if (CheckCallReturnType(FD->getReturnType(), UDSuffixLoc, UDL, FD)) return ExprError(); if (CheckFunctionCall(FD, UDL, nullptr)) return ExprError(); return MaybeBindToTemporary(UDL); } /// Build a call to 'begin' or 'end' for a C++11 for-range statement. If the /// given LookupResult is non-empty, it is assumed to describe a member which /// will be invoked. Otherwise, the function will be found via argument /// dependent lookup. /// CallExpr is set to a valid expression and FRS_Success returned on success, /// otherwise CallExpr is set to ExprError() and some non-success value /// is returned. Sema::ForRangeStatus Sema::BuildForRangeBeginEndCall(SourceLocation Loc, SourceLocation RangeLoc, const DeclarationNameInfo &NameInfo, LookupResult &MemberLookup, OverloadCandidateSet *CandidateSet, Expr *Range, ExprResult *CallExpr) { Scope *S = nullptr; CandidateSet->clear(OverloadCandidateSet::CSK_Normal); if (!MemberLookup.empty()) { ExprResult MemberRef = BuildMemberReferenceExpr(Range, Range->getType(), Loc, /*IsPtr=*/false, CXXScopeSpec(), /*TemplateKWLoc=*/SourceLocation(), /*FirstQualifierInScope=*/nullptr, MemberLookup, /*TemplateArgs=*/nullptr, S); if (MemberRef.isInvalid()) { *CallExpr = ExprError(); return FRS_DiagnosticIssued; } *CallExpr = BuildCallExpr(S, MemberRef.get(), Loc, None, Loc, nullptr); if (CallExpr->isInvalid()) { *CallExpr = ExprError(); return FRS_DiagnosticIssued; } } else { UnresolvedSet<0> FoundNames; UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create(Context, /*NamingClass=*/nullptr, NestedNameSpecifierLoc(), NameInfo, /*NeedsADL=*/true, /*Overloaded=*/false, FoundNames.begin(), FoundNames.end()); bool CandidateSetError = buildOverloadedCallSet(S, Fn, Fn, Range, Loc, CandidateSet, CallExpr); if (CandidateSet->empty() || CandidateSetError) { *CallExpr = ExprError(); return FRS_NoViableFunction; } OverloadCandidateSet::iterator Best; OverloadingResult OverloadResult = CandidateSet->BestViableFunction(*this, Fn->getBeginLoc(), Best); if (OverloadResult == OR_No_Viable_Function) { *CallExpr = ExprError(); return FRS_NoViableFunction; } *CallExpr = FinishOverloadedCallExpr(*this, S, Fn, Fn, Loc, Range, Loc, nullptr, CandidateSet, &Best, OverloadResult, /*AllowTypoCorrection=*/false); if (CallExpr->isInvalid() || OverloadResult != OR_Success) { *CallExpr = ExprError(); return FRS_DiagnosticIssued; } } return FRS_Success; } /// FixOverloadedFunctionReference - E is an expression that refers to /// a C++ overloaded function (possibly with some parentheses and /// perhaps a '&' around it). We have resolved the overloaded function /// to the function declaration Fn, so patch up the expression E to /// refer (possibly indirectly) to Fn. Returns the new expr. Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, FunctionDecl *Fn) { if (ParenExpr *PE = dyn_cast(E)) { Expr *SubExpr = FixOverloadedFunctionReference(PE->getSubExpr(), Found, Fn); if (SubExpr == PE->getSubExpr()) return PE; return new (Context) ParenExpr(PE->getLParen(), PE->getRParen(), SubExpr); } if (ImplicitCastExpr *ICE = dyn_cast(E)) { Expr *SubExpr = FixOverloadedFunctionReference(ICE->getSubExpr(), Found, Fn); assert(Context.hasSameType(ICE->getSubExpr()->getType(), SubExpr->getType()) && "Implicit cast type cannot be determined from overload"); assert(ICE->path_empty() && "fixing up hierarchy conversion?"); if (SubExpr == ICE->getSubExpr()) return ICE; return ImplicitCastExpr::Create(Context, ICE->getType(), ICE->getCastKind(), SubExpr, nullptr, ICE->getValueKind()); } if (auto *GSE = dyn_cast(E)) { if (!GSE->isResultDependent()) { Expr *SubExpr = FixOverloadedFunctionReference(GSE->getResultExpr(), Found, Fn); if (SubExpr == GSE->getResultExpr()) return GSE; // Replace the resulting type information before rebuilding the generic // selection expression. ArrayRef A = GSE->getAssocExprs(); SmallVector AssocExprs(A.begin(), A.end()); unsigned ResultIdx = GSE->getResultIndex(); AssocExprs[ResultIdx] = SubExpr; return GenericSelectionExpr::Create( Context, GSE->getGenericLoc(), GSE->getControllingExpr(), GSE->getAssocTypeSourceInfos(), AssocExprs, GSE->getDefaultLoc(), GSE->getRParenLoc(), GSE->containsUnexpandedParameterPack(), ResultIdx); } // Rather than fall through to the unreachable, return the original generic // selection expression. return GSE; } if (UnaryOperator *UnOp = dyn_cast(E)) { assert(UnOp->getOpcode() == UO_AddrOf && "Can only take the address of an overloaded function"); if (CXXMethodDecl *Method = dyn_cast(Fn)) { if (Method->isStatic()) { // Do nothing: static member functions aren't any different // from non-member functions. } else { // Fix the subexpression, which really has to be an // UnresolvedLookupExpr holding an overloaded member function // or template. Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Found, Fn); if (SubExpr == UnOp->getSubExpr()) return UnOp; assert(isa(SubExpr) && "fixed to something other than a decl ref"); assert(cast(SubExpr)->getQualifier() && "fixed to a member ref with no nested name qualifier"); // We have taken the address of a pointer to member // function. Perform the computation here so that we get the // appropriate pointer to member type. QualType ClassType = Context.getTypeDeclType(cast(Method->getDeclContext())); QualType MemPtrType = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr()); // Under the MS ABI, lock down the inheritance model now. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) (void)isCompleteType(UnOp->getOperatorLoc(), MemPtrType); return new (Context) UnaryOperator(SubExpr, UO_AddrOf, MemPtrType, VK_RValue, OK_Ordinary, UnOp->getOperatorLoc(), false); } } Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Found, Fn); if (SubExpr == UnOp->getSubExpr()) return UnOp; return new (Context) UnaryOperator(SubExpr, UO_AddrOf, Context.getPointerType(SubExpr->getType()), VK_RValue, OK_Ordinary, UnOp->getOperatorLoc(), false); } if (UnresolvedLookupExpr *ULE = dyn_cast(E)) { // FIXME: avoid copy. TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr; if (ULE->hasExplicitTemplateArgs()) { ULE->copyTemplateArgumentsInto(TemplateArgsBuffer); TemplateArgs = &TemplateArgsBuffer; } DeclRefExpr *DRE = BuildDeclRefExpr(Fn, Fn->getType(), VK_LValue, ULE->getNameInfo(), ULE->getQualifierLoc(), Found.getDecl(), ULE->getTemplateKeywordLoc(), TemplateArgs); DRE->setHadMultipleCandidates(ULE->getNumDecls() > 1); return DRE; } if (UnresolvedMemberExpr *MemExpr = dyn_cast(E)) { // FIXME: avoid copy. TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr; if (MemExpr->hasExplicitTemplateArgs()) { MemExpr->copyTemplateArgumentsInto(TemplateArgsBuffer); TemplateArgs = &TemplateArgsBuffer; } Expr *Base; // If we're filling in a static method where we used to have an // implicit member access, rewrite to a simple decl ref. if (MemExpr->isImplicitAccess()) { if (cast(Fn)->isStatic()) { DeclRefExpr *DRE = BuildDeclRefExpr( Fn, Fn->getType(), VK_LValue, MemExpr->getNameInfo(), MemExpr->getQualifierLoc(), Found.getDecl(), MemExpr->getTemplateKeywordLoc(), TemplateArgs); DRE->setHadMultipleCandidates(MemExpr->getNumDecls() > 1); return DRE; } else { SourceLocation Loc = MemExpr->getMemberLoc(); if (MemExpr->getQualifier()) Loc = MemExpr->getQualifierLoc().getBeginLoc(); Base = BuildCXXThisExpr(Loc, MemExpr->getBaseType(), /*IsImplicit=*/true); } } else Base = MemExpr->getBase(); ExprValueKind valueKind; QualType type; if (cast(Fn)->isStatic()) { valueKind = VK_LValue; type = Fn->getType(); } else { valueKind = VK_RValue; type = Context.BoundMemberTy; } return BuildMemberExpr( Base, MemExpr->isArrow(), MemExpr->getOperatorLoc(), MemExpr->getQualifierLoc(), MemExpr->getTemplateKeywordLoc(), Fn, Found, /*HadMultipleCandidates=*/true, MemExpr->getMemberNameInfo(), type, valueKind, OK_Ordinary, TemplateArgs); } llvm_unreachable("Invalid reference to overloaded function"); } ExprResult Sema::FixOverloadedFunctionReference(ExprResult E, DeclAccessPair Found, FunctionDecl *Fn) { return FixOverloadedFunctionReference(E.get(), Found, Fn); } Index: stable/11/contrib/llvm-project/clang =================================================================== --- stable/11/contrib/llvm-project/clang (revision 363091) +++ stable/11/contrib/llvm-project/clang (revision 363092) Property changes on: stable/11/contrib/llvm-project/clang ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/contrib/llvm-project/clang:r363013 Index: stable/11 =================================================================== --- stable/11 (revision 363091) +++ stable/11 (revision 363092) Property changes on: stable/11 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r363013 Index: stable/12/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- stable/12/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp (revision 363091) +++ stable/12/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp (revision 363092) @@ -1,8548 +1,8544 @@ //===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// Implements semantic analysis for C++ expressions. /// //===----------------------------------------------------------------------===// #include "clang/Sema/Template.h" #include "clang/Sema/SemaInternal.h" #include "TreeTransform.h" #include "TypeLocBuilder.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTLambda.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/AlignedAllocation.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaLambda.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; using namespace sema; /// Handle the result of the special case name lookup for inheriting /// constructor declarations. 'NS::X::X' and 'NS::X<...>::X' are treated as /// constructor names in member using declarations, even if 'X' is not the /// name of the corresponding type. ParsedType Sema::getInheritingConstructorName(CXXScopeSpec &SS, SourceLocation NameLoc, IdentifierInfo &Name) { NestedNameSpecifier *NNS = SS.getScopeRep(); // Convert the nested-name-specifier into a type. QualType Type; switch (NNS->getKind()) { case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpecWithTemplate: Type = QualType(NNS->getAsType(), 0); break; case NestedNameSpecifier::Identifier: // Strip off the last layer of the nested-name-specifier and build a // typename type for it. assert(NNS->getAsIdentifier() == &Name && "not a constructor name"); Type = Context.getDependentNameType(ETK_None, NNS->getPrefix(), NNS->getAsIdentifier()); break; case NestedNameSpecifier::Global: case NestedNameSpecifier::Super: case NestedNameSpecifier::Namespace: case NestedNameSpecifier::NamespaceAlias: llvm_unreachable("Nested name specifier is not a type for inheriting ctor"); } // This reference to the type is located entirely at the location of the // final identifier in the qualified-id. return CreateParsedType(Type, Context.getTrivialTypeSourceInfo(Type, NameLoc)); } ParsedType Sema::getConstructorName(IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, bool EnteringContext) { CXXRecordDecl *CurClass = getCurrentClass(S, &SS); assert(CurClass && &II == CurClass->getIdentifier() && "not a constructor name"); // When naming a constructor as a member of a dependent context (eg, in a // friend declaration or an inherited constructor declaration), form an // unresolved "typename" type. if (CurClass->isDependentContext() && !EnteringContext && SS.getScopeRep()) { QualType T = Context.getDependentNameType(ETK_None, SS.getScopeRep(), &II); return ParsedType::make(T); } if (SS.isNotEmpty() && RequireCompleteDeclContext(SS, CurClass)) return ParsedType(); // Find the injected-class-name declaration. Note that we make no attempt to // diagnose cases where the injected-class-name is shadowed: the only // declaration that can validly shadow the injected-class-name is a // non-static data member, and if the class contains both a non-static data // member and a constructor then it is ill-formed (we check that in // CheckCompletedCXXClass). CXXRecordDecl *InjectedClassName = nullptr; for (NamedDecl *ND : CurClass->lookup(&II)) { auto *RD = dyn_cast(ND); if (RD && RD->isInjectedClassName()) { InjectedClassName = RD; break; } } if (!InjectedClassName) { if (!CurClass->isInvalidDecl()) { // FIXME: RequireCompleteDeclContext doesn't check dependent contexts // properly. Work around it here for now. Diag(SS.getLastQualifierNameLoc(), diag::err_incomplete_nested_name_spec) << CurClass << SS.getRange(); } return ParsedType(); } QualType T = Context.getTypeDeclType(InjectedClassName); DiagnoseUseOfDecl(InjectedClassName, NameLoc); MarkAnyDeclReferenced(NameLoc, InjectedClassName, /*OdrUse=*/false); return ParsedType::make(T); } ParsedType Sema::getDestructorName(SourceLocation TildeLoc, IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, ParsedType ObjectTypePtr, bool EnteringContext) { // Determine where to perform name lookup. // FIXME: This area of the standard is very messy, and the current // wording is rather unclear about which scopes we search for the // destructor name; see core issues 399 and 555. Issue 399 in // particular shows where the current description of destructor name // lookup is completely out of line with existing practice, e.g., // this appears to be ill-formed: // // namespace N { // template struct S { // ~S(); // }; // } // // void f(N::S* s) { // s->N::S::~S(); // } // // See also PR6358 and PR6359. // For this reason, we're currently only doing the C++03 version of this // code; the C++0x version has to wait until we get a proper spec. QualType SearchType; DeclContext *LookupCtx = nullptr; bool isDependent = false; bool LookInScope = false; if (SS.isInvalid()) return nullptr; // If we have an object type, it's because we are in a // pseudo-destructor-expression or a member access expression, and // we know what type we're looking for. if (ObjectTypePtr) SearchType = GetTypeFromParser(ObjectTypePtr); if (SS.isSet()) { NestedNameSpecifier *NNS = SS.getScopeRep(); bool AlreadySearched = false; bool LookAtPrefix = true; // C++11 [basic.lookup.qual]p6: // If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier, // the type-names are looked up as types in the scope designated by the // nested-name-specifier. Similarly, in a qualified-id of the form: // // nested-name-specifier[opt] class-name :: ~ class-name // // the second class-name is looked up in the same scope as the first. // // Here, we determine whether the code below is permitted to look at the // prefix of the nested-name-specifier. DeclContext *DC = computeDeclContext(SS, EnteringContext); if (DC && DC->isFileContext()) { AlreadySearched = true; LookupCtx = DC; isDependent = false; } else if (DC && isa(DC)) { LookAtPrefix = false; LookInScope = true; } // The second case from the C++03 rules quoted further above. NestedNameSpecifier *Prefix = nullptr; if (AlreadySearched) { // Nothing left to do. } else if (LookAtPrefix && (Prefix = NNS->getPrefix())) { CXXScopeSpec PrefixSS; PrefixSS.Adopt(NestedNameSpecifierLoc(Prefix, SS.location_data())); LookupCtx = computeDeclContext(PrefixSS, EnteringContext); isDependent = isDependentScopeSpecifier(PrefixSS); } else if (ObjectTypePtr) { LookupCtx = computeDeclContext(SearchType); isDependent = SearchType->isDependentType(); } else { LookupCtx = computeDeclContext(SS, EnteringContext); isDependent = LookupCtx && LookupCtx->isDependentContext(); } } else if (ObjectTypePtr) { // C++ [basic.lookup.classref]p3: // If the unqualified-id is ~type-name, the type-name is looked up // in the context of the entire postfix-expression. If the type T // of the object expression is of a class type C, the type-name is // also looked up in the scope of class C. At least one of the // lookups shall find a name that refers to (possibly // cv-qualified) T. LookupCtx = computeDeclContext(SearchType); isDependent = SearchType->isDependentType(); assert((isDependent || !SearchType->isIncompleteType()) && "Caller should have completed object type"); LookInScope = true; } else { // Perform lookup into the current scope (only). LookInScope = true; } TypeDecl *NonMatchingTypeDecl = nullptr; LookupResult Found(*this, &II, NameLoc, LookupOrdinaryName); for (unsigned Step = 0; Step != 2; ++Step) { // Look for the name first in the computed lookup context (if we // have one) and, if that fails to find a match, in the scope (if // we're allowed to look there). Found.clear(); if (Step == 0 && LookupCtx) { if (RequireCompleteDeclContext(SS, LookupCtx)) return nullptr; LookupQualifiedName(Found, LookupCtx); } else if (Step == 1 && LookInScope && S) { LookupName(Found, S); } else { continue; } // FIXME: Should we be suppressing ambiguities here? if (Found.isAmbiguous()) return nullptr; if (TypeDecl *Type = Found.getAsSingle()) { QualType T = Context.getTypeDeclType(Type); MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false); if (SearchType.isNull() || SearchType->isDependentType() || Context.hasSameUnqualifiedType(T, SearchType)) { // We found our type! return CreateParsedType(T, Context.getTrivialTypeSourceInfo(T, NameLoc)); } if (!SearchType.isNull()) NonMatchingTypeDecl = Type; } // If the name that we found is a class template name, and it is // the same name as the template name in the last part of the // nested-name-specifier (if present) or the object type, then // this is the destructor for that class. // FIXME: This is a workaround until we get real drafting for core // issue 399, for which there isn't even an obvious direction. if (ClassTemplateDecl *Template = Found.getAsSingle()) { QualType MemberOfType; if (SS.isSet()) { if (DeclContext *Ctx = computeDeclContext(SS, EnteringContext)) { // Figure out the type of the context, if it has one. if (CXXRecordDecl *Record = dyn_cast(Ctx)) MemberOfType = Context.getTypeDeclType(Record); } } if (MemberOfType.isNull()) MemberOfType = SearchType; if (MemberOfType.isNull()) continue; // We're referring into a class template specialization. If the // class template we found is the same as the template being // specialized, we found what we are looking for. if (const RecordType *Record = MemberOfType->getAs()) { if (ClassTemplateSpecializationDecl *Spec = dyn_cast(Record->getDecl())) { if (Spec->getSpecializedTemplate()->getCanonicalDecl() == Template->getCanonicalDecl()) return CreateParsedType( MemberOfType, Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc)); } continue; } // We're referring to an unresolved class template // specialization. Determine whether we class template we found // is the same as the template being specialized or, if we don't // know which template is being specialized, that it at least // has the same name. if (const TemplateSpecializationType *SpecType = MemberOfType->getAs()) { TemplateName SpecName = SpecType->getTemplateName(); // The class template we found is the same template being // specialized. if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) { if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl()) return CreateParsedType( MemberOfType, Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc)); continue; } // The class template we found has the same name as the // (dependent) template name being specialized. if (DependentTemplateName *DepTemplate = SpecName.getAsDependentTemplateName()) { if (DepTemplate->isIdentifier() && DepTemplate->getIdentifier() == Template->getIdentifier()) return CreateParsedType( MemberOfType, Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc)); continue; } } } } if (isDependent) { // We didn't find our type, but that's okay: it's dependent // anyway. // FIXME: What if we have no nested-name-specifier? QualType T = CheckTypenameType(ETK_None, SourceLocation(), SS.getWithLocInContext(Context), II, NameLoc); return ParsedType::make(T); } if (NonMatchingTypeDecl) { QualType T = Context.getTypeDeclType(NonMatchingTypeDecl); Diag(NameLoc, diag::err_destructor_expr_type_mismatch) << T << SearchType; Diag(NonMatchingTypeDecl->getLocation(), diag::note_destructor_type_here) << T; } else if (ObjectTypePtr) Diag(NameLoc, diag::err_ident_in_dtor_not_a_type) << &II; else { SemaDiagnosticBuilder DtorDiag = Diag(NameLoc, diag::err_destructor_class_name); if (S) { const DeclContext *Ctx = S->getEntity(); if (const CXXRecordDecl *Class = dyn_cast_or_null(Ctx)) DtorDiag << FixItHint::CreateReplacement(SourceRange(NameLoc), Class->getNameAsString()); } } return nullptr; } ParsedType Sema::getDestructorTypeForDecltype(const DeclSpec &DS, ParsedType ObjectType) { if (DS.getTypeSpecType() == DeclSpec::TST_error) return nullptr; if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto) { Diag(DS.getTypeSpecTypeLoc(), diag::err_decltype_auto_invalid); return nullptr; } assert(DS.getTypeSpecType() == DeclSpec::TST_decltype && "unexpected type in getDestructorType"); QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc()); // If we know the type of the object, check that the correct destructor // type was named now; we can give better diagnostics this way. QualType SearchType = GetTypeFromParser(ObjectType); if (!SearchType.isNull() && !SearchType->isDependentType() && !Context.hasSameUnqualifiedType(T, SearchType)) { Diag(DS.getTypeSpecTypeLoc(), diag::err_destructor_expr_type_mismatch) << T << SearchType; return nullptr; } return ParsedType::make(T); } bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Name) { assert(Name.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId); if (!SS.isValid()) return false; switch (SS.getScopeRep()->getKind()) { case NestedNameSpecifier::Identifier: case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpecWithTemplate: // Per C++11 [over.literal]p2, literal operators can only be declared at // namespace scope. Therefore, this unqualified-id cannot name anything. // Reject it early, because we have no AST representation for this in the // case where the scope is dependent. Diag(Name.getBeginLoc(), diag::err_literal_operator_id_outside_namespace) << SS.getScopeRep(); return true; case NestedNameSpecifier::Global: case NestedNameSpecifier::Super: case NestedNameSpecifier::Namespace: case NestedNameSpecifier::NamespaceAlias: return false; } llvm_unreachable("unknown nested name specifier kind"); } /// Build a C++ typeid expression with a type operand. ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc) { // C++ [expr.typeid]p4: // The top-level cv-qualifiers of the lvalue expression or the type-id // that is the operand of typeid are always ignored. // If the type of the type-id is a class type or a reference to a class // type, the class shall be completely-defined. Qualifiers Quals; QualType T = Context.getUnqualifiedArrayType(Operand->getType().getNonReferenceType(), Quals); if (T->getAs() && RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid)) return ExprError(); if (T->isVariablyModifiedType()) return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << T); if (CheckQualifiedFunctionForTypeId(T, TypeidLoc)) return ExprError(); return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand, SourceRange(TypeidLoc, RParenLoc)); } /// Build a C++ typeid expression with an expression operand. ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, SourceLocation TypeidLoc, Expr *E, SourceLocation RParenLoc) { bool WasEvaluated = false; if (E && !E->isTypeDependent()) { if (E->getType()->isPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(E); if (result.isInvalid()) return ExprError(); E = result.get(); } QualType T = E->getType(); if (const RecordType *RecordT = T->getAs()) { CXXRecordDecl *RecordD = cast(RecordT->getDecl()); // C++ [expr.typeid]p3: // [...] If the type of the expression is a class type, the class // shall be completely-defined. if (RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid)) return ExprError(); // C++ [expr.typeid]p3: // When typeid is applied to an expression other than an glvalue of a // polymorphic class type [...] [the] expression is an unevaluated // operand. [...] if (RecordD->isPolymorphic() && E->isGLValue()) { // The subexpression is potentially evaluated; switch the context // and recheck the subexpression. ExprResult Result = TransformToPotentiallyEvaluated(E); if (Result.isInvalid()) return ExprError(); E = Result.get(); // We require a vtable to query the type at run time. MarkVTableUsed(TypeidLoc, RecordD); WasEvaluated = true; } } ExprResult Result = CheckUnevaluatedOperand(E); if (Result.isInvalid()) return ExprError(); E = Result.get(); // C++ [expr.typeid]p4: // [...] If the type of the type-id is a reference to a possibly // cv-qualified type, the result of the typeid expression refers to a // std::type_info object representing the cv-unqualified referenced // type. Qualifiers Quals; QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals); if (!Context.hasSameType(T, UnqualT)) { T = UnqualT; E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).get(); } } if (E->getType()->isVariablyModifiedType()) return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << E->getType()); else if (!inTemplateInstantiation() && E->HasSideEffects(Context, WasEvaluated)) { // The expression operand for typeid is in an unevaluated expression // context, so side effects could result in unintended consequences. Diag(E->getExprLoc(), WasEvaluated ? diag::warn_side_effects_typeid : diag::warn_side_effects_unevaluated_context); } return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E, SourceRange(TypeidLoc, RParenLoc)); } /// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression); ExprResult Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, bool isType, void *TyOrExpr, SourceLocation RParenLoc) { // typeid is not supported in OpenCL. if (getLangOpts().OpenCLCPlusPlus) { return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported) << "typeid"); } // Find the std::type_info type. if (!getStdNamespace()) return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); if (!CXXTypeInfoDecl) { IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info"); LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName); LookupQualifiedName(R, getStdNamespace()); CXXTypeInfoDecl = R.getAsSingle(); // Microsoft's typeinfo doesn't have type_info in std but in the global // namespace if _HAS_EXCEPTIONS is defined to 0. See PR13153. if (!CXXTypeInfoDecl && LangOpts.MSVCCompat) { LookupQualifiedName(R, Context.getTranslationUnitDecl()); CXXTypeInfoDecl = R.getAsSingle(); } if (!CXXTypeInfoDecl) return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); } if (!getLangOpts().RTTI) { return ExprError(Diag(OpLoc, diag::err_no_typeid_with_fno_rtti)); } QualType TypeInfoType = Context.getTypeDeclType(CXXTypeInfoDecl); if (isType) { // The operand is a type; handle it as such. TypeSourceInfo *TInfo = nullptr; QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr), &TInfo); if (T.isNull()) return ExprError(); if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc); return BuildCXXTypeId(TypeInfoType, OpLoc, TInfo, RParenLoc); } // The operand is an expression. return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc); } /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to /// a single GUID. static void getUuidAttrOfType(Sema &SemaRef, QualType QT, llvm::SmallSetVector &UuidAttrs) { // Optionally remove one level of pointer, reference or array indirection. const Type *Ty = QT.getTypePtr(); if (QT->isPointerType() || QT->isReferenceType()) Ty = QT->getPointeeType().getTypePtr(); else if (QT->isArrayType()) Ty = Ty->getBaseElementTypeUnsafe(); const auto *TD = Ty->getAsTagDecl(); if (!TD) return; if (const auto *Uuid = TD->getMostRecentDecl()->getAttr()) { UuidAttrs.insert(Uuid); return; } // __uuidof can grab UUIDs from template arguments. if (const auto *CTSD = dyn_cast(TD)) { const TemplateArgumentList &TAL = CTSD->getTemplateArgs(); for (const TemplateArgument &TA : TAL.asArray()) { const UuidAttr *UuidForTA = nullptr; if (TA.getKind() == TemplateArgument::Type) getUuidAttrOfType(SemaRef, TA.getAsType(), UuidAttrs); else if (TA.getKind() == TemplateArgument::Declaration) getUuidAttrOfType(SemaRef, TA.getAsDecl()->getType(), UuidAttrs); if (UuidForTA) UuidAttrs.insert(UuidForTA); } } } /// Build a Microsoft __uuidof expression with a type operand. ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc) { StringRef UuidStr; if (!Operand->getType()->isDependentType()) { llvm::SmallSetVector UuidAttrs; getUuidAttrOfType(*this, Operand->getType(), UuidAttrs); if (UuidAttrs.empty()) return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); if (UuidAttrs.size() > 1) return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids)); UuidStr = UuidAttrs.back()->getGuid(); } return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UuidStr, SourceRange(TypeidLoc, RParenLoc)); } /// Build a Microsoft __uuidof expression with an expression operand. ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, SourceLocation TypeidLoc, Expr *E, SourceLocation RParenLoc) { StringRef UuidStr; if (!E->getType()->isDependentType()) { if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { UuidStr = "00000000-0000-0000-0000-000000000000"; } else { llvm::SmallSetVector UuidAttrs; getUuidAttrOfType(*this, E->getType(), UuidAttrs); if (UuidAttrs.empty()) return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); if (UuidAttrs.size() > 1) return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids)); UuidStr = UuidAttrs.back()->getGuid(); } } return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E, UuidStr, SourceRange(TypeidLoc, RParenLoc)); } /// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression); ExprResult Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc, bool isType, void *TyOrExpr, SourceLocation RParenLoc) { // If MSVCGuidDecl has not been cached, do the lookup. if (!MSVCGuidDecl) { IdentifierInfo *GuidII = &PP.getIdentifierTable().get("_GUID"); LookupResult R(*this, GuidII, SourceLocation(), LookupTagName); LookupQualifiedName(R, Context.getTranslationUnitDecl()); MSVCGuidDecl = R.getAsSingle(); if (!MSVCGuidDecl) return ExprError(Diag(OpLoc, diag::err_need_header_before_ms_uuidof)); } QualType GuidType = Context.getTypeDeclType(MSVCGuidDecl); if (isType) { // The operand is a type; handle it as such. TypeSourceInfo *TInfo = nullptr; QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr), &TInfo); if (T.isNull()) return ExprError(); if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc); return BuildCXXUuidof(GuidType, OpLoc, TInfo, RParenLoc); } // The operand is an expression. return BuildCXXUuidof(GuidType, OpLoc, (Expr*)TyOrExpr, RParenLoc); } /// ActOnCXXBoolLiteral - Parse {true,false} literals. ExprResult Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { assert((Kind == tok::kw_true || Kind == tok::kw_false) && "Unknown C++ Boolean value!"); return new (Context) CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc); } /// ActOnCXXNullPtrLiteral - Parse 'nullptr'. ExprResult Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) { return new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc); } /// ActOnCXXThrow - Parse throw expressions. ExprResult Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) { bool IsThrownVarInScope = false; if (Ex) { // C++0x [class.copymove]p31: // When certain criteria are met, an implementation is allowed to omit the // copy/move construction of a class object [...] // // - in a throw-expression, when the operand is the name of a // non-volatile automatic object (other than a function or catch- // clause parameter) whose scope does not extend beyond the end of the // innermost enclosing try-block (if there is one), the copy/move // operation from the operand to the exception object (15.1) can be // omitted by constructing the automatic object directly into the // exception object if (DeclRefExpr *DRE = dyn_cast(Ex->IgnoreParens())) if (VarDecl *Var = dyn_cast(DRE->getDecl())) { if (Var->hasLocalStorage() && !Var->getType().isVolatileQualified()) { for( ; S; S = S->getParent()) { if (S->isDeclScope(Var)) { IsThrownVarInScope = true; break; } if (S->getFlags() & (Scope::FnScope | Scope::ClassScope | Scope::BlockScope | Scope::FunctionPrototypeScope | Scope::ObjCMethodScope | Scope::TryScope)) break; } } } } return BuildCXXThrow(OpLoc, Ex, IsThrownVarInScope); } ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, bool IsThrownVarInScope) { // Don't report an error if 'throw' is used in system headers. if (!getLangOpts().CXXExceptions && !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) { // Delay error emission for the OpenMP device code. targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw"; } // Exceptions aren't allowed in CUDA device code. if (getLangOpts().CUDA) CUDADiagIfDeviceCode(OpLoc, diag::err_cuda_device_exceptions) << "throw" << CurrentCUDATarget(); if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope()) Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw"; if (Ex && !Ex->isTypeDependent()) { QualType ExceptionObjectTy = Context.getExceptionObjectType(Ex->getType()); if (CheckCXXThrowOperand(OpLoc, ExceptionObjectTy, Ex)) return ExprError(); // Initialize the exception result. This implicitly weeds out // abstract types or types with inaccessible copy constructors. // C++0x [class.copymove]p31: // When certain criteria are met, an implementation is allowed to omit the // copy/move construction of a class object [...] // // - in a throw-expression, when the operand is the name of a // non-volatile automatic object (other than a function or // catch-clause // parameter) whose scope does not extend beyond the end of the // innermost enclosing try-block (if there is one), the copy/move // operation from the operand to the exception object (15.1) can be // omitted by constructing the automatic object directly into the // exception object const VarDecl *NRVOVariable = nullptr; if (IsThrownVarInScope) NRVOVariable = getCopyElisionCandidate(QualType(), Ex, CES_Strict); InitializedEntity Entity = InitializedEntity::InitializeException( OpLoc, ExceptionObjectTy, /*NRVO=*/NRVOVariable != nullptr); ExprResult Res = PerformMoveOrCopyInitialization( Entity, NRVOVariable, QualType(), Ex, IsThrownVarInScope); if (Res.isInvalid()) return ExprError(); Ex = Res.get(); } return new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope); } static void collectPublicBases(CXXRecordDecl *RD, llvm::DenseMap &SubobjectsSeen, llvm::SmallPtrSetImpl &VBases, llvm::SetVector &PublicSubobjectsSeen, bool ParentIsPublic) { for (const CXXBaseSpecifier &BS : RD->bases()) { CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl(); bool NewSubobject; // Virtual bases constitute the same subobject. Non-virtual bases are // always distinct subobjects. if (BS.isVirtual()) NewSubobject = VBases.insert(BaseDecl).second; else NewSubobject = true; if (NewSubobject) ++SubobjectsSeen[BaseDecl]; // Only add subobjects which have public access throughout the entire chain. bool PublicPath = ParentIsPublic && BS.getAccessSpecifier() == AS_public; if (PublicPath) PublicSubobjectsSeen.insert(BaseDecl); // Recurse on to each base subobject. collectPublicBases(BaseDecl, SubobjectsSeen, VBases, PublicSubobjectsSeen, PublicPath); } } static void getUnambiguousPublicSubobjects( CXXRecordDecl *RD, llvm::SmallVectorImpl &Objects) { llvm::DenseMap SubobjectsSeen; llvm::SmallSet VBases; llvm::SetVector PublicSubobjectsSeen; SubobjectsSeen[RD] = 1; PublicSubobjectsSeen.insert(RD); collectPublicBases(RD, SubobjectsSeen, VBases, PublicSubobjectsSeen, /*ParentIsPublic=*/true); for (CXXRecordDecl *PublicSubobject : PublicSubobjectsSeen) { // Skip ambiguous objects. if (SubobjectsSeen[PublicSubobject] > 1) continue; Objects.push_back(PublicSubobject); } } /// CheckCXXThrowOperand - Validate the operand of a throw. bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ExceptionObjectTy, Expr *E) { // If the type of the exception would be an incomplete type or a pointer // to an incomplete type other than (cv) void the program is ill-formed. QualType Ty = ExceptionObjectTy; bool isPointer = false; if (const PointerType* Ptr = Ty->getAs()) { Ty = Ptr->getPointeeType(); isPointer = true; } if (!isPointer || !Ty->isVoidType()) { if (RequireCompleteType(ThrowLoc, Ty, isPointer ? diag::err_throw_incomplete_ptr : diag::err_throw_incomplete, E->getSourceRange())) return true; if (RequireNonAbstractType(ThrowLoc, ExceptionObjectTy, diag::err_throw_abstract_type, E)) return true; } // If the exception has class type, we need additional handling. CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); if (!RD) return false; // If we are throwing a polymorphic class type or pointer thereof, // exception handling will make use of the vtable. MarkVTableUsed(ThrowLoc, RD); // If a pointer is thrown, the referenced object will not be destroyed. if (isPointer) return false; // If the class has a destructor, we must be able to call it. if (!RD->hasIrrelevantDestructor()) { if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) { MarkFunctionReferenced(E->getExprLoc(), Destructor); CheckDestructorAccess(E->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_exception) << Ty); if (DiagnoseUseOfDecl(Destructor, E->getExprLoc())) return true; } } // The MSVC ABI creates a list of all types which can catch the exception // object. This list also references the appropriate copy constructor to call // if the object is caught by value and has a non-trivial copy constructor. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { // We are only interested in the public, unambiguous bases contained within // the exception object. Bases which are ambiguous or otherwise // inaccessible are not catchable types. llvm::SmallVector UnambiguousPublicSubobjects; getUnambiguousPublicSubobjects(RD, UnambiguousPublicSubobjects); for (CXXRecordDecl *Subobject : UnambiguousPublicSubobjects) { // Attempt to lookup the copy constructor. Various pieces of machinery // will spring into action, like template instantiation, which means this // cannot be a simple walk of the class's decls. Instead, we must perform // lookup and overload resolution. CXXConstructorDecl *CD = LookupCopyingConstructor(Subobject, 0); if (!CD || CD->isDeleted()) continue; // Mark the constructor referenced as it is used by this throw expression. MarkFunctionReferenced(E->getExprLoc(), CD); // Skip this copy constructor if it is trivial, we don't need to record it // in the catchable type data. if (CD->isTrivial()) continue; // The copy constructor is non-trivial, create a mapping from this class // type to this constructor. // N.B. The selection of copy constructor is not sensitive to this // particular throw-site. Lookup will be performed at the catch-site to // ensure that the copy constructor is, in fact, accessible (via // friendship or any other means). Context.addCopyConstructorForExceptionObject(Subobject, CD); // We don't keep the instantiated default argument expressions around so // we must rebuild them here. for (unsigned I = 1, E = CD->getNumParams(); I != E; ++I) { if (CheckCXXDefaultArgExpr(ThrowLoc, CD, CD->getParamDecl(I))) return true; } } } // Under the Itanium C++ ABI, memory for the exception object is allocated by // the runtime with no ability for the compiler to request additional // alignment. Warn if the exception type requires alignment beyond the minimum // guaranteed by the target C++ runtime. if (Context.getTargetInfo().getCXXABI().isItaniumFamily()) { CharUnits TypeAlign = Context.getTypeAlignInChars(Ty); CharUnits ExnObjAlign = Context.getExnObjectAlignment(); if (ExnObjAlign < TypeAlign) { Diag(ThrowLoc, diag::warn_throw_underaligned_obj); Diag(ThrowLoc, diag::note_throw_underaligned_obj) << Ty << (unsigned)TypeAlign.getQuantity() << (unsigned)ExnObjAlign.getQuantity(); } } return false; } static QualType adjustCVQualifiersForCXXThisWithinLambda( ArrayRef FunctionScopes, QualType ThisTy, DeclContext *CurSemaContext, ASTContext &ASTCtx) { QualType ClassType = ThisTy->getPointeeType(); LambdaScopeInfo *CurLSI = nullptr; DeclContext *CurDC = CurSemaContext; // Iterate through the stack of lambdas starting from the innermost lambda to // the outermost lambda, checking if '*this' is ever captured by copy - since // that could change the cv-qualifiers of the '*this' object. // The object referred to by '*this' starts out with the cv-qualifiers of its // member function. We then start with the innermost lambda and iterate // outward checking to see if any lambda performs a by-copy capture of '*this' // - and if so, any nested lambda must respect the 'constness' of that // capturing lamdbda's call operator. // // Since the FunctionScopeInfo stack is representative of the lexical // nesting of the lambda expressions during initial parsing (and is the best // place for querying information about captures about lambdas that are // partially processed) and perhaps during instantiation of function templates // that contain lambda expressions that need to be transformed BUT not // necessarily during instantiation of a nested generic lambda's function call // operator (which might even be instantiated at the end of the TU) - at which // time the DeclContext tree is mature enough to query capture information // reliably - we use a two pronged approach to walk through all the lexically // enclosing lambda expressions: // // 1) Climb down the FunctionScopeInfo stack as long as each item represents // a Lambda (i.e. LambdaScopeInfo) AND each LSI's 'closure-type' is lexically // enclosed by the call-operator of the LSI below it on the stack (while // tracking the enclosing DC for step 2 if needed). Note the topmost LSI on // the stack represents the innermost lambda. // // 2) If we run out of enclosing LSI's, check if the enclosing DeclContext // represents a lambda's call operator. If it does, we must be instantiating // a generic lambda's call operator (represented by the Current LSI, and // should be the only scenario where an inconsistency between the LSI and the // DeclContext should occur), so climb out the DeclContexts if they // represent lambdas, while querying the corresponding closure types // regarding capture information. // 1) Climb down the function scope info stack. for (int I = FunctionScopes.size(); I-- && isa(FunctionScopes[I]) && (!CurLSI || !CurLSI->Lambda || CurLSI->Lambda->getDeclContext() == cast(FunctionScopes[I])->CallOperator); CurDC = getLambdaAwareParentOfDeclContext(CurDC)) { CurLSI = cast(FunctionScopes[I]); if (!CurLSI->isCXXThisCaptured()) continue; auto C = CurLSI->getCXXThisCapture(); if (C.isCopyCapture()) { ClassType.removeLocalCVRQualifiers(Qualifiers::CVRMask); if (CurLSI->CallOperator->isConst()) ClassType.addConst(); return ASTCtx.getPointerType(ClassType); } } // 2) We've run out of ScopeInfos but check if CurDC is a lambda (which can // happen during instantiation of its nested generic lambda call operator) if (isLambdaCallOperator(CurDC)) { assert(CurLSI && "While computing 'this' capture-type for a generic " "lambda, we must have a corresponding LambdaScopeInfo"); assert(isGenericLambdaCallOperatorSpecialization(CurLSI->CallOperator) && "While computing 'this' capture-type for a generic lambda, when we " "run out of enclosing LSI's, yet the enclosing DC is a " "lambda-call-operator we must be (i.e. Current LSI) in a generic " "lambda call oeprator"); assert(CurDC == getLambdaAwareParentOfDeclContext(CurLSI->CallOperator)); auto IsThisCaptured = [](CXXRecordDecl *Closure, bool &IsByCopy, bool &IsConst) { IsConst = false; IsByCopy = false; for (auto &&C : Closure->captures()) { if (C.capturesThis()) { if (C.getCaptureKind() == LCK_StarThis) IsByCopy = true; if (Closure->getLambdaCallOperator()->isConst()) IsConst = true; return true; } } return false; }; bool IsByCopyCapture = false; bool IsConstCapture = false; CXXRecordDecl *Closure = cast(CurDC->getParent()); while (Closure && IsThisCaptured(Closure, IsByCopyCapture, IsConstCapture)) { if (IsByCopyCapture) { ClassType.removeLocalCVRQualifiers(Qualifiers::CVRMask); if (IsConstCapture) ClassType.addConst(); return ASTCtx.getPointerType(ClassType); } Closure = isLambdaCallOperator(Closure->getParent()) ? cast(Closure->getParent()->getParent()) : nullptr; } } return ASTCtx.getPointerType(ClassType); } QualType Sema::getCurrentThisType() { DeclContext *DC = getFunctionLevelDeclContext(); QualType ThisTy = CXXThisTypeOverride; if (CXXMethodDecl *method = dyn_cast(DC)) { if (method && method->isInstance()) ThisTy = method->getThisType(); } if (ThisTy.isNull() && isLambdaCallOperator(CurContext) && inTemplateInstantiation()) { assert(isa(DC) && "Trying to get 'this' type from static method?"); // This is a lambda call operator that is being instantiated as a default // initializer. DC must point to the enclosing class type, so we can recover // the 'this' type from it. QualType ClassTy = Context.getTypeDeclType(cast(DC)); // There are no cv-qualifiers for 'this' within default initializers, // per [expr.prim.general]p4. ThisTy = Context.getPointerType(ClassTy); } // If we are within a lambda's call operator, the cv-qualifiers of 'this' // might need to be adjusted if the lambda or any of its enclosing lambda's // captures '*this' by copy. if (!ThisTy.isNull() && isLambdaCallOperator(CurContext)) return adjustCVQualifiersForCXXThisWithinLambda(FunctionScopes, ThisTy, CurContext, Context); return ThisTy; } Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S, Decl *ContextDecl, Qualifiers CXXThisTypeQuals, bool Enabled) : S(S), OldCXXThisTypeOverride(S.CXXThisTypeOverride), Enabled(false) { if (!Enabled || !ContextDecl) return; CXXRecordDecl *Record = nullptr; if (ClassTemplateDecl *Template = dyn_cast(ContextDecl)) Record = Template->getTemplatedDecl(); else Record = cast(ContextDecl); QualType T = S.Context.getRecordType(Record); T = S.getASTContext().getQualifiedType(T, CXXThisTypeQuals); S.CXXThisTypeOverride = S.Context.getPointerType(T); this->Enabled = true; } Sema::CXXThisScopeRAII::~CXXThisScopeRAII() { if (Enabled) { S.CXXThisTypeOverride = OldCXXThisTypeOverride; } } bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit, bool BuildAndDiagnose, const unsigned *const FunctionScopeIndexToStopAt, const bool ByCopy) { // We don't need to capture this in an unevaluated context. if (isUnevaluatedContext() && !Explicit) return true; assert((!ByCopy || Explicit) && "cannot implicitly capture *this by value"); const int MaxFunctionScopesIndex = FunctionScopeIndexToStopAt ? *FunctionScopeIndexToStopAt : FunctionScopes.size() - 1; // Check that we can capture the *enclosing object* (referred to by '*this') // by the capturing-entity/closure (lambda/block/etc) at // MaxFunctionScopesIndex-deep on the FunctionScopes stack. // Note: The *enclosing object* can only be captured by-value by a // closure that is a lambda, using the explicit notation: // [*this] { ... }. // Every other capture of the *enclosing object* results in its by-reference // capture. // For a closure 'L' (at MaxFunctionScopesIndex in the FunctionScopes // stack), we can capture the *enclosing object* only if: // - 'L' has an explicit byref or byval capture of the *enclosing object* // - or, 'L' has an implicit capture. // AND // -- there is no enclosing closure // -- or, there is some enclosing closure 'E' that has already captured the // *enclosing object*, and every intervening closure (if any) between 'E' // and 'L' can implicitly capture the *enclosing object*. // -- or, every enclosing closure can implicitly capture the // *enclosing object* unsigned NumCapturingClosures = 0; for (int idx = MaxFunctionScopesIndex; idx >= 0; idx--) { if (CapturingScopeInfo *CSI = dyn_cast(FunctionScopes[idx])) { if (CSI->CXXThisCaptureIndex != 0) { // 'this' is already being captured; there isn't anything more to do. CSI->Captures[CSI->CXXThisCaptureIndex - 1].markUsed(BuildAndDiagnose); break; } LambdaScopeInfo *LSI = dyn_cast(CSI); if (LSI && isGenericLambdaCallOperatorSpecialization(LSI->CallOperator)) { // This context can't implicitly capture 'this'; fail out. if (BuildAndDiagnose) Diag(Loc, diag::err_this_capture) << (Explicit && idx == MaxFunctionScopesIndex); return true; } if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref || CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval || CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block || CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_CapturedRegion || (Explicit && idx == MaxFunctionScopesIndex)) { // Regarding (Explicit && idx == MaxFunctionScopesIndex): only the first // iteration through can be an explicit capture, all enclosing closures, // if any, must perform implicit captures. // This closure can capture 'this'; continue looking upwards. NumCapturingClosures++; continue; } // This context can't implicitly capture 'this'; fail out. if (BuildAndDiagnose) Diag(Loc, diag::err_this_capture) << (Explicit && idx == MaxFunctionScopesIndex); return true; } break; } if (!BuildAndDiagnose) return false; // If we got here, then the closure at MaxFunctionScopesIndex on the // FunctionScopes stack, can capture the *enclosing object*, so capture it // (including implicit by-reference captures in any enclosing closures). // In the loop below, respect the ByCopy flag only for the closure requesting // the capture (i.e. first iteration through the loop below). Ignore it for // all enclosing closure's up to NumCapturingClosures (since they must be // implicitly capturing the *enclosing object* by reference (see loop // above)). assert((!ByCopy || dyn_cast(FunctionScopes[MaxFunctionScopesIndex])) && "Only a lambda can capture the enclosing object (referred to by " "*this) by copy"); QualType ThisTy = getCurrentThisType(); for (int idx = MaxFunctionScopesIndex; NumCapturingClosures; --idx, --NumCapturingClosures) { CapturingScopeInfo *CSI = cast(FunctionScopes[idx]); // The type of the corresponding data member (not a 'this' pointer if 'by // copy'). QualType CaptureType = ThisTy; if (ByCopy) { // If we are capturing the object referred to by '*this' by copy, ignore // any cv qualifiers inherited from the type of the member function for // the type of the closure-type's corresponding data member and any use // of 'this'. CaptureType = ThisTy->getPointeeType(); CaptureType.removeLocalCVRQualifiers(Qualifiers::CVRMask); } bool isNested = NumCapturingClosures > 1; CSI->addThisCapture(isNested, Loc, CaptureType, ByCopy); } return false; } ExprResult Sema::ActOnCXXThis(SourceLocation Loc) { /// C++ 9.3.2: In the body of a non-static member function, the keyword this /// is a non-lvalue expression whose value is the address of the object for /// which the function is called. QualType ThisTy = getCurrentThisType(); if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use); return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false); } Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit) { auto *This = new (Context) CXXThisExpr(Loc, Type, IsImplicit); MarkThisReferenced(This); return This; } void Sema::MarkThisReferenced(CXXThisExpr *This) { CheckCXXThisCapture(This->getExprLoc()); } bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) { // If we're outside the body of a member function, then we'll have a specified // type for 'this'. if (CXXThisTypeOverride.isNull()) return false; // Determine whether we're looking into a class that's currently being // defined. CXXRecordDecl *Class = BaseType->getAsCXXRecordDecl(); return Class && Class->isBeingDefined(); } /// Parse construction of a specified type. /// Can be interpreted either as function-style casting ("int(x)") /// or class type construction ("ClassType(x,y,z)") /// or creation of a value-initialized type ("int()"). ExprResult Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep, SourceLocation LParenOrBraceLoc, MultiExprArg exprs, SourceLocation RParenOrBraceLoc, bool ListInitialization) { if (!TypeRep) return ExprError(); TypeSourceInfo *TInfo; QualType Ty = GetTypeFromParser(TypeRep, &TInfo); if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation()); auto Result = BuildCXXTypeConstructExpr(TInfo, LParenOrBraceLoc, exprs, RParenOrBraceLoc, ListInitialization); // Avoid creating a non-type-dependent expression that contains typos. // Non-type-dependent expressions are liable to be discarded without // checking for embedded typos. if (!Result.isInvalid() && Result.get()->isInstantiationDependent() && !Result.get()->isTypeDependent()) Result = CorrectDelayedTyposInExpr(Result.get()); return Result; } ExprResult Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, SourceLocation LParenOrBraceLoc, MultiExprArg Exprs, SourceLocation RParenOrBraceLoc, bool ListInitialization) { QualType Ty = TInfo->getType(); SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc(); if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) { // FIXME: CXXUnresolvedConstructExpr does not model list-initialization // directly. We work around this by dropping the locations of the braces. SourceRange Locs = ListInitialization ? SourceRange() : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc); return CXXUnresolvedConstructExpr::Create(Context, TInfo, Locs.getBegin(), Exprs, Locs.getEnd()); } assert((!ListInitialization || (Exprs.size() == 1 && isa(Exprs[0]))) && "List initialization must have initializer list as expression."); SourceRange FullRange = SourceRange(TyBeginLoc, RParenOrBraceLoc); InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo); InitializationKind Kind = Exprs.size() ? ListInitialization ? InitializationKind::CreateDirectList( TyBeginLoc, LParenOrBraceLoc, RParenOrBraceLoc) : InitializationKind::CreateDirect(TyBeginLoc, LParenOrBraceLoc, RParenOrBraceLoc) : InitializationKind::CreateValue(TyBeginLoc, LParenOrBraceLoc, RParenOrBraceLoc); // C++1z [expr.type.conv]p1: // If the type is a placeholder for a deduced class type, [...perform class // template argument deduction...] DeducedType *Deduced = Ty->getContainedDeducedType(); if (Deduced && isa(Deduced)) { Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity, Kind, Exprs); if (Ty.isNull()) return ExprError(); Entity = InitializedEntity::InitializeTemporary(TInfo, Ty); } // C++ [expr.type.conv]p1: // If the expression list is a parenthesized single expression, the type // conversion expression is equivalent (in definedness, and if defined in // meaning) to the corresponding cast expression. if (Exprs.size() == 1 && !ListInitialization && !isa(Exprs[0])) { Expr *Arg = Exprs[0]; return BuildCXXFunctionalCastExpr(TInfo, Ty, LParenOrBraceLoc, Arg, RParenOrBraceLoc); } // For an expression of the form T(), T shall not be an array type. QualType ElemTy = Ty; if (Ty->isArrayType()) { if (!ListInitialization) return ExprError(Diag(TyBeginLoc, diag::err_value_init_for_array_type) << FullRange); ElemTy = Context.getBaseElementType(Ty); } // There doesn't seem to be an explicit rule against this but sanity demands // we only construct objects with object types. if (Ty->isFunctionType()) return ExprError(Diag(TyBeginLoc, diag::err_init_for_function_type) << Ty << FullRange); // C++17 [expr.type.conv]p2: // If the type is cv void and the initializer is (), the expression is a // prvalue of the specified type that performs no initialization. if (!Ty->isVoidType() && RequireCompleteType(TyBeginLoc, ElemTy, diag::err_invalid_incomplete_type_use, FullRange)) return ExprError(); // Otherwise, the expression is a prvalue of the specified type whose // result object is direct-initialized (11.6) with the initializer. InitializationSequence InitSeq(*this, Entity, Kind, Exprs); ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Exprs); if (Result.isInvalid()) return Result; Expr *Inner = Result.get(); if (CXXBindTemporaryExpr *BTE = dyn_cast_or_null(Inner)) Inner = BTE->getSubExpr(); if (!isa(Inner) && !isa(Inner)) { // If we created a CXXTemporaryObjectExpr, that node also represents the // functional cast. Otherwise, create an explicit cast to represent // the syntactic form of a functional-style cast that was used here. // // FIXME: Creating a CXXFunctionalCastExpr around a CXXConstructExpr // would give a more consistent AST representation than using a // CXXTemporaryObjectExpr. It's also weird that the functional cast // is sometimes handled by initialization and sometimes not. QualType ResultType = Result.get()->getType(); SourceRange Locs = ListInitialization ? SourceRange() : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc); Result = CXXFunctionalCastExpr::Create( Context, ResultType, Expr::getValueKindForType(Ty), TInfo, CK_NoOp, Result.get(), /*Path=*/nullptr, Locs.getBegin(), Locs.getEnd()); } return Result; } bool Sema::isUsualDeallocationFunction(const CXXMethodDecl *Method) { // [CUDA] Ignore this function, if we can't call it. const FunctionDecl *Caller = dyn_cast(CurContext); if (getLangOpts().CUDA && IdentifyCUDAPreference(Caller, Method) <= CFP_WrongSide) return false; SmallVector PreventedBy; bool Result = Method->isUsualDeallocationFunction(PreventedBy); if (Result || !getLangOpts().CUDA || PreventedBy.empty()) return Result; // In case of CUDA, return true if none of the 1-argument deallocator // functions are actually callable. return llvm::none_of(PreventedBy, [&](const FunctionDecl *FD) { assert(FD->getNumParams() == 1 && "Only single-operand functions should be in PreventedBy"); return IdentifyCUDAPreference(Caller, FD) >= CFP_HostDevice; }); } /// Determine whether the given function is a non-placement /// deallocation function. static bool isNonPlacementDeallocationFunction(Sema &S, FunctionDecl *FD) { if (CXXMethodDecl *Method = dyn_cast(FD)) return S.isUsualDeallocationFunction(Method); if (FD->getOverloadedOperator() != OO_Delete && FD->getOverloadedOperator() != OO_Array_Delete) return false; unsigned UsualParams = 1; if (S.getLangOpts().SizedDeallocation && UsualParams < FD->getNumParams() && S.Context.hasSameUnqualifiedType( FD->getParamDecl(UsualParams)->getType(), S.Context.getSizeType())) ++UsualParams; if (S.getLangOpts().AlignedAllocation && UsualParams < FD->getNumParams() && S.Context.hasSameUnqualifiedType( FD->getParamDecl(UsualParams)->getType(), S.Context.getTypeDeclType(S.getStdAlignValT()))) ++UsualParams; return UsualParams == FD->getNumParams(); } namespace { struct UsualDeallocFnInfo { UsualDeallocFnInfo() : Found(), FD(nullptr) {} UsualDeallocFnInfo(Sema &S, DeclAccessPair Found) : Found(Found), FD(dyn_cast(Found->getUnderlyingDecl())), Destroying(false), HasSizeT(false), HasAlignValT(false), CUDAPref(Sema::CFP_Native) { // A function template declaration is never a usual deallocation function. if (!FD) return; unsigned NumBaseParams = 1; if (FD->isDestroyingOperatorDelete()) { Destroying = true; ++NumBaseParams; } if (NumBaseParams < FD->getNumParams() && S.Context.hasSameUnqualifiedType( FD->getParamDecl(NumBaseParams)->getType(), S.Context.getSizeType())) { ++NumBaseParams; HasSizeT = true; } if (NumBaseParams < FD->getNumParams() && FD->getParamDecl(NumBaseParams)->getType()->isAlignValT()) { ++NumBaseParams; HasAlignValT = true; } // In CUDA, determine how much we'd like / dislike to call this. if (S.getLangOpts().CUDA) if (auto *Caller = dyn_cast(S.CurContext)) CUDAPref = S.IdentifyCUDAPreference(Caller, FD); } explicit operator bool() const { return FD; } bool isBetterThan(const UsualDeallocFnInfo &Other, bool WantSize, bool WantAlign) const { // C++ P0722: // A destroying operator delete is preferred over a non-destroying // operator delete. if (Destroying != Other.Destroying) return Destroying; // C++17 [expr.delete]p10: // If the type has new-extended alignment, a function with a parameter // of type std::align_val_t is preferred; otherwise a function without // such a parameter is preferred if (HasAlignValT != Other.HasAlignValT) return HasAlignValT == WantAlign; if (HasSizeT != Other.HasSizeT) return HasSizeT == WantSize; // Use CUDA call preference as a tiebreaker. return CUDAPref > Other.CUDAPref; } DeclAccessPair Found; FunctionDecl *FD; bool Destroying, HasSizeT, HasAlignValT; Sema::CUDAFunctionPreference CUDAPref; }; } /// Determine whether a type has new-extended alignment. This may be called when /// the type is incomplete (for a delete-expression with an incomplete pointee /// type), in which case it will conservatively return false if the alignment is /// not known. static bool hasNewExtendedAlignment(Sema &S, QualType AllocType) { return S.getLangOpts().AlignedAllocation && S.getASTContext().getTypeAlignIfKnown(AllocType) > S.getASTContext().getTargetInfo().getNewAlign(); } /// Select the correct "usual" deallocation function to use from a selection of /// deallocation functions (either global or class-scope). static UsualDeallocFnInfo resolveDeallocationOverload( Sema &S, LookupResult &R, bool WantSize, bool WantAlign, llvm::SmallVectorImpl *BestFns = nullptr) { UsualDeallocFnInfo Best; for (auto I = R.begin(), E = R.end(); I != E; ++I) { UsualDeallocFnInfo Info(S, I.getPair()); if (!Info || !isNonPlacementDeallocationFunction(S, Info.FD) || Info.CUDAPref == Sema::CFP_Never) continue; if (!Best) { Best = Info; if (BestFns) BestFns->push_back(Info); continue; } if (Best.isBetterThan(Info, WantSize, WantAlign)) continue; // If more than one preferred function is found, all non-preferred // functions are eliminated from further consideration. if (BestFns && Info.isBetterThan(Best, WantSize, WantAlign)) BestFns->clear(); Best = Info; if (BestFns) BestFns->push_back(Info); } return Best; } /// Determine whether a given type is a class for which 'delete[]' would call /// a member 'operator delete[]' with a 'size_t' parameter. This implies that /// we need to store the array size (even if the type is /// trivially-destructible). static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc, QualType allocType) { const RecordType *record = allocType->getBaseElementTypeUnsafe()->getAs(); if (!record) return false; // Try to find an operator delete[] in class scope. DeclarationName deleteName = S.Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete); LookupResult ops(S, deleteName, loc, Sema::LookupOrdinaryName); S.LookupQualifiedName(ops, record->getDecl()); // We're just doing this for information. ops.suppressDiagnostics(); // Very likely: there's no operator delete[]. if (ops.empty()) return false; // If it's ambiguous, it should be illegal to call operator delete[] // on this thing, so it doesn't matter if we allocate extra space or not. if (ops.isAmbiguous()) return false; // C++17 [expr.delete]p10: // If the deallocation functions have class scope, the one without a // parameter of type std::size_t is selected. auto Best = resolveDeallocationOverload( S, ops, /*WantSize*/false, /*WantAlign*/hasNewExtendedAlignment(S, allocType)); return Best && Best.HasSizeT; } /// Parsed a C++ 'new' expression (C++ 5.3.4). /// /// E.g.: /// @code new (memory) int[size][4] @endcode /// or /// @code ::new Foo(23, "hello") @endcode /// /// \param StartLoc The first location of the expression. /// \param UseGlobal True if 'new' was prefixed with '::'. /// \param PlacementLParen Opening paren of the placement arguments. /// \param PlacementArgs Placement new arguments. /// \param PlacementRParen Closing paren of the placement arguments. /// \param TypeIdParens If the type is in parens, the source range. /// \param D The type to be allocated, as well as array dimensions. /// \param Initializer The initializing expression or initializer-list, or null /// if there is none. ExprResult Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, Declarator &D, Expr *Initializer) { Optional ArraySize; // If the specified type is an array, unwrap it and save the expression. if (D.getNumTypeObjects() > 0 && D.getTypeObject(0).Kind == DeclaratorChunk::Array) { DeclaratorChunk &Chunk = D.getTypeObject(0); if (D.getDeclSpec().hasAutoTypeSpec()) return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto) << D.getSourceRange()); if (Chunk.Arr.hasStatic) return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new) << D.getSourceRange()); if (!Chunk.Arr.NumElts && !Initializer) return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size) << D.getSourceRange()); ArraySize = static_cast(Chunk.Arr.NumElts); D.DropFirstTypeObject(); } // Every dimension shall be of constant size. if (ArraySize) { for (unsigned I = 0, N = D.getNumTypeObjects(); I < N; ++I) { if (D.getTypeObject(I).Kind != DeclaratorChunk::Array) break; DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr; if (Expr *NumElts = (Expr *)Array.NumElts) { if (!NumElts->isTypeDependent() && !NumElts->isValueDependent()) { if (getLangOpts().CPlusPlus14) { // C++1y [expr.new]p6: Every constant-expression in a noptr-new-declarator // shall be a converted constant expression (5.19) of type std::size_t // and shall evaluate to a strictly positive value. unsigned IntWidth = Context.getTargetInfo().getIntWidth(); assert(IntWidth && "Builtin type of size 0?"); llvm::APSInt Value(IntWidth); Array.NumElts = CheckConvertedConstantExpression(NumElts, Context.getSizeType(), Value, CCEK_NewExpr) .get(); } else { Array.NumElts = VerifyIntegerConstantExpression(NumElts, nullptr, diag::err_new_array_nonconst) .get(); } if (!Array.NumElts) return ExprError(); } } } } TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/nullptr); QualType AllocType = TInfo->getType(); if (D.isInvalidType()) return ExprError(); SourceRange DirectInitRange; if (ParenListExpr *List = dyn_cast_or_null(Initializer)) DirectInitRange = List->getSourceRange(); return BuildCXXNew(SourceRange(StartLoc, D.getEndLoc()), UseGlobal, PlacementLParen, PlacementArgs, PlacementRParen, TypeIdParens, AllocType, TInfo, ArraySize, DirectInitRange, Initializer); } static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style, Expr *Init) { if (!Init) return true; if (ParenListExpr *PLE = dyn_cast(Init)) return PLE->getNumExprs() == 0; if (isa(Init)) return true; else if (CXXConstructExpr *CCE = dyn_cast(Init)) return !CCE->isListInitialization() && CCE->getConstructor()->isDefaultConstructor(); else if (Style == CXXNewExpr::ListInit) { assert(isa(Init) && "Shouldn't create list CXXConstructExprs for arrays."); return true; } return false; } bool Sema::isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const { if (!getLangOpts().AlignedAllocationUnavailable) return false; if (FD.isDefined()) return false; bool IsAligned = false; if (FD.isReplaceableGlobalAllocationFunction(&IsAligned) && IsAligned) return true; return false; } // Emit a diagnostic if an aligned allocation/deallocation function that is not // implemented in the standard library is selected. void Sema::diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD, SourceLocation Loc) { if (isUnavailableAlignedAllocationFunction(FD)) { const llvm::Triple &T = getASTContext().getTargetInfo().getTriple(); StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling( getASTContext().getTargetInfo().getPlatformName()); OverloadedOperatorKind Kind = FD.getDeclName().getCXXOverloadedOperator(); bool IsDelete = Kind == OO_Delete || Kind == OO_Array_Delete; Diag(Loc, diag::err_aligned_allocation_unavailable) << IsDelete << FD.getType().getAsString() << OSName << alignedAllocMinVersion(T.getOS()).getAsString(); Diag(Loc, diag::note_silence_aligned_allocation_unavailable); } } ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, QualType AllocType, TypeSourceInfo *AllocTypeInfo, Optional ArraySize, SourceRange DirectInitRange, Expr *Initializer) { SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange(); SourceLocation StartLoc = Range.getBegin(); CXXNewExpr::InitializationStyle initStyle; if (DirectInitRange.isValid()) { assert(Initializer && "Have parens but no initializer."); initStyle = CXXNewExpr::CallInit; } else if (Initializer && isa(Initializer)) initStyle = CXXNewExpr::ListInit; else { assert((!Initializer || isa(Initializer) || isa(Initializer)) && "Initializer expression that cannot have been implicitly created."); initStyle = CXXNewExpr::NoInit; } Expr **Inits = &Initializer; unsigned NumInits = Initializer ? 1 : 0; if (ParenListExpr *List = dyn_cast_or_null(Initializer)) { assert(initStyle == CXXNewExpr::CallInit && "paren init for non-call init"); Inits = List->getExprs(); NumInits = List->getNumExprs(); } // C++11 [expr.new]p15: // A new-expression that creates an object of type T initializes that // object as follows: InitializationKind Kind // - If the new-initializer is omitted, the object is default- // initialized (8.5); if no initialization is performed, // the object has indeterminate value = initStyle == CXXNewExpr::NoInit ? InitializationKind::CreateDefault(TypeRange.getBegin()) // - Otherwise, the new-initializer is interpreted according to // the // initialization rules of 8.5 for direct-initialization. : initStyle == CXXNewExpr::ListInit ? InitializationKind::CreateDirectList( TypeRange.getBegin(), Initializer->getBeginLoc(), Initializer->getEndLoc()) : InitializationKind::CreateDirect(TypeRange.getBegin(), DirectInitRange.getBegin(), DirectInitRange.getEnd()); // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for. auto *Deduced = AllocType->getContainedDeducedType(); if (Deduced && isa(Deduced)) { if (ArraySize) return ExprError( Diag(ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(), diag::err_deduced_class_template_compound_type) << /*array*/ 2 << (ArraySize ? (*ArraySize)->getSourceRange() : TypeRange)); InitializedEntity Entity = InitializedEntity::InitializeNew(StartLoc, AllocType); AllocType = DeduceTemplateSpecializationFromInitializer( AllocTypeInfo, Entity, Kind, MultiExprArg(Inits, NumInits)); if (AllocType.isNull()) return ExprError(); } else if (Deduced) { bool Braced = (initStyle == CXXNewExpr::ListInit); if (NumInits == 1) { if (auto p = dyn_cast_or_null(Inits[0])) { Inits = p->getInits(); NumInits = p->getNumInits(); Braced = true; } } if (initStyle == CXXNewExpr::NoInit || NumInits == 0) return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg) << AllocType << TypeRange); if (NumInits > 1) { Expr *FirstBad = Inits[1]; return ExprError(Diag(FirstBad->getBeginLoc(), diag::err_auto_new_ctor_multiple_expressions) << AllocType << TypeRange); } if (Braced && !getLangOpts().CPlusPlus17) Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init) << AllocType << TypeRange; Expr *Deduce = Inits[0]; QualType DeducedType; if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed) return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure) << AllocType << Deduce->getType() << TypeRange << Deduce->getSourceRange()); if (DeducedType.isNull()) return ExprError(); AllocType = DeducedType; } // Per C++0x [expr.new]p5, the type being constructed may be a // typedef of an array type. if (!ArraySize) { if (const ConstantArrayType *Array = Context.getAsConstantArrayType(AllocType)) { ArraySize = IntegerLiteral::Create(Context, Array->getSize(), Context.getSizeType(), TypeRange.getEnd()); AllocType = Array->getElementType(); } } if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange)) return ExprError(); // In ARC, infer 'retaining' for the allocated if (getLangOpts().ObjCAutoRefCount && AllocType.getObjCLifetime() == Qualifiers::OCL_None && AllocType->isObjCLifetimeType()) { AllocType = Context.getLifetimeQualifiedType(AllocType, AllocType->getObjCARCImplicitLifetime()); } QualType ResultType = Context.getPointerType(AllocType); if (ArraySize && *ArraySize && (*ArraySize)->getType()->isNonOverloadPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(*ArraySize); if (result.isInvalid()) return ExprError(); ArraySize = result.get(); } // C++98 5.3.4p6: "The expression in a direct-new-declarator shall have // integral or enumeration type with a non-negative value." // C++11 [expr.new]p6: The expression [...] shall be of integral or unscoped // enumeration type, or a class type for which a single non-explicit // conversion function to integral or unscoped enumeration type exists. // C++1y [expr.new]p6: The expression [...] is implicitly converted to // std::size_t. llvm::Optional KnownArraySize; if (ArraySize && *ArraySize && !(*ArraySize)->isTypeDependent()) { ExprResult ConvertedSize; if (getLangOpts().CPlusPlus14) { assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?"); ConvertedSize = PerformImplicitConversion(*ArraySize, Context.getSizeType(), AA_Converting); if (!ConvertedSize.isInvalid() && (*ArraySize)->getType()->getAs()) // Diagnose the compatibility of this conversion. Diag(StartLoc, diag::warn_cxx98_compat_array_size_conversion) << (*ArraySize)->getType() << 0 << "'size_t'"; } else { class SizeConvertDiagnoser : public ICEConvertDiagnoser { protected: Expr *ArraySize; public: SizeConvertDiagnoser(Expr *ArraySize) : ICEConvertDiagnoser(/*AllowScopedEnumerations*/false, false, false), ArraySize(ArraySize) {} SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_array_size_not_integral) << S.getLangOpts().CPlusPlus11 << T; } SemaDiagnosticBuilder diagnoseIncomplete( Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_array_size_incomplete_type) << T << ArraySize->getSourceRange(); } SemaDiagnosticBuilder diagnoseExplicitConv( Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { return S.Diag(Loc, diag::err_array_size_explicit_conversion) << T << ConvTy; } SemaDiagnosticBuilder noteExplicitConv( Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_array_size_conversion) << ConvTy->isEnumeralType() << ConvTy; } SemaDiagnosticBuilder diagnoseAmbiguous( Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_array_size_ambiguous_conversion) << T; } SemaDiagnosticBuilder noteAmbiguous( Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_array_size_conversion) << ConvTy->isEnumeralType() << ConvTy; } SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { return S.Diag(Loc, S.getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_array_size_conversion : diag::ext_array_size_conversion) << T << ConvTy->isEnumeralType() << ConvTy; } } SizeDiagnoser(*ArraySize); ConvertedSize = PerformContextualImplicitConversion(StartLoc, *ArraySize, SizeDiagnoser); } if (ConvertedSize.isInvalid()) return ExprError(); ArraySize = ConvertedSize.get(); QualType SizeType = (*ArraySize)->getType(); if (!SizeType->isIntegralOrUnscopedEnumerationType()) return ExprError(); // C++98 [expr.new]p7: // The expression in a direct-new-declarator shall have integral type // with a non-negative value. // // Let's see if this is a constant < 0. If so, we reject it out of hand, // per CWG1464. Otherwise, if it's not a constant, we must have an // unparenthesized array type. if (!(*ArraySize)->isValueDependent()) { llvm::APSInt Value; // We've already performed any required implicit conversion to integer or // unscoped enumeration type. // FIXME: Per CWG1464, we are required to check the value prior to // converting to size_t. This will never find a negative array size in // C++14 onwards, because Value is always unsigned here! if ((*ArraySize)->isIntegerConstantExpr(Value, Context)) { if (Value.isSigned() && Value.isNegative()) { return ExprError(Diag((*ArraySize)->getBeginLoc(), diag::err_typecheck_negative_array_size) << (*ArraySize)->getSourceRange()); } if (!AllocType->isDependentType()) { unsigned ActiveSizeBits = ConstantArrayType::getNumAddressingBits(Context, AllocType, Value); if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) return ExprError( Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large) << Value.toString(10) << (*ArraySize)->getSourceRange()); } KnownArraySize = Value.getZExtValue(); } else if (TypeIdParens.isValid()) { // Can't have dynamic array size when the type-id is in parentheses. Diag((*ArraySize)->getBeginLoc(), diag::ext_new_paren_array_nonconst) << (*ArraySize)->getSourceRange() << FixItHint::CreateRemoval(TypeIdParens.getBegin()) << FixItHint::CreateRemoval(TypeIdParens.getEnd()); TypeIdParens = SourceRange(); } } // Note that we do *not* convert the argument in any way. It can // be signed, larger than size_t, whatever. } FunctionDecl *OperatorNew = nullptr; FunctionDecl *OperatorDelete = nullptr; unsigned Alignment = AllocType->isDependentType() ? 0 : Context.getTypeAlign(AllocType); unsigned NewAlignment = Context.getTargetInfo().getNewAlign(); bool PassAlignment = getLangOpts().AlignedAllocation && Alignment > NewAlignment; AllocationFunctionScope Scope = UseGlobal ? AFS_Global : AFS_Both; if (!AllocType->isDependentType() && !Expr::hasAnyTypeDependentArguments(PlacementArgs) && FindAllocationFunctions( StartLoc, SourceRange(PlacementLParen, PlacementRParen), Scope, Scope, AllocType, ArraySize.hasValue(), PassAlignment, PlacementArgs, OperatorNew, OperatorDelete)) return ExprError(); // If this is an array allocation, compute whether the usual array // deallocation function for the type has a size_t parameter. bool UsualArrayDeleteWantsSize = false; if (ArraySize && !AllocType->isDependentType()) UsualArrayDeleteWantsSize = doesUsualArrayDeleteWantSize(*this, StartLoc, AllocType); SmallVector AllPlaceArgs; if (OperatorNew) { const FunctionProtoType *Proto = OperatorNew->getType()->getAs(); VariadicCallType CallType = Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply; // We've already converted the placement args, just fill in any default // arguments. Skip the first parameter because we don't have a corresponding // argument. Skip the second parameter too if we're passing in the // alignment; we've already filled it in. if (GatherArgumentsForCall(PlacementLParen, OperatorNew, Proto, PassAlignment ? 2 : 1, PlacementArgs, AllPlaceArgs, CallType)) return ExprError(); if (!AllPlaceArgs.empty()) PlacementArgs = AllPlaceArgs; // FIXME: This is wrong: PlacementArgs misses out the first (size) argument. DiagnoseSentinelCalls(OperatorNew, PlacementLParen, PlacementArgs); // FIXME: Missing call to CheckFunctionCall or equivalent // Warn if the type is over-aligned and is being allocated by (unaligned) // global operator new. if (PlacementArgs.empty() && !PassAlignment && (OperatorNew->isImplicit() || (OperatorNew->getBeginLoc().isValid() && getSourceManager().isInSystemHeader(OperatorNew->getBeginLoc())))) { if (Alignment > NewAlignment) Diag(StartLoc, diag::warn_overaligned_type) << AllocType << unsigned(Alignment / Context.getCharWidth()) << unsigned(NewAlignment / Context.getCharWidth()); } } // Array 'new' can't have any initializers except empty parentheses. // Initializer lists are also allowed, in C++11. Rely on the parser for the // dialect distinction. if (ArraySize && !isLegalArrayNewInitializer(initStyle, Initializer)) { SourceRange InitRange(Inits[0]->getBeginLoc(), Inits[NumInits - 1]->getEndLoc()); Diag(StartLoc, diag::err_new_array_init_args) << InitRange; return ExprError(); } // If we can perform the initialization, and we've not already done so, // do it now. if (!AllocType->isDependentType() && !Expr::hasAnyTypeDependentArguments( llvm::makeArrayRef(Inits, NumInits))) { // The type we initialize is the complete type, including the array bound. QualType InitType; if (KnownArraySize) InitType = Context.getConstantArrayType( AllocType, llvm::APInt(Context.getTypeSize(Context.getSizeType()), *KnownArraySize), *ArraySize, ArrayType::Normal, 0); else if (ArraySize) InitType = Context.getIncompleteArrayType(AllocType, ArrayType::Normal, 0); else InitType = AllocType; InitializedEntity Entity = InitializedEntity::InitializeNew(StartLoc, InitType); InitializationSequence InitSeq(*this, Entity, Kind, MultiExprArg(Inits, NumInits)); ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, MultiExprArg(Inits, NumInits)); if (FullInit.isInvalid()) return ExprError(); // FullInit is our initializer; strip off CXXBindTemporaryExprs, because // we don't want the initialized object to be destructed. // FIXME: We should not create these in the first place. if (CXXBindTemporaryExpr *Binder = dyn_cast_or_null(FullInit.get())) FullInit = Binder->getSubExpr(); Initializer = FullInit.get(); // FIXME: If we have a KnownArraySize, check that the array bound of the // initializer is no greater than that constant value. if (ArraySize && !*ArraySize) { auto *CAT = Context.getAsConstantArrayType(Initializer->getType()); if (CAT) { // FIXME: Track that the array size was inferred rather than explicitly // specified. ArraySize = IntegerLiteral::Create( Context, CAT->getSize(), Context.getSizeType(), TypeRange.getEnd()); } else { Diag(TypeRange.getEnd(), diag::err_new_array_size_unknown_from_init) << Initializer->getSourceRange(); } } } // Mark the new and delete operators as referenced. if (OperatorNew) { if (DiagnoseUseOfDecl(OperatorNew, StartLoc)) return ExprError(); MarkFunctionReferenced(StartLoc, OperatorNew); } if (OperatorDelete) { if (DiagnoseUseOfDecl(OperatorDelete, StartLoc)) return ExprError(); MarkFunctionReferenced(StartLoc, OperatorDelete); } return CXXNewExpr::Create(Context, UseGlobal, OperatorNew, OperatorDelete, PassAlignment, UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens, ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo, Range, DirectInitRange); } /// Checks that a type is suitable as the allocated type /// in a new-expression. bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc, SourceRange R) { // C++ 5.3.4p1: "[The] type shall be a complete object type, but not an // abstract class type or array thereof. if (AllocType->isFunctionType()) return Diag(Loc, diag::err_bad_new_type) << AllocType << 0 << R; else if (AllocType->isReferenceType()) return Diag(Loc, diag::err_bad_new_type) << AllocType << 1 << R; else if (!AllocType->isDependentType() && RequireCompleteType(Loc, AllocType, diag::err_new_incomplete_type,R)) return true; else if (RequireNonAbstractType(Loc, AllocType, diag::err_allocation_of_abstract_type)) return true; else if (AllocType->isVariablyModifiedType()) return Diag(Loc, diag::err_variably_modified_new_type) << AllocType; else if (AllocType.getAddressSpace() != LangAS::Default && !getLangOpts().OpenCLCPlusPlus) return Diag(Loc, diag::err_address_space_qualified_new) << AllocType.getUnqualifiedType() << AllocType.getQualifiers().getAddressSpaceAttributePrintValue(); else if (getLangOpts().ObjCAutoRefCount) { if (const ArrayType *AT = Context.getAsArrayType(AllocType)) { QualType BaseAllocType = Context.getBaseElementType(AT); if (BaseAllocType.getObjCLifetime() == Qualifiers::OCL_None && BaseAllocType->isObjCLifetimeType()) return Diag(Loc, diag::err_arc_new_array_without_ownership) << BaseAllocType; } } return false; } static bool resolveAllocationOverload( Sema &S, LookupResult &R, SourceRange Range, SmallVectorImpl &Args, bool &PassAlignment, FunctionDecl *&Operator, OverloadCandidateSet *AlignedCandidates, Expr *AlignArg, bool Diagnose) { OverloadCandidateSet Candidates(R.getNameLoc(), OverloadCandidateSet::CSK_Normal); for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end(); Alloc != AllocEnd; ++Alloc) { // Even member operator new/delete are implicitly treated as // static, so don't use AddMemberCandidate. NamedDecl *D = (*Alloc)->getUnderlyingDecl(); if (FunctionTemplateDecl *FnTemplate = dyn_cast(D)) { S.AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(), /*ExplicitTemplateArgs=*/nullptr, Args, Candidates, /*SuppressUserConversions=*/false); continue; } FunctionDecl *Fn = cast(D); S.AddOverloadCandidate(Fn, Alloc.getPair(), Args, Candidates, /*SuppressUserConversions=*/false); } // Do the resolution. OverloadCandidateSet::iterator Best; switch (Candidates.BestViableFunction(S, R.getNameLoc(), Best)) { case OR_Success: { // Got one! FunctionDecl *FnDecl = Best->Function; if (S.CheckAllocationAccess(R.getNameLoc(), Range, R.getNamingClass(), Best->FoundDecl) == Sema::AR_inaccessible) return true; Operator = FnDecl; return false; } case OR_No_Viable_Function: // C++17 [expr.new]p13: // If no matching function is found and the allocated object type has // new-extended alignment, the alignment argument is removed from the // argument list, and overload resolution is performed again. if (PassAlignment) { PassAlignment = false; AlignArg = Args[1]; Args.erase(Args.begin() + 1); return resolveAllocationOverload(S, R, Range, Args, PassAlignment, Operator, &Candidates, AlignArg, Diagnose); } // MSVC will fall back on trying to find a matching global operator new // if operator new[] cannot be found. Also, MSVC will leak by not // generating a call to operator delete or operator delete[], but we // will not replicate that bug. // FIXME: Find out how this interacts with the std::align_val_t fallback // once MSVC implements it. if (R.getLookupName().getCXXOverloadedOperator() == OO_Array_New && S.Context.getLangOpts().MSVCCompat) { R.clear(); R.setLookupName(S.Context.DeclarationNames.getCXXOperatorName(OO_New)); S.LookupQualifiedName(R, S.Context.getTranslationUnitDecl()); // FIXME: This will give bad diagnostics pointing at the wrong functions. return resolveAllocationOverload(S, R, Range, Args, PassAlignment, Operator, /*Candidates=*/nullptr, /*AlignArg=*/nullptr, Diagnose); } if (Diagnose) { PartialDiagnosticAt PD(R.getNameLoc(), S.PDiag(diag::err_ovl_no_viable_function_in_call) << R.getLookupName() << Range); // If we have aligned candidates, only note the align_val_t candidates // from AlignedCandidates and the non-align_val_t candidates from // Candidates. if (AlignedCandidates) { auto IsAligned = [](OverloadCandidate &C) { return C.Function->getNumParams() > 1 && C.Function->getParamDecl(1)->getType()->isAlignValT(); }; auto IsUnaligned = [&](OverloadCandidate &C) { return !IsAligned(C); }; // This was an overaligned allocation, so list the aligned candidates // first. Args.insert(Args.begin() + 1, AlignArg); AlignedCandidates->NoteCandidates(PD, S, OCD_AllCandidates, Args, "", R.getNameLoc(), IsAligned); Args.erase(Args.begin() + 1); Candidates.NoteCandidates(PD, S, OCD_AllCandidates, Args, "", R.getNameLoc(), IsUnaligned); } else { Candidates.NoteCandidates(PD, S, OCD_AllCandidates, Args); } } return true; case OR_Ambiguous: if (Diagnose) { Candidates.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_ambiguous_call) << R.getLookupName() << Range), S, OCD_AmbiguousCandidates, Args); } return true; case OR_Deleted: { if (Diagnose) { Candidates.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_deleted_call) << R.getLookupName() << Range), S, OCD_AllCandidates, Args); } return true; } } llvm_unreachable("Unreachable, bad result from BestViableFunction"); } bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, AllocationFunctionScope NewScope, AllocationFunctionScope DeleteScope, QualType AllocType, bool IsArray, bool &PassAlignment, MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete, bool Diagnose) { // --- Choosing an allocation function --- // C++ 5.3.4p8 - 14 & 18 // 1) If looking in AFS_Global scope for allocation functions, only look in // the global scope. Else, if AFS_Class, only look in the scope of the // allocated class. If AFS_Both, look in both. // 2) If an array size is given, look for operator new[], else look for // operator new. // 3) The first argument is always size_t. Append the arguments from the // placement form. SmallVector AllocArgs; AllocArgs.reserve((PassAlignment ? 2 : 1) + PlaceArgs.size()); // We don't care about the actual value of these arguments. // FIXME: Should the Sema create the expression and embed it in the syntax // tree? Or should the consumer just recalculate the value? // FIXME: Using a dummy value will interact poorly with attribute enable_if. IntegerLiteral Size(Context, llvm::APInt::getNullValue( Context.getTargetInfo().getPointerWidth(0)), Context.getSizeType(), SourceLocation()); AllocArgs.push_back(&Size); QualType AlignValT = Context.VoidTy; if (PassAlignment) { DeclareGlobalNewDelete(); AlignValT = Context.getTypeDeclType(getStdAlignValT()); } CXXScalarValueInitExpr Align(AlignValT, nullptr, SourceLocation()); if (PassAlignment) AllocArgs.push_back(&Align); AllocArgs.insert(AllocArgs.end(), PlaceArgs.begin(), PlaceArgs.end()); // C++ [expr.new]p8: // If the allocated type is a non-array type, the allocation // function's name is operator new and the deallocation function's // name is operator delete. If the allocated type is an array // type, the allocation function's name is operator new[] and the // deallocation function's name is operator delete[]. DeclarationName NewName = Context.DeclarationNames.getCXXOperatorName( IsArray ? OO_Array_New : OO_New); QualType AllocElemType = Context.getBaseElementType(AllocType); // Find the allocation function. { LookupResult R(*this, NewName, StartLoc, LookupOrdinaryName); // C++1z [expr.new]p9: // If the new-expression begins with a unary :: operator, the allocation // function's name is looked up in the global scope. Otherwise, if the // allocated type is a class type T or array thereof, the allocation // function's name is looked up in the scope of T. if (AllocElemType->isRecordType() && NewScope != AFS_Global) LookupQualifiedName(R, AllocElemType->getAsCXXRecordDecl()); // We can see ambiguity here if the allocation function is found in // multiple base classes. if (R.isAmbiguous()) return true; // If this lookup fails to find the name, or if the allocated type is not // a class type, the allocation function's name is looked up in the // global scope. if (R.empty()) { if (NewScope == AFS_Class) return true; LookupQualifiedName(R, Context.getTranslationUnitDecl()); } if (getLangOpts().OpenCLCPlusPlus && R.empty()) { if (PlaceArgs.empty()) { Diag(StartLoc, diag::err_openclcxx_not_supported) << "default new"; } else { Diag(StartLoc, diag::err_openclcxx_placement_new); } return true; } assert(!R.empty() && "implicitly declared allocation functions not found"); assert(!R.isAmbiguous() && "global allocation functions are ambiguous"); // We do our own custom access checks below. R.suppressDiagnostics(); if (resolveAllocationOverload(*this, R, Range, AllocArgs, PassAlignment, OperatorNew, /*Candidates=*/nullptr, /*AlignArg=*/nullptr, Diagnose)) return true; } // We don't need an operator delete if we're running under -fno-exceptions. if (!getLangOpts().Exceptions) { OperatorDelete = nullptr; return false; } // Note, the name of OperatorNew might have been changed from array to // non-array by resolveAllocationOverload. DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName( OperatorNew->getDeclName().getCXXOverloadedOperator() == OO_Array_New ? OO_Array_Delete : OO_Delete); // C++ [expr.new]p19: // // If the new-expression begins with a unary :: operator, the // deallocation function's name is looked up in the global // scope. Otherwise, if the allocated type is a class type T or an // array thereof, the deallocation function's name is looked up in // the scope of T. If this lookup fails to find the name, or if // the allocated type is not a class type or array thereof, the // deallocation function's name is looked up in the global scope. LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName); if (AllocElemType->isRecordType() && DeleteScope != AFS_Global) { auto *RD = cast(AllocElemType->castAs()->getDecl()); LookupQualifiedName(FoundDelete, RD); } if (FoundDelete.isAmbiguous()) return true; // FIXME: clean up expressions? bool FoundGlobalDelete = FoundDelete.empty(); if (FoundDelete.empty()) { if (DeleteScope == AFS_Class) return true; DeclareGlobalNewDelete(); LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl()); } FoundDelete.suppressDiagnostics(); SmallVector, 2> Matches; // Whether we're looking for a placement operator delete is dictated // by whether we selected a placement operator new, not by whether // we had explicit placement arguments. This matters for things like // struct A { void *operator new(size_t, int = 0); ... }; // A *a = new A() // // We don't have any definition for what a "placement allocation function" // is, but we assume it's any allocation function whose // parameter-declaration-clause is anything other than (size_t). // // FIXME: Should (size_t, std::align_val_t) also be considered non-placement? // This affects whether an exception from the constructor of an overaligned // type uses the sized or non-sized form of aligned operator delete. bool isPlacementNew = !PlaceArgs.empty() || OperatorNew->param_size() != 1 || OperatorNew->isVariadic(); if (isPlacementNew) { // C++ [expr.new]p20: // A declaration of a placement deallocation function matches the // declaration of a placement allocation function if it has the // same number of parameters and, after parameter transformations // (8.3.5), all parameter types except the first are // identical. [...] // // To perform this comparison, we compute the function type that // the deallocation function should have, and use that type both // for template argument deduction and for comparison purposes. QualType ExpectedFunctionType; { const FunctionProtoType *Proto = OperatorNew->getType()->getAs(); SmallVector ArgTypes; ArgTypes.push_back(Context.VoidPtrTy); for (unsigned I = 1, N = Proto->getNumParams(); I < N; ++I) ArgTypes.push_back(Proto->getParamType(I)); FunctionProtoType::ExtProtoInfo EPI; // FIXME: This is not part of the standard's rule. EPI.Variadic = Proto->isVariadic(); ExpectedFunctionType = Context.getFunctionType(Context.VoidTy, ArgTypes, EPI); } for (LookupResult::iterator D = FoundDelete.begin(), DEnd = FoundDelete.end(); D != DEnd; ++D) { FunctionDecl *Fn = nullptr; if (FunctionTemplateDecl *FnTmpl = dyn_cast((*D)->getUnderlyingDecl())) { // Perform template argument deduction to try to match the // expected function type. TemplateDeductionInfo Info(StartLoc); if (DeduceTemplateArguments(FnTmpl, nullptr, ExpectedFunctionType, Fn, Info)) continue; } else Fn = cast((*D)->getUnderlyingDecl()); if (Context.hasSameType(adjustCCAndNoReturn(Fn->getType(), ExpectedFunctionType, /*AdjustExcpetionSpec*/true), ExpectedFunctionType)) Matches.push_back(std::make_pair(D.getPair(), Fn)); } if (getLangOpts().CUDA) EraseUnwantedCUDAMatches(dyn_cast(CurContext), Matches); } else { // C++1y [expr.new]p22: // For a non-placement allocation function, the normal deallocation // function lookup is used // // Per [expr.delete]p10, this lookup prefers a member operator delete // without a size_t argument, but prefers a non-member operator delete // with a size_t where possible (which it always is in this case). llvm::SmallVector BestDeallocFns; UsualDeallocFnInfo Selected = resolveDeallocationOverload( *this, FoundDelete, /*WantSize*/ FoundGlobalDelete, /*WantAlign*/ hasNewExtendedAlignment(*this, AllocElemType), &BestDeallocFns); if (Selected) Matches.push_back(std::make_pair(Selected.Found, Selected.FD)); else { // If we failed to select an operator, all remaining functions are viable // but ambiguous. for (auto Fn : BestDeallocFns) Matches.push_back(std::make_pair(Fn.Found, Fn.FD)); } } // C++ [expr.new]p20: // [...] If the lookup finds a single matching deallocation // function, that function will be called; otherwise, no // deallocation function will be called. if (Matches.size() == 1) { OperatorDelete = Matches[0].second; // C++1z [expr.new]p23: // If the lookup finds a usual deallocation function (3.7.4.2) // with a parameter of type std::size_t and that function, considered // as a placement deallocation function, would have been // selected as a match for the allocation function, the program // is ill-formed. if (getLangOpts().CPlusPlus11 && isPlacementNew && isNonPlacementDeallocationFunction(*this, OperatorDelete)) { UsualDeallocFnInfo Info(*this, DeclAccessPair::make(OperatorDelete, AS_public)); // Core issue, per mail to core reflector, 2016-10-09: // If this is a member operator delete, and there is a corresponding // non-sized member operator delete, this isn't /really/ a sized // deallocation function, it just happens to have a size_t parameter. bool IsSizedDelete = Info.HasSizeT; if (IsSizedDelete && !FoundGlobalDelete) { auto NonSizedDelete = resolveDeallocationOverload(*this, FoundDelete, /*WantSize*/false, /*WantAlign*/Info.HasAlignValT); if (NonSizedDelete && !NonSizedDelete.HasSizeT && NonSizedDelete.HasAlignValT == Info.HasAlignValT) IsSizedDelete = false; } if (IsSizedDelete) { SourceRange R = PlaceArgs.empty() ? SourceRange() : SourceRange(PlaceArgs.front()->getBeginLoc(), PlaceArgs.back()->getEndLoc()); Diag(StartLoc, diag::err_placement_new_non_placement_delete) << R; if (!OperatorDelete->isImplicit()) Diag(OperatorDelete->getLocation(), diag::note_previous_decl) << DeleteName; } } CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(), Matches[0].first); } else if (!Matches.empty()) { // We found multiple suitable operators. Per [expr.new]p20, that means we // call no 'operator delete' function, but we should at least warn the user. // FIXME: Suppress this warning if the construction cannot throw. Diag(StartLoc, diag::warn_ambiguous_suitable_delete_function_found) << DeleteName << AllocElemType; for (auto &Match : Matches) Diag(Match.second->getLocation(), diag::note_member_declared_here) << DeleteName; } return false; } /// DeclareGlobalNewDelete - Declare the global forms of operator new and /// delete. These are: /// @code /// // C++03: /// void* operator new(std::size_t) throw(std::bad_alloc); /// void* operator new[](std::size_t) throw(std::bad_alloc); /// void operator delete(void *) throw(); /// void operator delete[](void *) throw(); /// // C++11: /// void* operator new(std::size_t); /// void* operator new[](std::size_t); /// void operator delete(void *) noexcept; /// void operator delete[](void *) noexcept; /// // C++1y: /// void* operator new(std::size_t); /// void* operator new[](std::size_t); /// void operator delete(void *) noexcept; /// void operator delete[](void *) noexcept; /// void operator delete(void *, std::size_t) noexcept; /// void operator delete[](void *, std::size_t) noexcept; /// @endcode /// Note that the placement and nothrow forms of new are *not* implicitly /// declared. Their use requires including \. void Sema::DeclareGlobalNewDelete() { if (GlobalNewDeleteDeclared) return; // The implicitly declared new and delete operators // are not supported in OpenCL. if (getLangOpts().OpenCLCPlusPlus) return; // C++ [basic.std.dynamic]p2: // [...] The following allocation and deallocation functions (18.4) are // implicitly declared in global scope in each translation unit of a // program // // C++03: // void* operator new(std::size_t) throw(std::bad_alloc); // void* operator new[](std::size_t) throw(std::bad_alloc); // void operator delete(void*) throw(); // void operator delete[](void*) throw(); // C++11: // void* operator new(std::size_t); // void* operator new[](std::size_t); // void operator delete(void*) noexcept; // void operator delete[](void*) noexcept; // C++1y: // void* operator new(std::size_t); // void* operator new[](std::size_t); // void operator delete(void*) noexcept; // void operator delete[](void*) noexcept; // void operator delete(void*, std::size_t) noexcept; // void operator delete[](void*, std::size_t) noexcept; // // These implicit declarations introduce only the function names operator // new, operator new[], operator delete, operator delete[]. // // Here, we need to refer to std::bad_alloc, so we will implicitly declare // "std" or "bad_alloc" as necessary to form the exception specification. // However, we do not make these implicit declarations visible to name // lookup. if (!StdBadAlloc && !getLangOpts().CPlusPlus11) { // The "std::bad_alloc" class has not yet been declared, so build it // implicitly. StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class, getOrCreateStdNamespace(), SourceLocation(), SourceLocation(), &PP.getIdentifierTable().get("bad_alloc"), nullptr); getStdBadAlloc()->setImplicit(true); } if (!StdAlignValT && getLangOpts().AlignedAllocation) { // The "std::align_val_t" enum class has not yet been declared, so build it // implicitly. auto *AlignValT = EnumDecl::Create( Context, getOrCreateStdNamespace(), SourceLocation(), SourceLocation(), &PP.getIdentifierTable().get("align_val_t"), nullptr, true, true, true); AlignValT->setIntegerType(Context.getSizeType()); AlignValT->setPromotionType(Context.getSizeType()); AlignValT->setImplicit(true); StdAlignValT = AlignValT; } GlobalNewDeleteDeclared = true; QualType VoidPtr = Context.getPointerType(Context.VoidTy); QualType SizeT = Context.getSizeType(); auto DeclareGlobalAllocationFunctions = [&](OverloadedOperatorKind Kind, QualType Return, QualType Param) { llvm::SmallVector Params; Params.push_back(Param); // Create up to four variants of the function (sized/aligned). bool HasSizedVariant = getLangOpts().SizedDeallocation && (Kind == OO_Delete || Kind == OO_Array_Delete); bool HasAlignedVariant = getLangOpts().AlignedAllocation; int NumSizeVariants = (HasSizedVariant ? 2 : 1); int NumAlignVariants = (HasAlignedVariant ? 2 : 1); for (int Sized = 0; Sized < NumSizeVariants; ++Sized) { if (Sized) Params.push_back(SizeT); for (int Aligned = 0; Aligned < NumAlignVariants; ++Aligned) { if (Aligned) Params.push_back(Context.getTypeDeclType(getStdAlignValT())); DeclareGlobalAllocationFunction( Context.DeclarationNames.getCXXOperatorName(Kind), Return, Params); if (Aligned) Params.pop_back(); } } }; DeclareGlobalAllocationFunctions(OO_New, VoidPtr, SizeT); DeclareGlobalAllocationFunctions(OO_Array_New, VoidPtr, SizeT); DeclareGlobalAllocationFunctions(OO_Delete, Context.VoidTy, VoidPtr); DeclareGlobalAllocationFunctions(OO_Array_Delete, Context.VoidTy, VoidPtr); } /// DeclareGlobalAllocationFunction - Declares a single implicit global /// allocation function if it doesn't already exist. void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, ArrayRef Params) { DeclContext *GlobalCtx = Context.getTranslationUnitDecl(); // Check if this function is already declared. DeclContext::lookup_result R = GlobalCtx->lookup(Name); for (DeclContext::lookup_iterator Alloc = R.begin(), AllocEnd = R.end(); Alloc != AllocEnd; ++Alloc) { // Only look at non-template functions, as it is the predefined, // non-templated allocation function we are trying to declare here. if (FunctionDecl *Func = dyn_cast(*Alloc)) { if (Func->getNumParams() == Params.size()) { llvm::SmallVector FuncParams; for (auto *P : Func->parameters()) FuncParams.push_back( Context.getCanonicalType(P->getType().getUnqualifiedType())); if (llvm::makeArrayRef(FuncParams) == Params) { // Make the function visible to name lookup, even if we found it in // an unimported module. It either is an implicitly-declared global // allocation function, or is suppressing that function. Func->setVisibleDespiteOwningModule(); return; } } } } FunctionProtoType::ExtProtoInfo EPI(Context.getDefaultCallingConvention( /*IsVariadic=*/false, /*IsCXXMethod=*/false, /*IsBuiltin=*/true)); QualType BadAllocType; bool HasBadAllocExceptionSpec = (Name.getCXXOverloadedOperator() == OO_New || Name.getCXXOverloadedOperator() == OO_Array_New); if (HasBadAllocExceptionSpec) { if (!getLangOpts().CPlusPlus11) { BadAllocType = Context.getTypeDeclType(getStdBadAlloc()); assert(StdBadAlloc && "Must have std::bad_alloc declared"); EPI.ExceptionSpec.Type = EST_Dynamic; EPI.ExceptionSpec.Exceptions = llvm::makeArrayRef(BadAllocType); } } else { EPI.ExceptionSpec = getLangOpts().CPlusPlus11 ? EST_BasicNoexcept : EST_DynamicNone; } auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) { QualType FnType = Context.getFunctionType(Return, Params, EPI); FunctionDecl *Alloc = FunctionDecl::Create( Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, FnType, /*TInfo=*/nullptr, SC_None, false, true); Alloc->setImplicit(); // Global allocation functions should always be visible. Alloc->setVisibleDespiteOwningModule(); Alloc->addAttr(VisibilityAttr::CreateImplicit( Context, LangOpts.GlobalAllocationFunctionVisibilityHidden ? VisibilityAttr::Hidden : VisibilityAttr::Default)); llvm::SmallVector ParamDecls; for (QualType T : Params) { ParamDecls.push_back(ParmVarDecl::Create( Context, Alloc, SourceLocation(), SourceLocation(), nullptr, T, /*TInfo=*/nullptr, SC_None, nullptr)); ParamDecls.back()->setImplicit(); } Alloc->setParams(ParamDecls); if (ExtraAttr) Alloc->addAttr(ExtraAttr); Context.getTranslationUnitDecl()->addDecl(Alloc); IdResolver.tryAddTopLevelDecl(Alloc, Name); }; if (!LangOpts.CUDA) CreateAllocationFunctionDecl(nullptr); else { // Host and device get their own declaration so each can be // defined or re-declared independently. CreateAllocationFunctionDecl(CUDAHostAttr::CreateImplicit(Context)); CreateAllocationFunctionDecl(CUDADeviceAttr::CreateImplicit(Context)); } } FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc, bool CanProvideSize, bool Overaligned, DeclarationName Name) { DeclareGlobalNewDelete(); LookupResult FoundDelete(*this, Name, StartLoc, LookupOrdinaryName); LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl()); // FIXME: It's possible for this to result in ambiguity, through a // user-declared variadic operator delete or the enable_if attribute. We // should probably not consider those cases to be usual deallocation // functions. But for now we just make an arbitrary choice in that case. auto Result = resolveDeallocationOverload(*this, FoundDelete, CanProvideSize, Overaligned); assert(Result.FD && "operator delete missing from global scope?"); return Result.FD; } FunctionDecl *Sema::FindDeallocationFunctionForDestructor(SourceLocation Loc, CXXRecordDecl *RD) { DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Delete); FunctionDecl *OperatorDelete = nullptr; if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete)) return nullptr; if (OperatorDelete) return OperatorDelete; // If there's no class-specific operator delete, look up the global // non-array delete. return FindUsualDeallocationFunction( Loc, true, hasNewExtendedAlignment(*this, Context.getRecordType(RD)), Name); } bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl *&Operator, bool Diagnose) { LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName); // Try to find operator delete/operator delete[] in class scope. LookupQualifiedName(Found, RD); if (Found.isAmbiguous()) return true; Found.suppressDiagnostics(); bool Overaligned = hasNewExtendedAlignment(*this, Context.getRecordType(RD)); // C++17 [expr.delete]p10: // If the deallocation functions have class scope, the one without a // parameter of type std::size_t is selected. llvm::SmallVector Matches; resolveDeallocationOverload(*this, Found, /*WantSize*/ false, /*WantAlign*/ Overaligned, &Matches); // If we could find an overload, use it. if (Matches.size() == 1) { Operator = cast(Matches[0].FD); // FIXME: DiagnoseUseOfDecl? if (Operator->isDeleted()) { if (Diagnose) { Diag(StartLoc, diag::err_deleted_function_use); NoteDeletedFunction(Operator); } return true; } if (CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(), Matches[0].Found, Diagnose) == AR_inaccessible) return true; return false; } // We found multiple suitable operators; complain about the ambiguity. // FIXME: The standard doesn't say to do this; it appears that the intent // is that this should never happen. if (!Matches.empty()) { if (Diagnose) { Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found) << Name << RD; for (auto &Match : Matches) Diag(Match.FD->getLocation(), diag::note_member_declared_here) << Name; } return true; } // We did find operator delete/operator delete[] declarations, but // none of them were suitable. if (!Found.empty()) { if (Diagnose) { Diag(StartLoc, diag::err_no_suitable_delete_member_function_found) << Name << RD; for (NamedDecl *D : Found) Diag(D->getUnderlyingDecl()->getLocation(), diag::note_member_declared_here) << Name; } return true; } Operator = nullptr; return false; } namespace { /// Checks whether delete-expression, and new-expression used for /// initializing deletee have the same array form. class MismatchingNewDeleteDetector { public: enum MismatchResult { /// Indicates that there is no mismatch or a mismatch cannot be proven. NoMismatch, /// Indicates that variable is initialized with mismatching form of \a new. VarInitMismatches, /// Indicates that member is initialized with mismatching form of \a new. MemberInitMismatches, /// Indicates that 1 or more constructors' definitions could not been /// analyzed, and they will be checked again at the end of translation unit. AnalyzeLater }; /// \param EndOfTU True, if this is the final analysis at the end of /// translation unit. False, if this is the initial analysis at the point /// delete-expression was encountered. explicit MismatchingNewDeleteDetector(bool EndOfTU) : Field(nullptr), IsArrayForm(false), EndOfTU(EndOfTU), HasUndefinedConstructors(false) {} /// Checks whether pointee of a delete-expression is initialized with /// matching form of new-expression. /// /// If return value is \c VarInitMismatches or \c MemberInitMismatches at the /// point where delete-expression is encountered, then a warning will be /// issued immediately. If return value is \c AnalyzeLater at the point where /// delete-expression is seen, then member will be analyzed at the end of /// translation unit. \c AnalyzeLater is returned iff at least one constructor /// couldn't be analyzed. If at least one constructor initializes the member /// with matching type of new, the return value is \c NoMismatch. MismatchResult analyzeDeleteExpr(const CXXDeleteExpr *DE); /// Analyzes a class member. /// \param Field Class member to analyze. /// \param DeleteWasArrayForm Array form-ness of the delete-expression used /// for deleting the \p Field. MismatchResult analyzeField(FieldDecl *Field, bool DeleteWasArrayForm); FieldDecl *Field; /// List of mismatching new-expressions used for initialization of the pointee llvm::SmallVector NewExprs; /// Indicates whether delete-expression was in array form. bool IsArrayForm; private: const bool EndOfTU; /// Indicates that there is at least one constructor without body. bool HasUndefinedConstructors; /// Returns \c CXXNewExpr from given initialization expression. /// \param E Expression used for initializing pointee in delete-expression. /// E can be a single-element \c InitListExpr consisting of new-expression. const CXXNewExpr *getNewExprFromInitListOrExpr(const Expr *E); /// Returns whether member is initialized with mismatching form of /// \c new either by the member initializer or in-class initialization. /// /// If bodies of all constructors are not visible at the end of translation /// unit or at least one constructor initializes member with the matching /// form of \c new, mismatch cannot be proven, and this function will return /// \c NoMismatch. MismatchResult analyzeMemberExpr(const MemberExpr *ME); /// Returns whether variable is initialized with mismatching form of /// \c new. /// /// If variable is initialized with matching form of \c new or variable is not /// initialized with a \c new expression, this function will return true. /// If variable is initialized with mismatching form of \c new, returns false. /// \param D Variable to analyze. bool hasMatchingVarInit(const DeclRefExpr *D); /// Checks whether the constructor initializes pointee with mismatching /// form of \c new. /// /// Returns true, if member is initialized with matching form of \c new in /// member initializer list. Returns false, if member is initialized with the /// matching form of \c new in this constructor's initializer or given /// constructor isn't defined at the point where delete-expression is seen, or /// member isn't initialized by the constructor. bool hasMatchingNewInCtor(const CXXConstructorDecl *CD); /// Checks whether member is initialized with matching form of /// \c new in member initializer list. bool hasMatchingNewInCtorInit(const CXXCtorInitializer *CI); /// Checks whether member is initialized with mismatching form of \c new by /// in-class initializer. MismatchResult analyzeInClassInitializer(); }; } MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeDeleteExpr(const CXXDeleteExpr *DE) { NewExprs.clear(); assert(DE && "Expected delete-expression"); IsArrayForm = DE->isArrayForm(); const Expr *E = DE->getArgument()->IgnoreParenImpCasts(); if (const MemberExpr *ME = dyn_cast(E)) { return analyzeMemberExpr(ME); } else if (const DeclRefExpr *D = dyn_cast(E)) { if (!hasMatchingVarInit(D)) return VarInitMismatches; } return NoMismatch; } const CXXNewExpr * MismatchingNewDeleteDetector::getNewExprFromInitListOrExpr(const Expr *E) { assert(E != nullptr && "Expected a valid initializer expression"); E = E->IgnoreParenImpCasts(); if (const InitListExpr *ILE = dyn_cast(E)) { if (ILE->getNumInits() == 1) E = dyn_cast(ILE->getInit(0)->IgnoreParenImpCasts()); } return dyn_cast_or_null(E); } bool MismatchingNewDeleteDetector::hasMatchingNewInCtorInit( const CXXCtorInitializer *CI) { const CXXNewExpr *NE = nullptr; if (Field == CI->getMember() && (NE = getNewExprFromInitListOrExpr(CI->getInit()))) { if (NE->isArray() == IsArrayForm) return true; else NewExprs.push_back(NE); } return false; } bool MismatchingNewDeleteDetector::hasMatchingNewInCtor( const CXXConstructorDecl *CD) { if (CD->isImplicit()) return false; const FunctionDecl *Definition = CD; if (!CD->isThisDeclarationADefinition() && !CD->isDefined(Definition)) { HasUndefinedConstructors = true; return EndOfTU; } for (const auto *CI : cast(Definition)->inits()) { if (hasMatchingNewInCtorInit(CI)) return true; } return false; } MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeInClassInitializer() { assert(Field != nullptr && "This should be called only for members"); const Expr *InitExpr = Field->getInClassInitializer(); if (!InitExpr) return EndOfTU ? NoMismatch : AnalyzeLater; if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) { if (NE->isArray() != IsArrayForm) { NewExprs.push_back(NE); return MemberInitMismatches; } } return NoMismatch; } MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeField(FieldDecl *Field, bool DeleteWasArrayForm) { assert(Field != nullptr && "Analysis requires a valid class member."); this->Field = Field; IsArrayForm = DeleteWasArrayForm; const CXXRecordDecl *RD = cast(Field->getParent()); for (const auto *CD : RD->ctors()) { if (hasMatchingNewInCtor(CD)) return NoMismatch; } if (HasUndefinedConstructors) return EndOfTU ? NoMismatch : AnalyzeLater; if (!NewExprs.empty()) return MemberInitMismatches; return Field->hasInClassInitializer() ? analyzeInClassInitializer() : NoMismatch; } MismatchingNewDeleteDetector::MismatchResult MismatchingNewDeleteDetector::analyzeMemberExpr(const MemberExpr *ME) { assert(ME != nullptr && "Expected a member expression"); if (FieldDecl *F = dyn_cast(ME->getMemberDecl())) return analyzeField(F, IsArrayForm); return NoMismatch; } bool MismatchingNewDeleteDetector::hasMatchingVarInit(const DeclRefExpr *D) { const CXXNewExpr *NE = nullptr; if (const VarDecl *VD = dyn_cast(D->getDecl())) { if (VD->hasInit() && (NE = getNewExprFromInitListOrExpr(VD->getInit())) && NE->isArray() != IsArrayForm) { NewExprs.push_back(NE); } } return NewExprs.empty(); } static void DiagnoseMismatchedNewDelete(Sema &SemaRef, SourceLocation DeleteLoc, const MismatchingNewDeleteDetector &Detector) { SourceLocation EndOfDelete = SemaRef.getLocForEndOfToken(DeleteLoc); FixItHint H; if (!Detector.IsArrayForm) H = FixItHint::CreateInsertion(EndOfDelete, "[]"); else { SourceLocation RSquare = Lexer::findLocationAfterToken( DeleteLoc, tok::l_square, SemaRef.getSourceManager(), SemaRef.getLangOpts(), true); if (RSquare.isValid()) H = FixItHint::CreateRemoval(SourceRange(EndOfDelete, RSquare)); } SemaRef.Diag(DeleteLoc, diag::warn_mismatched_delete_new) << Detector.IsArrayForm << H; for (const auto *NE : Detector.NewExprs) SemaRef.Diag(NE->getExprLoc(), diag::note_allocated_here) << Detector.IsArrayForm; } void Sema::AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE) { if (Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation())) return; MismatchingNewDeleteDetector Detector(/*EndOfTU=*/false); switch (Detector.analyzeDeleteExpr(DE)) { case MismatchingNewDeleteDetector::VarInitMismatches: case MismatchingNewDeleteDetector::MemberInitMismatches: { DiagnoseMismatchedNewDelete(*this, DE->getBeginLoc(), Detector); break; } case MismatchingNewDeleteDetector::AnalyzeLater: { DeleteExprs[Detector.Field].push_back( std::make_pair(DE->getBeginLoc(), DE->isArrayForm())); break; } case MismatchingNewDeleteDetector::NoMismatch: break; } } void Sema::AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc, bool DeleteWasArrayForm) { MismatchingNewDeleteDetector Detector(/*EndOfTU=*/true); switch (Detector.analyzeField(Field, DeleteWasArrayForm)) { case MismatchingNewDeleteDetector::VarInitMismatches: llvm_unreachable("This analysis should have been done for class members."); case MismatchingNewDeleteDetector::AnalyzeLater: llvm_unreachable("Analysis cannot be postponed any point beyond end of " "translation unit."); case MismatchingNewDeleteDetector::MemberInitMismatches: DiagnoseMismatchedNewDelete(*this, DeleteLoc, Detector); break; case MismatchingNewDeleteDetector::NoMismatch: break; } } /// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in: /// @code ::delete ptr; @endcode /// or /// @code delete [] ptr; @endcode ExprResult Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool ArrayForm, Expr *ExE) { // C++ [expr.delete]p1: // The operand shall have a pointer type, or a class type having a single // non-explicit conversion function to a pointer type. The result has type // void. // // DR599 amends "pointer type" to "pointer to object type" in both cases. ExprResult Ex = ExE; FunctionDecl *OperatorDelete = nullptr; bool ArrayFormAsWritten = ArrayForm; bool UsualArrayDeleteWantsSize = false; if (!Ex.get()->isTypeDependent()) { // Perform lvalue-to-rvalue cast, if needed. Ex = DefaultLvalueConversion(Ex.get()); if (Ex.isInvalid()) return ExprError(); QualType Type = Ex.get()->getType(); class DeleteConverter : public ContextualImplicitConverter { public: DeleteConverter() : ContextualImplicitConverter(false, true) {} bool match(QualType ConvType) override { // FIXME: If we have an operator T* and an operator void*, we must pick // the operator T*. if (const PointerType *ConvPtrType = ConvType->getAs()) if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType()) return true; return false; } SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_delete_operand) << T; } SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_delete_incomplete_class_type) << T; } SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { return S.Diag(Loc, diag::err_delete_explicit_conversion) << T << ConvTy; } SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_delete_conversion) << ConvTy; } SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override { return S.Diag(Loc, diag::err_ambiguous_delete_operand) << T; } SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { return S.Diag(Conv->getLocation(), diag::note_delete_conversion) << ConvTy; } SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override { llvm_unreachable("conversion functions are permitted"); } } Converter; Ex = PerformContextualImplicitConversion(StartLoc, Ex.get(), Converter); if (Ex.isInvalid()) return ExprError(); Type = Ex.get()->getType(); if (!Converter.match(Type)) // FIXME: PerformContextualImplicitConversion should return ExprError // itself in this case. return ExprError(); QualType Pointee = Type->castAs()->getPointeeType(); QualType PointeeElem = Context.getBaseElementType(Pointee); if (Pointee.getAddressSpace() != LangAS::Default && !getLangOpts().OpenCLCPlusPlus) return Diag(Ex.get()->getBeginLoc(), diag::err_address_space_qualified_delete) << Pointee.getUnqualifiedType() << Pointee.getQualifiers().getAddressSpaceAttributePrintValue(); CXXRecordDecl *PointeeRD = nullptr; if (Pointee->isVoidType() && !isSFINAEContext()) { // The C++ standard bans deleting a pointer to a non-object type, which // effectively bans deletion of "void*". However, most compilers support // this, so we treat it as a warning unless we're in a SFINAE context. Diag(StartLoc, diag::ext_delete_void_ptr_operand) << Type << Ex.get()->getSourceRange(); } else if (Pointee->isFunctionType() || Pointee->isVoidType()) { return ExprError(Diag(StartLoc, diag::err_delete_operand) << Type << Ex.get()->getSourceRange()); } else if (!Pointee->isDependentType()) { // FIXME: This can result in errors if the definition was imported from a // module but is hidden. if (!RequireCompleteType(StartLoc, Pointee, diag::warn_delete_incomplete, Ex.get())) { if (const RecordType *RT = PointeeElem->getAs()) PointeeRD = cast(RT->getDecl()); } } if (Pointee->isArrayType() && !ArrayForm) { Diag(StartLoc, diag::warn_delete_array_type) << Type << Ex.get()->getSourceRange() << FixItHint::CreateInsertion(getLocForEndOfToken(StartLoc), "[]"); ArrayForm = true; } DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName( ArrayForm ? OO_Array_Delete : OO_Delete); if (PointeeRD) { if (!UseGlobal && FindDeallocationFunction(StartLoc, PointeeRD, DeleteName, OperatorDelete)) return ExprError(); // If we're allocating an array of records, check whether the // usual operator delete[] has a size_t parameter. if (ArrayForm) { // If the user specifically asked to use the global allocator, // we'll need to do the lookup into the class. if (UseGlobal) UsualArrayDeleteWantsSize = doesUsualArrayDeleteWantSize(*this, StartLoc, PointeeElem); // Otherwise, the usual operator delete[] should be the // function we just found. else if (OperatorDelete && isa(OperatorDelete)) UsualArrayDeleteWantsSize = UsualDeallocFnInfo(*this, DeclAccessPair::make(OperatorDelete, AS_public)) .HasSizeT; } if (!PointeeRD->hasIrrelevantDestructor()) if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) { MarkFunctionReferenced(StartLoc, const_cast(Dtor)); if (DiagnoseUseOfDecl(Dtor, StartLoc)) return ExprError(); } CheckVirtualDtorCall(PointeeRD->getDestructor(), StartLoc, /*IsDelete=*/true, /*CallCanBeVirtual=*/true, /*WarnOnNonAbstractTypes=*/!ArrayForm, SourceLocation()); } if (!OperatorDelete) { if (getLangOpts().OpenCLCPlusPlus) { Diag(StartLoc, diag::err_openclcxx_not_supported) << "default delete"; return ExprError(); } bool IsComplete = isCompleteType(StartLoc, Pointee); bool CanProvideSize = IsComplete && (!ArrayForm || UsualArrayDeleteWantsSize || Pointee.isDestructedType()); bool Overaligned = hasNewExtendedAlignment(*this, Pointee); // Look for a global declaration. OperatorDelete = FindUsualDeallocationFunction(StartLoc, CanProvideSize, Overaligned, DeleteName); } MarkFunctionReferenced(StartLoc, OperatorDelete); // Check access and ambiguity of destructor if we're going to call it. // Note that this is required even for a virtual delete. bool IsVirtualDelete = false; if (PointeeRD) { if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) { CheckDestructorAccess(Ex.get()->getExprLoc(), Dtor, PDiag(diag::err_access_dtor) << PointeeElem); IsVirtualDelete = Dtor->isVirtual(); } } DiagnoseUseOfDecl(OperatorDelete, StartLoc); // Convert the operand to the type of the first parameter of operator // delete. This is only necessary if we selected a destroying operator // delete that we are going to call (non-virtually); converting to void* // is trivial and left to AST consumers to handle. QualType ParamType = OperatorDelete->getParamDecl(0)->getType(); if (!IsVirtualDelete && !ParamType->getPointeeType()->isVoidType()) { Qualifiers Qs = Pointee.getQualifiers(); if (Qs.hasCVRQualifiers()) { // Qualifiers are irrelevant to this conversion; we're only looking // for access and ambiguity. Qs.removeCVRQualifiers(); QualType Unqual = Context.getPointerType( Context.getQualifiedType(Pointee.getUnqualifiedType(), Qs)); Ex = ImpCastExprToType(Ex.get(), Unqual, CK_NoOp); } Ex = PerformImplicitConversion(Ex.get(), ParamType, AA_Passing); if (Ex.isInvalid()) return ExprError(); } } CXXDeleteExpr *Result = new (Context) CXXDeleteExpr( Context.VoidTy, UseGlobal, ArrayForm, ArrayFormAsWritten, UsualArrayDeleteWantsSize, OperatorDelete, Ex.get(), StartLoc); AnalyzeDeleteExprMismatch(Result); return Result; } static bool resolveBuiltinNewDeleteOverload(Sema &S, CallExpr *TheCall, bool IsDelete, FunctionDecl *&Operator) { DeclarationName NewName = S.Context.DeclarationNames.getCXXOperatorName( IsDelete ? OO_Delete : OO_New); LookupResult R(S, NewName, TheCall->getBeginLoc(), Sema::LookupOrdinaryName); S.LookupQualifiedName(R, S.Context.getTranslationUnitDecl()); assert(!R.empty() && "implicitly declared allocation functions not found"); assert(!R.isAmbiguous() && "global allocation functions are ambiguous"); // We do our own custom access checks below. R.suppressDiagnostics(); SmallVector Args(TheCall->arg_begin(), TheCall->arg_end()); OverloadCandidateSet Candidates(R.getNameLoc(), OverloadCandidateSet::CSK_Normal); for (LookupResult::iterator FnOvl = R.begin(), FnOvlEnd = R.end(); FnOvl != FnOvlEnd; ++FnOvl) { // Even member operator new/delete are implicitly treated as // static, so don't use AddMemberCandidate. NamedDecl *D = (*FnOvl)->getUnderlyingDecl(); if (FunctionTemplateDecl *FnTemplate = dyn_cast(D)) { S.AddTemplateOverloadCandidate(FnTemplate, FnOvl.getPair(), /*ExplicitTemplateArgs=*/nullptr, Args, Candidates, /*SuppressUserConversions=*/false); continue; } FunctionDecl *Fn = cast(D); S.AddOverloadCandidate(Fn, FnOvl.getPair(), Args, Candidates, /*SuppressUserConversions=*/false); } SourceRange Range = TheCall->getSourceRange(); // Do the resolution. OverloadCandidateSet::iterator Best; switch (Candidates.BestViableFunction(S, R.getNameLoc(), Best)) { case OR_Success: { // Got one! FunctionDecl *FnDecl = Best->Function; assert(R.getNamingClass() == nullptr && "class members should not be considered"); if (!FnDecl->isReplaceableGlobalAllocationFunction()) { S.Diag(R.getNameLoc(), diag::err_builtin_operator_new_delete_not_usual) << (IsDelete ? 1 : 0) << Range; S.Diag(FnDecl->getLocation(), diag::note_non_usual_function_declared_here) << R.getLookupName() << FnDecl->getSourceRange(); return true; } Operator = FnDecl; return false; } case OR_No_Viable_Function: Candidates.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_no_viable_function_in_call) << R.getLookupName() << Range), S, OCD_AllCandidates, Args); return true; case OR_Ambiguous: Candidates.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_ambiguous_call) << R.getLookupName() << Range), S, OCD_AmbiguousCandidates, Args); return true; case OR_Deleted: { Candidates.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_deleted_call) << R.getLookupName() << Range), S, OCD_AllCandidates, Args); return true; } } llvm_unreachable("Unreachable, bad result from BestViableFunction"); } ExprResult Sema::SemaBuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult, bool IsDelete) { CallExpr *TheCall = cast(TheCallResult.get()); if (!getLangOpts().CPlusPlus) { Diag(TheCall->getExprLoc(), diag::err_builtin_requires_language) << (IsDelete ? "__builtin_operator_delete" : "__builtin_operator_new") << "C++"; return ExprError(); } // CodeGen assumes it can find the global new and delete to call, // so ensure that they are declared. DeclareGlobalNewDelete(); FunctionDecl *OperatorNewOrDelete = nullptr; if (resolveBuiltinNewDeleteOverload(*this, TheCall, IsDelete, OperatorNewOrDelete)) return ExprError(); assert(OperatorNewOrDelete && "should be found"); DiagnoseUseOfDecl(OperatorNewOrDelete, TheCall->getExprLoc()); MarkFunctionReferenced(TheCall->getExprLoc(), OperatorNewOrDelete); TheCall->setType(OperatorNewOrDelete->getReturnType()); for (unsigned i = 0; i != TheCall->getNumArgs(); ++i) { QualType ParamTy = OperatorNewOrDelete->getParamDecl(i)->getType(); InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, ParamTy, false); ExprResult Arg = PerformCopyInitialization( Entity, TheCall->getArg(i)->getBeginLoc(), TheCall->getArg(i)); if (Arg.isInvalid()) return ExprError(); TheCall->setArg(i, Arg.get()); } auto Callee = dyn_cast(TheCall->getCallee()); assert(Callee && Callee->getCastKind() == CK_BuiltinFnToFnPtr && "Callee expected to be implicit cast to a builtin function pointer"); Callee->setType(OperatorNewOrDelete->getType()); return TheCallResult; } void Sema::CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc, bool IsDelete, bool CallCanBeVirtual, bool WarnOnNonAbstractTypes, SourceLocation DtorLoc) { if (!dtor || dtor->isVirtual() || !CallCanBeVirtual || isUnevaluatedContext()) return; // C++ [expr.delete]p3: // In the first alternative (delete object), if the static type of the // object to be deleted is different from its dynamic type, the static // type shall be a base class of the dynamic type of the object to be // deleted and the static type shall have a virtual destructor or the // behavior is undefined. // const CXXRecordDecl *PointeeRD = dtor->getParent(); // Note: a final class cannot be derived from, no issue there if (!PointeeRD->isPolymorphic() || PointeeRD->hasAttr()) return; // If the superclass is in a system header, there's nothing that can be done. // The `delete` (where we emit the warning) can be in a system header, // what matters for this warning is where the deleted type is defined. if (getSourceManager().isInSystemHeader(PointeeRD->getLocation())) return; QualType ClassType = dtor->getThisType()->getPointeeType(); if (PointeeRD->isAbstract()) { // If the class is abstract, we warn by default, because we're // sure the code has undefined behavior. Diag(Loc, diag::warn_delete_abstract_non_virtual_dtor) << (IsDelete ? 0 : 1) << ClassType; } else if (WarnOnNonAbstractTypes) { // Otherwise, if this is not an array delete, it's a bit suspect, // but not necessarily wrong. Diag(Loc, diag::warn_delete_non_virtual_dtor) << (IsDelete ? 0 : 1) << ClassType; } if (!IsDelete) { std::string TypeStr; ClassType.getAsStringInternal(TypeStr, getPrintingPolicy()); Diag(DtorLoc, diag::note_delete_non_virtual) << FixItHint::CreateInsertion(DtorLoc, TypeStr + "::"); } } Sema::ConditionResult Sema::ActOnConditionVariable(Decl *ConditionVar, SourceLocation StmtLoc, ConditionKind CK) { ExprResult E = CheckConditionVariable(cast(ConditionVar), StmtLoc, CK); if (E.isInvalid()) return ConditionError(); return ConditionResult(*this, ConditionVar, MakeFullExpr(E.get(), StmtLoc), CK == ConditionKind::ConstexprIf); } /// Check the use of the given variable as a C++ condition in an if, /// while, do-while, or switch statement. ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, SourceLocation StmtLoc, ConditionKind CK) { if (ConditionVar->isInvalidDecl()) return ExprError(); QualType T = ConditionVar->getType(); // C++ [stmt.select]p2: // The declarator shall not specify a function or an array. if (T->isFunctionType()) return ExprError(Diag(ConditionVar->getLocation(), diag::err_invalid_use_of_function_type) << ConditionVar->getSourceRange()); else if (T->isArrayType()) return ExprError(Diag(ConditionVar->getLocation(), diag::err_invalid_use_of_array_type) << ConditionVar->getSourceRange()); ExprResult Condition = BuildDeclRefExpr( ConditionVar, ConditionVar->getType().getNonReferenceType(), VK_LValue, ConditionVar->getLocation()); switch (CK) { case ConditionKind::Boolean: return CheckBooleanCondition(StmtLoc, Condition.get()); case ConditionKind::ConstexprIf: return CheckBooleanCondition(StmtLoc, Condition.get(), true); case ConditionKind::Switch: return CheckSwitchCondition(StmtLoc, Condition.get()); } llvm_unreachable("unexpected condition kind"); } /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid. ExprResult Sema::CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr) { // C++ 6.4p4: // The value of a condition that is an initialized declaration in a statement // other than a switch statement is the value of the declared variable // implicitly converted to type bool. If that conversion is ill-formed, the // program is ill-formed. // The value of a condition that is an expression is the value of the // expression, implicitly converted to bool. // // FIXME: Return this value to the caller so they don't need to recompute it. llvm::APSInt Value(/*BitWidth*/1); return (IsConstexpr && !CondExpr->isValueDependent()) ? CheckConvertedConstantExpression(CondExpr, Context.BoolTy, Value, CCEK_ConstexprIf) : PerformContextuallyConvertToBool(CondExpr); } /// Helper function to determine whether this is the (deprecated) C++ /// conversion from a string literal to a pointer to non-const char or /// non-const wchar_t (for narrow and wide string literals, /// respectively). bool Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) { // Look inside the implicit cast, if it exists. if (ImplicitCastExpr *Cast = dyn_cast(From)) From = Cast->getSubExpr(); // A string literal (2.13.4) that is not a wide string literal can // be converted to an rvalue of type "pointer to char"; a wide // string literal can be converted to an rvalue of type "pointer // to wchar_t" (C++ 4.2p2). if (StringLiteral *StrLit = dyn_cast(From->IgnoreParens())) if (const PointerType *ToPtrType = ToType->getAs()) if (const BuiltinType *ToPointeeType = ToPtrType->getPointeeType()->getAs()) { // This conversion is considered only when there is an // explicit appropriate pointer target type (C++ 4.2p2). if (!ToPtrType->getPointeeType().hasQualifiers()) { switch (StrLit->getKind()) { case StringLiteral::UTF8: case StringLiteral::UTF16: case StringLiteral::UTF32: // We don't allow UTF literals to be implicitly converted break; case StringLiteral::Ascii: return (ToPointeeType->getKind() == BuiltinType::Char_U || ToPointeeType->getKind() == BuiltinType::Char_S); case StringLiteral::Wide: return Context.typesAreCompatible(Context.getWideCharType(), QualType(ToPointeeType, 0)); } } } return false; } static ExprResult BuildCXXCastArgument(Sema &S, SourceLocation CastLoc, QualType Ty, CastKind Kind, CXXMethodDecl *Method, DeclAccessPair FoundDecl, bool HadMultipleCandidates, Expr *From) { switch (Kind) { default: llvm_unreachable("Unhandled cast kind!"); case CK_ConstructorConversion: { CXXConstructorDecl *Constructor = cast(Method); SmallVector ConstructorArgs; if (S.RequireNonAbstractType(CastLoc, Ty, diag::err_allocation_of_abstract_type)) return ExprError(); if (S.CompleteConstructorCall(Constructor, From, CastLoc, ConstructorArgs)) return ExprError(); S.CheckConstructorAccess(CastLoc, Constructor, FoundDecl, InitializedEntity::InitializeTemporary(Ty)); if (S.DiagnoseUseOfDecl(Method, CastLoc)) return ExprError(); ExprResult Result = S.BuildCXXConstructExpr( CastLoc, Ty, FoundDecl, cast(Method), ConstructorArgs, HadMultipleCandidates, /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, SourceRange()); if (Result.isInvalid()) return ExprError(); return S.MaybeBindToTemporary(Result.getAs()); } case CK_UserDefinedConversion: { assert(!From->getType()->isPointerType() && "Arg can't have pointer type!"); S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl); if (S.DiagnoseUseOfDecl(Method, CastLoc)) return ExprError(); // Create an implicit call expr that calls it. CXXConversionDecl *Conv = cast(Method); ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Conv, HadMultipleCandidates); if (Result.isInvalid()) return ExprError(); // Record usage of conversion in an implicit cast. Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(), CK_UserDefinedConversion, Result.get(), nullptr, Result.get()->getValueKind()); return S.MaybeBindToTemporary(Result.get()); } } } /// PerformImplicitConversion - Perform an implicit conversion of the /// expression From to the type ToType using the pre-computed implicit /// conversion sequence ICS. Returns the converted /// expression. Action is the kind of conversion we're performing, /// used in the error message. ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK) { // C++ [over.match.oper]p7: [...] operands of class type are converted [...] if (CCK == CCK_ForBuiltinOverloadedOp && !From->getType()->isRecordType()) return From; switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: { ExprResult Res = PerformImplicitConversion(From, ToType, ICS.Standard, Action, CCK); if (Res.isInvalid()) return ExprError(); From = Res.get(); break; } case ImplicitConversionSequence::UserDefinedConversion: { FunctionDecl *FD = ICS.UserDefined.ConversionFunction; CastKind CastKind; QualType BeforeToType; assert(FD && "no conversion function for user-defined conversion seq"); if (const CXXConversionDecl *Conv = dyn_cast(FD)) { CastKind = CK_UserDefinedConversion; // If the user-defined conversion is specified by a conversion function, // the initial standard conversion sequence converts the source type to // the implicit object parameter of the conversion function. BeforeToType = Context.getTagDeclType(Conv->getParent()); } else { const CXXConstructorDecl *Ctor = cast(FD); CastKind = CK_ConstructorConversion; // Do no conversion if dealing with ... for the first conversion. if (!ICS.UserDefined.EllipsisConversion) { // If the user-defined conversion is specified by a constructor, the // initial standard conversion sequence converts the source type to // the type required by the argument of the constructor BeforeToType = Ctor->getParamDecl(0)->getType().getNonReferenceType(); } } // Watch out for ellipsis conversion. if (!ICS.UserDefined.EllipsisConversion) { ExprResult Res = PerformImplicitConversion(From, BeforeToType, ICS.UserDefined.Before, AA_Converting, CCK); if (Res.isInvalid()) return ExprError(); From = Res.get(); } ExprResult CastArg = BuildCXXCastArgument( *this, From->getBeginLoc(), ToType.getNonReferenceType(), CastKind, cast(FD), ICS.UserDefined.FoundConversionFunction, ICS.UserDefined.HadMultipleCandidates, From); if (CastArg.isInvalid()) return ExprError(); From = CastArg.get(); // C++ [over.match.oper]p7: // [...] the second standard conversion sequence of a user-defined // conversion sequence is not applied. if (CCK == CCK_ForBuiltinOverloadedOp) return From; return PerformImplicitConversion(From, ToType, ICS.UserDefined.After, AA_Converting, CCK); } case ImplicitConversionSequence::AmbiguousConversion: ICS.DiagnoseAmbiguousConversion(*this, From->getExprLoc(), PDiag(diag::err_typecheck_ambiguous_condition) << From->getSourceRange()); return ExprError(); case ImplicitConversionSequence::EllipsisConversion: llvm_unreachable("Cannot perform an ellipsis conversion"); case ImplicitConversionSequence::BadConversion: bool Diagnosed = DiagnoseAssignmentResult(Incompatible, From->getExprLoc(), ToType, From->getType(), From, Action); assert(Diagnosed && "failed to diagnose bad conversion"); (void)Diagnosed; return ExprError(); } // Everything went well. return From; } /// PerformImplicitConversion - Perform an implicit conversion of the /// expression From to the type ToType by following the standard /// conversion sequence SCS. Returns the converted /// expression. Flavor is the context in which we're performing this /// conversion, for use in error messages. ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, const StandardConversionSequence& SCS, AssignmentAction Action, CheckedConversionKind CCK) { bool CStyle = (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast); // Overall FIXME: we are recomputing too many types here and doing far too // much extra work. What this means is that we need to keep track of more // information that is computed when we try the implicit conversion initially, // so that we don't need to recompute anything here. QualType FromType = From->getType(); if (SCS.CopyConstructor) { // FIXME: When can ToType be a reference type? assert(!ToType->isReferenceType()); if (SCS.Second == ICK_Derived_To_Base) { SmallVector ConstructorArgs; if (CompleteConstructorCall(cast(SCS.CopyConstructor), From, /*FIXME:ConstructLoc*/SourceLocation(), ConstructorArgs)) return ExprError(); return BuildCXXConstructExpr( /*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.FoundCopyConstructor, SCS.CopyConstructor, ConstructorArgs, /*HadMultipleCandidates*/ false, /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, SourceRange()); } return BuildCXXConstructExpr( /*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.FoundCopyConstructor, SCS.CopyConstructor, From, /*HadMultipleCandidates*/ false, /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, SourceRange()); } // Resolve overloaded function references. if (Context.hasSameType(FromType, Context.OverloadTy)) { DeclAccessPair Found; FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType, true, Found); if (!Fn) return ExprError(); if (DiagnoseUseOfDecl(Fn, From->getBeginLoc())) return ExprError(); From = FixOverloadedFunctionReference(From, Found, Fn); FromType = From->getType(); } // If we're converting to an atomic type, first convert to the corresponding // non-atomic type. QualType ToAtomicType; if (const AtomicType *ToAtomic = ToType->getAs()) { ToAtomicType = ToType; ToType = ToAtomic->getValueType(); } QualType InitialFromType = FromType; // Perform the first implicit conversion. switch (SCS.First) { case ICK_Identity: if (const AtomicType *FromAtomic = FromType->getAs()) { FromType = FromAtomic->getValueType().getUnqualifiedType(); From = ImplicitCastExpr::Create(Context, FromType, CK_AtomicToNonAtomic, From, /*BasePath=*/nullptr, VK_RValue); } break; case ICK_Lvalue_To_Rvalue: { assert(From->getObjectKind() != OK_ObjCProperty); ExprResult FromRes = DefaultLvalueConversion(From); assert(!FromRes.isInvalid() && "Can't perform deduced conversion?!"); From = FromRes.get(); FromType = From->getType(); break; } case ICK_Array_To_Pointer: FromType = Context.getArrayDecayedType(FromType); From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Function_To_Pointer: FromType = Context.getPointerType(FromType); From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; default: llvm_unreachable("Improper first standard conversion"); } // Perform the second implicit conversion switch (SCS.Second) { case ICK_Identity: // C++ [except.spec]p5: // [For] assignment to and initialization of pointers to functions, // pointers to member functions, and references to functions: the // target entity shall allow at least the exceptions allowed by the // source value in the assignment or initialization. switch (Action) { case AA_Assigning: case AA_Initializing: // Note, function argument passing and returning are initialization. case AA_Passing: case AA_Returning: case AA_Sending: case AA_Passing_CFAudited: if (CheckExceptionSpecCompatibility(From, ToType)) return ExprError(); break; case AA_Casting: case AA_Converting: // Casts and implicit conversions are not initialization, so are not // checked for exception specification mismatches. break; } // Nothing else to do. break; case ICK_Integral_Promotion: case ICK_Integral_Conversion: if (ToType->isBooleanType()) { assert(FromType->castAs()->getDecl()->isFixed() && SCS.Second == ICK_Integral_Promotion && "only enums with fixed underlying type can promote to bool"); From = ImpCastExprToType(From, ToType, CK_IntegralToBoolean, VK_RValue, /*BasePath=*/nullptr, CCK).get(); } else { From = ImpCastExprToType(From, ToType, CK_IntegralCast, VK_RValue, /*BasePath=*/nullptr, CCK).get(); } break; case ICK_Floating_Promotion: case ICK_Floating_Conversion: From = ImpCastExprToType(From, ToType, CK_FloatingCast, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Complex_Promotion: case ICK_Complex_Conversion: { QualType FromEl = From->getType()->castAs()->getElementType(); QualType ToEl = ToType->castAs()->getElementType(); CastKind CK; if (FromEl->isRealFloatingType()) { if (ToEl->isRealFloatingType()) CK = CK_FloatingComplexCast; else CK = CK_FloatingComplexToIntegralComplex; } else if (ToEl->isRealFloatingType()) { CK = CK_IntegralComplexToFloatingComplex; } else { CK = CK_IntegralComplexCast; } From = ImpCastExprToType(From, ToType, CK, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; } case ICK_Floating_Integral: if (ToType->isRealFloatingType()) From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_RValue, /*BasePath=*/nullptr, CCK).get(); else From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Compatible_Conversion: - From = ImpCastExprToType(From, ToType, CK_NoOp, - VK_RValue, /*BasePath=*/nullptr, CCK).get(); + From = ImpCastExprToType(From, ToType, CK_NoOp, From->getValueKind(), + /*BasePath=*/nullptr, CCK).get(); break; case ICK_Writeback_Conversion: case ICK_Pointer_Conversion: { if (SCS.IncompatibleObjC && Action != AA_Casting) { // Diagnose incompatible Objective-C conversions if (Action == AA_Initializing || Action == AA_Assigning) Diag(From->getBeginLoc(), diag::ext_typecheck_convert_incompatible_pointer) << ToType << From->getType() << Action << From->getSourceRange() << 0; else Diag(From->getBeginLoc(), diag::ext_typecheck_convert_incompatible_pointer) << From->getType() << ToType << Action << From->getSourceRange() << 0; if (From->getType()->isObjCObjectPointerType() && ToType->isObjCObjectPointerType()) EmitRelatedResultTypeNote(From); } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && !CheckObjCARCUnavailableWeakConversion(ToType, From->getType())) { if (Action == AA_Initializing) Diag(From->getBeginLoc(), diag::err_arc_weak_unavailable_assign); else Diag(From->getBeginLoc(), diag::err_arc_convesion_of_weak_unavailable) << (Action == AA_Casting) << From->getType() << ToType << From->getSourceRange(); } // Defer address space conversion to the third conversion. QualType FromPteeType = From->getType()->getPointeeType(); QualType ToPteeType = ToType->getPointeeType(); QualType NewToType = ToType; if (!FromPteeType.isNull() && !ToPteeType.isNull() && FromPteeType.getAddressSpace() != ToPteeType.getAddressSpace()) { NewToType = Context.removeAddrSpaceQualType(ToPteeType); NewToType = Context.getAddrSpaceQualType(NewToType, FromPteeType.getAddressSpace()); if (ToType->isObjCObjectPointerType()) NewToType = Context.getObjCObjectPointerType(NewToType); else if (ToType->isBlockPointerType()) NewToType = Context.getBlockPointerType(NewToType); else NewToType = Context.getPointerType(NewToType); } CastKind Kind; CXXCastPath BasePath; if (CheckPointerConversion(From, NewToType, Kind, BasePath, CStyle)) return ExprError(); // Make sure we extend blocks if necessary. // FIXME: doing this here is really ugly. if (Kind == CK_BlockPointerToObjCPointerCast) { ExprResult E = From; (void) PrepareCastToObjCObjectPointer(E); From = E.get(); } if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) CheckObjCConversion(SourceRange(), NewToType, From, CCK); From = ImpCastExprToType(From, NewToType, Kind, VK_RValue, &BasePath, CCK) .get(); break; } case ICK_Pointer_Member: { CastKind Kind; CXXCastPath BasePath; if (CheckMemberPointerConversion(From, ToType, Kind, BasePath, CStyle)) return ExprError(); if (CheckExceptionSpecCompatibility(From, ToType)) return ExprError(); // We may not have been able to figure out what this member pointer resolved // to up until this exact point. Attempt to lock-in it's inheritance model. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { (void)isCompleteType(From->getExprLoc(), From->getType()); (void)isCompleteType(From->getExprLoc(), ToType); } From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK) .get(); break; } case ICK_Boolean_Conversion: // Perform half-to-boolean conversion via float. if (From->getType()->isHalfType()) { From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).get(); FromType = Context.FloatTy; } From = ImpCastExprToType(From, Context.BoolTy, ScalarTypeToBooleanCastKind(FromType), VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Derived_To_Base: { CXXCastPath BasePath; if (CheckDerivedToBaseConversion( From->getType(), ToType.getNonReferenceType(), From->getBeginLoc(), From->getSourceRange(), &BasePath, CStyle)) return ExprError(); From = ImpCastExprToType(From, ToType.getNonReferenceType(), CK_DerivedToBase, From->getValueKind(), &BasePath, CCK).get(); break; } case ICK_Vector_Conversion: From = ImpCastExprToType(From, ToType, CK_BitCast, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Vector_Splat: { // Vector splat from any arithmetic type to a vector. Expr *Elem = prepareVectorSplat(ToType, From).get(); From = ImpCastExprToType(Elem, ToType, CK_VectorSplat, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; } case ICK_Complex_Real: // Case 1. x -> _Complex y if (const ComplexType *ToComplex = ToType->getAs()) { QualType ElType = ToComplex->getElementType(); bool isFloatingComplex = ElType->isRealFloatingType(); // x -> y if (Context.hasSameUnqualifiedType(ElType, From->getType())) { // do nothing } else if (From->getType()->isRealFloatingType()) { From = ImpCastExprToType(From, ElType, isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).get(); } else { assert(From->getType()->isIntegerType()); From = ImpCastExprToType(From, ElType, isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).get(); } // y -> _Complex y From = ImpCastExprToType(From, ToType, isFloatingComplex ? CK_FloatingRealToComplex : CK_IntegralRealToComplex).get(); // Case 2. _Complex x -> y } else { const ComplexType *FromComplex = From->getType()->getAs(); assert(FromComplex); QualType ElType = FromComplex->getElementType(); bool isFloatingComplex = ElType->isRealFloatingType(); // _Complex x -> x From = ImpCastExprToType(From, ElType, isFloatingComplex ? CK_FloatingComplexToReal : CK_IntegralComplexToReal, VK_RValue, /*BasePath=*/nullptr, CCK).get(); // x -> y if (Context.hasSameUnqualifiedType(ElType, ToType)) { // do nothing } else if (ToType->isRealFloatingType()) { From = ImpCastExprToType(From, ToType, isFloatingComplex ? CK_FloatingCast : CK_IntegralToFloating, VK_RValue, /*BasePath=*/nullptr, CCK).get(); } else { assert(ToType->isIntegerType()); From = ImpCastExprToType(From, ToType, isFloatingComplex ? CK_FloatingToIntegral : CK_IntegralCast, VK_RValue, /*BasePath=*/nullptr, CCK).get(); } } break; case ICK_Block_Pointer_Conversion: { LangAS AddrSpaceL = ToType->castAs()->getPointeeType().getAddressSpace(); LangAS AddrSpaceR = FromType->castAs()->getPointeeType().getAddressSpace(); assert(Qualifiers::isAddressSpaceSupersetOf(AddrSpaceL, AddrSpaceR) && "Invalid cast"); CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast; From = ImpCastExprToType(From, ToType.getUnqualifiedType(), Kind, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; } case ICK_TransparentUnionConversion: { ExprResult FromRes = From; Sema::AssignConvertType ConvTy = CheckTransparentUnionArgumentConstraints(ToType, FromRes); if (FromRes.isInvalid()) return ExprError(); From = FromRes.get(); assert ((ConvTy == Sema::Compatible) && "Improper transparent union conversion"); (void)ConvTy; break; } case ICK_Zero_Event_Conversion: case ICK_Zero_Queue_Conversion: From = ImpCastExprToType(From, ToType, CK_ZeroToOCLOpaqueType, From->getValueKind()).get(); break; case ICK_Lvalue_To_Rvalue: case ICK_Array_To_Pointer: case ICK_Function_To_Pointer: case ICK_Function_Conversion: case ICK_Qualification: case ICK_Num_Conversion_Kinds: case ICK_C_Only_Conversion: case ICK_Incompatible_Pointer_Conversion: llvm_unreachable("Improper second standard conversion"); } switch (SCS.Third) { case ICK_Identity: // Nothing to do. break; case ICK_Function_Conversion: // If both sides are functions (or pointers/references to them), there could // be incompatible exception declarations. if (CheckExceptionSpecCompatibility(From, ToType)) return ExprError(); From = ImpCastExprToType(From, ToType, CK_NoOp, VK_RValue, /*BasePath=*/nullptr, CCK).get(); break; case ICK_Qualification: { - // The qualification keeps the category of the inner expression, unless the - // target type isn't a reference. - ExprValueKind VK = - ToType->isReferenceType() ? From->getValueKind() : VK_RValue; - + ExprValueKind VK = From->getValueKind(); CastKind CK = CK_NoOp; if (ToType->isReferenceType() && ToType->getPointeeType().getAddressSpace() != From->getType().getAddressSpace()) CK = CK_AddressSpaceConversion; if (ToType->isPointerType() && ToType->getPointeeType().getAddressSpace() != From->getType()->getPointeeType().getAddressSpace()) CK = CK_AddressSpaceConversion; From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context), CK, VK, /*BasePath=*/nullptr, CCK) .get(); if (SCS.DeprecatedStringLiteralToCharPtr && !getLangOpts().WritableStrings) { Diag(From->getBeginLoc(), getLangOpts().CPlusPlus11 ? diag::ext_deprecated_string_literal_conversion : diag::warn_deprecated_string_literal_conversion) << ToType.getNonReferenceType(); } break; } default: llvm_unreachable("Improper third standard conversion"); } // If this conversion sequence involved a scalar -> atomic conversion, perform // that conversion now. if (!ToAtomicType.isNull()) { assert(Context.hasSameType( ToAtomicType->castAs()->getValueType(), From->getType())); From = ImpCastExprToType(From, ToAtomicType, CK_NonAtomicToAtomic, VK_RValue, nullptr, CCK).get(); } // If this conversion sequence succeeded and involved implicitly converting a // _Nullable type to a _Nonnull one, complain. if (!isCast(CCK)) diagnoseNullableToNonnullConversion(ToType, InitialFromType, From->getBeginLoc()); return From; } /// Check the completeness of a type in a unary type trait. /// /// If the particular type trait requires a complete type, tries to complete /// it. If completing the type fails, a diagnostic is emitted and false /// returned. If completing the type succeeds or no completion was required, /// returns true. static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, SourceLocation Loc, QualType ArgTy) { // C++0x [meta.unary.prop]p3: // For all of the class templates X declared in this Clause, instantiating // that template with a template argument that is a class template // specialization may result in the implicit instantiation of the template // argument if and only if the semantics of X require that the argument // must be a complete type. // We apply this rule to all the type trait expressions used to implement // these class templates. We also try to follow any GCC documented behavior // in these expressions to ensure portability of standard libraries. switch (UTT) { default: llvm_unreachable("not a UTT"); // is_complete_type somewhat obviously cannot require a complete type. case UTT_IsCompleteType: // Fall-through // These traits are modeled on the type predicates in C++0x // [meta.unary.cat] and [meta.unary.comp]. They are not specified as // requiring a complete type, as whether or not they return true cannot be // impacted by the completeness of the type. case UTT_IsVoid: case UTT_IsIntegral: case UTT_IsFloatingPoint: case UTT_IsArray: case UTT_IsPointer: case UTT_IsLvalueReference: case UTT_IsRvalueReference: case UTT_IsMemberFunctionPointer: case UTT_IsMemberObjectPointer: case UTT_IsEnum: case UTT_IsUnion: case UTT_IsClass: case UTT_IsFunction: case UTT_IsReference: case UTT_IsArithmetic: case UTT_IsFundamental: case UTT_IsObject: case UTT_IsScalar: case UTT_IsCompound: case UTT_IsMemberPointer: // Fall-through // These traits are modeled on type predicates in C++0x [meta.unary.prop] // which requires some of its traits to have the complete type. However, // the completeness of the type cannot impact these traits' semantics, and // so they don't require it. This matches the comments on these traits in // Table 49. case UTT_IsConst: case UTT_IsVolatile: case UTT_IsSigned: case UTT_IsUnsigned: // This type trait always returns false, checking the type is moot. case UTT_IsInterfaceClass: return true; // C++14 [meta.unary.prop]: // If T is a non-union class type, T shall be a complete type. case UTT_IsEmpty: case UTT_IsPolymorphic: case UTT_IsAbstract: if (const auto *RD = ArgTy->getAsCXXRecordDecl()) if (!RD->isUnion()) return !S.RequireCompleteType( Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr); return true; // C++14 [meta.unary.prop]: // If T is a class type, T shall be a complete type. case UTT_IsFinal: case UTT_IsSealed: if (ArgTy->getAsCXXRecordDecl()) return !S.RequireCompleteType( Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr); return true; // C++1z [meta.unary.prop]: // remove_all_extents_t shall be a complete type or cv void. case UTT_IsAggregate: case UTT_IsTrivial: case UTT_IsTriviallyCopyable: case UTT_IsStandardLayout: case UTT_IsPOD: case UTT_IsLiteral: // Per the GCC type traits documentation, T shall be a complete type, cv void, // or an array of unknown bound. But GCC actually imposes the same constraints // as above. case UTT_HasNothrowAssign: case UTT_HasNothrowMoveAssign: case UTT_HasNothrowConstructor: case UTT_HasNothrowCopy: case UTT_HasTrivialAssign: case UTT_HasTrivialMoveAssign: case UTT_HasTrivialDefaultConstructor: case UTT_HasTrivialMoveConstructor: case UTT_HasTrivialCopy: case UTT_HasTrivialDestructor: case UTT_HasVirtualDestructor: ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0); LLVM_FALLTHROUGH; // C++1z [meta.unary.prop]: // T shall be a complete type, cv void, or an array of unknown bound. case UTT_IsDestructible: case UTT_IsNothrowDestructible: case UTT_IsTriviallyDestructible: case UTT_HasUniqueObjectRepresentations: if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType()) return true; return !S.RequireCompleteType( Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr); } } static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op, Sema &Self, SourceLocation KeyLoc, ASTContext &C, bool (CXXRecordDecl::*HasTrivial)() const, bool (CXXRecordDecl::*HasNonTrivial)() const, bool (CXXMethodDecl::*IsDesiredOp)() const) { CXXRecordDecl *RD = cast(RT->getDecl()); if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)()) return true; DeclarationName Name = C.DeclarationNames.getCXXOperatorName(Op); DeclarationNameInfo NameInfo(Name, KeyLoc); LookupResult Res(Self, NameInfo, Sema::LookupOrdinaryName); if (Self.LookupQualifiedName(Res, RD)) { bool FoundOperator = false; Res.suppressDiagnostics(); for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end(); Op != OpEnd; ++Op) { if (isa(*Op)) continue; CXXMethodDecl *Operator = cast(*Op); if((Operator->*IsDesiredOp)()) { FoundOperator = true; const FunctionProtoType *CPT = Operator->getType()->getAs(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); if (!CPT || !CPT->isNothrow()) return false; } } return FoundOperator; } return false; } static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, SourceLocation KeyLoc, QualType T) { assert(!T->isDependentType() && "Cannot evaluate traits of dependent type"); ASTContext &C = Self.Context; switch(UTT) { default: llvm_unreachable("not a UTT"); // Type trait expressions corresponding to the primary type category // predicates in C++0x [meta.unary.cat]. case UTT_IsVoid: return T->isVoidType(); case UTT_IsIntegral: return T->isIntegralType(C); case UTT_IsFloatingPoint: return T->isFloatingType(); case UTT_IsArray: return T->isArrayType(); case UTT_IsPointer: return T->isPointerType(); case UTT_IsLvalueReference: return T->isLValueReferenceType(); case UTT_IsRvalueReference: return T->isRValueReferenceType(); case UTT_IsMemberFunctionPointer: return T->isMemberFunctionPointerType(); case UTT_IsMemberObjectPointer: return T->isMemberDataPointerType(); case UTT_IsEnum: return T->isEnumeralType(); case UTT_IsUnion: return T->isUnionType(); case UTT_IsClass: return T->isClassType() || T->isStructureType() || T->isInterfaceType(); case UTT_IsFunction: return T->isFunctionType(); // Type trait expressions which correspond to the convenient composition // predicates in C++0x [meta.unary.comp]. case UTT_IsReference: return T->isReferenceType(); case UTT_IsArithmetic: return T->isArithmeticType() && !T->isEnumeralType(); case UTT_IsFundamental: return T->isFundamentalType(); case UTT_IsObject: return T->isObjectType(); case UTT_IsScalar: // Note: semantic analysis depends on Objective-C lifetime types to be // considered scalar types. However, such types do not actually behave // like scalar types at run time (since they may require retain/release // operations), so we report them as non-scalar. if (T->isObjCLifetimeType()) { switch (T.getObjCLifetime()) { case Qualifiers::OCL_None: case Qualifiers::OCL_ExplicitNone: return true; case Qualifiers::OCL_Strong: case Qualifiers::OCL_Weak: case Qualifiers::OCL_Autoreleasing: return false; } } return T->isScalarType(); case UTT_IsCompound: return T->isCompoundType(); case UTT_IsMemberPointer: return T->isMemberPointerType(); // Type trait expressions which correspond to the type property predicates // in C++0x [meta.unary.prop]. case UTT_IsConst: return T.isConstQualified(); case UTT_IsVolatile: return T.isVolatileQualified(); case UTT_IsTrivial: return T.isTrivialType(C); case UTT_IsTriviallyCopyable: return T.isTriviallyCopyableType(C); case UTT_IsStandardLayout: return T->isStandardLayoutType(); case UTT_IsPOD: return T.isPODType(C); case UTT_IsLiteral: return T->isLiteralType(C); case UTT_IsEmpty: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return !RD->isUnion() && RD->isEmpty(); return false; case UTT_IsPolymorphic: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return !RD->isUnion() && RD->isPolymorphic(); return false; case UTT_IsAbstract: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return !RD->isUnion() && RD->isAbstract(); return false; case UTT_IsAggregate: // Report vector extensions and complex types as aggregates because they // support aggregate initialization. GCC mirrors this behavior for vectors // but not _Complex. return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() || T->isAnyComplexType(); // __is_interface_class only returns true when CL is invoked in /CLR mode and // even then only when it is used with the 'interface struct ...' syntax // Clang doesn't support /CLR which makes this type trait moot. case UTT_IsInterfaceClass: return false; case UTT_IsFinal: case UTT_IsSealed: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return RD->hasAttr(); return false; case UTT_IsSigned: // Enum types should always return false. // Floating points should always return true. return !T->isEnumeralType() && (T->isFloatingType() || T->isSignedIntegerType()); case UTT_IsUnsigned: return T->isUnsignedIntegerType(); // Type trait expressions which query classes regarding their construction, // destruction, and copying. Rather than being based directly on the // related type predicates in the standard, they are specified by both // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those // specifications. // // 1: http://gcc.gnu/.org/onlinedocs/gcc/Type-Traits.html // 2: http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index // // Note that these builtins do not behave as documented in g++: if a class // has both a trivial and a non-trivial special member of a particular kind, // they return false! For now, we emulate this behavior. // FIXME: This appears to be a g++ bug: more complex cases reveal that it // does not correctly compute triviality in the presence of multiple special // members of the same kind. Revisit this once the g++ bug is fixed. case UTT_HasTrivialDefaultConstructor: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If __is_pod (type) is true then the trait is true, else if type is // a cv class or union type (or array thereof) with a trivial default // constructor ([class.ctor]) then the trait is true, else it is false. if (T.isPODType(C)) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) return RD->hasTrivialDefaultConstructor() && !RD->hasNonTrivialDefaultConstructor(); return false; case UTT_HasTrivialMoveConstructor: // This trait is implemented by MSVC 2012 and needed to parse the // standard library headers. Specifically this is used as the logic // behind std::is_trivially_move_constructible (20.9.4.3). if (T.isPODType(C)) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) return RD->hasTrivialMoveConstructor() && !RD->hasNonTrivialMoveConstructor(); return false; case UTT_HasTrivialCopy: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If __is_pod (type) is true or type is a reference type then // the trait is true, else if type is a cv class or union type // with a trivial copy constructor ([class.copy]) then the trait // is true, else it is false. if (T.isPODType(C) || T->isReferenceType()) return true; if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return RD->hasTrivialCopyConstructor() && !RD->hasNonTrivialCopyConstructor(); return false; case UTT_HasTrivialMoveAssign: // This trait is implemented by MSVC 2012 and needed to parse the // standard library headers. Specifically it is used as the logic // behind std::is_trivially_move_assignable (20.9.4.3) if (T.isPODType(C)) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) return RD->hasTrivialMoveAssignment() && !RD->hasNonTrivialMoveAssignment(); return false; case UTT_HasTrivialAssign: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If type is const qualified or is a reference type then the // trait is false. Otherwise if __is_pod (type) is true then the // trait is true, else if type is a cv class or union type with // a trivial copy assignment ([class.copy]) then the trait is // true, else it is false. // Note: the const and reference restrictions are interesting, // given that const and reference members don't prevent a class // from having a trivial copy assignment operator (but do cause // errors if the copy assignment operator is actually used, q.v. // [class.copy]p12). if (T.isConstQualified()) return false; if (T.isPODType(C)) return true; if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return RD->hasTrivialCopyAssignment() && !RD->hasNonTrivialCopyAssignment(); return false; case UTT_IsDestructible: case UTT_IsTriviallyDestructible: case UTT_IsNothrowDestructible: // C++14 [meta.unary.prop]: // For reference types, is_destructible::value is true. if (T->isReferenceType()) return true; // Objective-C++ ARC: autorelease types don't require destruction. if (T->isObjCLifetimeType() && T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) return true; // C++14 [meta.unary.prop]: // For incomplete types and function types, is_destructible::value is // false. if (T->isIncompleteType() || T->isFunctionType()) return false; // A type that requires destruction (via a non-trivial destructor or ARC // lifetime semantics) is not trivially-destructible. if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType()) return false; // C++14 [meta.unary.prop]: // For object types and given U equal to remove_all_extents_t, if the // expression std::declval().~U() is well-formed when treated as an // unevaluated operand (Clause 5), then is_destructible::value is true if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) { CXXDestructorDecl *Destructor = Self.LookupDestructor(RD); if (!Destructor) return false; // C++14 [dcl.fct.def.delete]p2: // A program that refers to a deleted function implicitly or // explicitly, other than to declare it, is ill-formed. if (Destructor->isDeleted()) return false; if (C.getLangOpts().AccessControl && Destructor->getAccess() != AS_public) return false; if (UTT == UTT_IsNothrowDestructible) { const FunctionProtoType *CPT = Destructor->getType()->getAs(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); if (!CPT || !CPT->isNothrow()) return false; } } return true; case UTT_HasTrivialDestructor: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html // If __is_pod (type) is true or type is a reference type // then the trait is true, else if type is a cv class or union // type (or array thereof) with a trivial destructor // ([class.dtor]) then the trait is true, else it is // false. if (T.isPODType(C) || T->isReferenceType()) return true; // Objective-C++ ARC: autorelease types don't require destruction. if (T->isObjCLifetimeType() && T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) return RD->hasTrivialDestructor(); return false; // TODO: Propagate nothrowness for implicitly declared special members. case UTT_HasNothrowAssign: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If type is const qualified or is a reference type then the // trait is false. Otherwise if __has_trivial_assign (type) // is true then the trait is true, else if type is a cv class // or union type with copy assignment operators that are known // not to throw an exception then the trait is true, else it is // false. if (C.getBaseElementType(T).isConstQualified()) return false; if (T->isReferenceType()) return false; if (T.isPODType(C) || T->isObjCLifetimeType()) return true; if (const RecordType *RT = T->getAs()) return HasNoThrowOperator(RT, OO_Equal, Self, KeyLoc, C, &CXXRecordDecl::hasTrivialCopyAssignment, &CXXRecordDecl::hasNonTrivialCopyAssignment, &CXXMethodDecl::isCopyAssignmentOperator); return false; case UTT_HasNothrowMoveAssign: // This trait is implemented by MSVC 2012 and needed to parse the // standard library headers. Specifically this is used as the logic // behind std::is_nothrow_move_assignable (20.9.4.3). if (T.isPODType(C)) return true; if (const RecordType *RT = C.getBaseElementType(T)->getAs()) return HasNoThrowOperator(RT, OO_Equal, Self, KeyLoc, C, &CXXRecordDecl::hasTrivialMoveAssignment, &CXXRecordDecl::hasNonTrivialMoveAssignment, &CXXMethodDecl::isMoveAssignmentOperator); return false; case UTT_HasNothrowCopy: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If __has_trivial_copy (type) is true then the trait is true, else // if type is a cv class or union type with copy constructors that are // known not to throw an exception then the trait is true, else it is // false. if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType()) return true; if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) { if (RD->hasTrivialCopyConstructor() && !RD->hasNonTrivialCopyConstructor()) return true; bool FoundConstructor = false; unsigned FoundTQs; for (const auto *ND : Self.LookupConstructors(RD)) { // A template constructor is never a copy constructor. // FIXME: However, it may actually be selected at the actual overload // resolution point. if (isa(ND->getUnderlyingDecl())) continue; // UsingDecl itself is not a constructor if (isa(ND)) continue; auto *Constructor = cast(ND->getUnderlyingDecl()); if (Constructor->isCopyConstructor(FoundTQs)) { FoundConstructor = true; const FunctionProtoType *CPT = Constructor->getType()->getAs(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); if (!CPT) return false; // TODO: check whether evaluating default arguments can throw. // For now, we'll be conservative and assume that they can throw. if (!CPT->isNothrow() || CPT->getNumParams() > 1) return false; } } return FoundConstructor; } return false; case UTT_HasNothrowConstructor: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html // If __has_trivial_constructor (type) is true then the trait is // true, else if type is a cv class or union type (or array // thereof) with a default constructor that is known not to // throw an exception then the trait is true, else it is false. if (T.isPODType(C) || T->isObjCLifetimeType()) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) { if (RD->hasTrivialDefaultConstructor() && !RD->hasNonTrivialDefaultConstructor()) return true; bool FoundConstructor = false; for (const auto *ND : Self.LookupConstructors(RD)) { // FIXME: In C++0x, a constructor template can be a default constructor. if (isa(ND->getUnderlyingDecl())) continue; // UsingDecl itself is not a constructor if (isa(ND)) continue; auto *Constructor = cast(ND->getUnderlyingDecl()); if (Constructor->isDefaultConstructor()) { FoundConstructor = true; const FunctionProtoType *CPT = Constructor->getType()->getAs(); CPT = Self.ResolveExceptionSpec(KeyLoc, CPT); if (!CPT) return false; // FIXME: check whether evaluating default arguments can throw. // For now, we'll be conservative and assume that they can throw. if (!CPT->isNothrow() || CPT->getNumParams() > 0) return false; } } return FoundConstructor; } return false; case UTT_HasVirtualDestructor: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: // If type is a class type with a virtual destructor ([class.dtor]) // then the trait is true, else it is false. if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD)) return Destructor->isVirtual(); return false; // These type trait expressions are modeled on the specifications for the // Embarcadero C++0x type trait functions: // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index case UTT_IsCompleteType: // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_): // Returns True if and only if T is a complete type at the point of the // function call. return !T->isIncompleteType(); case UTT_HasUniqueObjectRepresentations: return C.hasUniqueObjectRepresentations(T); } } static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT, QualType RhsT, SourceLocation KeyLoc); static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef Args, SourceLocation RParenLoc) { if (Kind <= UTT_Last) return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]->getType()); // Evaluate BTT_ReferenceBindsToTemporary alongside the IsConstructible // traits to avoid duplication. if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary) return EvaluateBinaryTypeTrait(S, Kind, Args[0]->getType(), Args[1]->getType(), RParenLoc); switch (Kind) { case clang::BTT_ReferenceBindsToTemporary: case clang::TT_IsConstructible: case clang::TT_IsNothrowConstructible: case clang::TT_IsTriviallyConstructible: { // C++11 [meta.unary.prop]: // is_trivially_constructible is defined as: // // is_constructible::value is true and the variable // definition for is_constructible, as defined below, is known to call // no operation that is not trivial. // // The predicate condition for a template specialization // is_constructible shall be satisfied if and only if the // following variable definition would be well-formed for some invented // variable t: // // T t(create()...); assert(!Args.empty()); // Precondition: T and all types in the parameter pack Args shall be // complete types, (possibly cv-qualified) void, or arrays of // unknown bound. for (const auto *TSI : Args) { QualType ArgTy = TSI->getType(); if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType()) continue; if (S.RequireCompleteType(KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr)) return false; } // Make sure the first argument is not incomplete nor a function type. QualType T = Args[0]->getType(); if (T->isIncompleteType() || T->isFunctionType()) return false; // Make sure the first argument is not an abstract type. CXXRecordDecl *RD = T->getAsCXXRecordDecl(); if (RD && RD->isAbstract()) return false; SmallVector OpaqueArgExprs; SmallVector ArgExprs; ArgExprs.reserve(Args.size() - 1); for (unsigned I = 1, N = Args.size(); I != N; ++I) { QualType ArgTy = Args[I]->getType(); if (ArgTy->isObjectType() || ArgTy->isFunctionType()) ArgTy = S.Context.getRValueReferenceType(ArgTy); OpaqueArgExprs.push_back( OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(), ArgTy.getNonLValueExprType(S.Context), Expr::getValueKindForType(ArgTy))); } for (Expr &E : OpaqueArgExprs) ArgExprs.push_back(&E); // Perform the initialization in an unevaluated context within a SFINAE // trap at translation unit scope. EnterExpressionEvaluationContext Unevaluated( S, Sema::ExpressionEvaluationContext::Unevaluated); Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); InitializedEntity To(InitializedEntity::InitializeTemporary(Args[0])); InitializationKind InitKind(InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc)); InitializationSequence Init(S, To, InitKind, ArgExprs); if (Init.Failed()) return false; ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs); if (Result.isInvalid() || SFINAE.hasErrorOccurred()) return false; if (Kind == clang::TT_IsConstructible) return true; if (Kind == clang::BTT_ReferenceBindsToTemporary) { if (!T->isReferenceType()) return false; return !Init.isDirectReferenceBinding(); } if (Kind == clang::TT_IsNothrowConstructible) return S.canThrow(Result.get()) == CT_Cannot; if (Kind == clang::TT_IsTriviallyConstructible) { // Under Objective-C ARC and Weak, if the destination has non-trivial // Objective-C lifetime, this is a non-trivial construction. if (T.getNonReferenceType().hasNonTrivialObjCLifetime()) return false; // The initialization succeeded; now make sure there are no non-trivial // calls. return !Result.get()->hasNonTrivialCall(S.Context); } llvm_unreachable("unhandled type trait"); return false; } default: llvm_unreachable("not a TT"); } return false; } ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef Args, SourceLocation RParenLoc) { QualType ResultType = Context.getLogicalOperationType(); if (Kind <= UTT_Last && !CheckUnaryTypeTraitTypeCompleteness( *this, Kind, KWLoc, Args[0]->getType())) return ExprError(); bool Dependent = false; for (unsigned I = 0, N = Args.size(); I != N; ++I) { if (Args[I]->getType()->isDependentType()) { Dependent = true; break; } } bool Result = false; if (!Dependent) Result = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc); return TypeTraitExpr::Create(Context, ResultType, KWLoc, Kind, Args, RParenLoc, Result); } ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef Args, SourceLocation RParenLoc) { SmallVector ConvertedArgs; ConvertedArgs.reserve(Args.size()); for (unsigned I = 0, N = Args.size(); I != N; ++I) { TypeSourceInfo *TInfo; QualType T = GetTypeFromParser(Args[I], &TInfo); if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc); ConvertedArgs.push_back(TInfo); } return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc); } static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT, QualType RhsT, SourceLocation KeyLoc) { assert(!LhsT->isDependentType() && !RhsT->isDependentType() && "Cannot evaluate traits of dependent types"); switch(BTT) { case BTT_IsBaseOf: { // C++0x [meta.rel]p2 // Base is a base class of Derived without regard to cv-qualifiers or // Base and Derived are not unions and name the same class type without // regard to cv-qualifiers. const RecordType *lhsRecord = LhsT->getAs(); const RecordType *rhsRecord = RhsT->getAs(); if (!rhsRecord || !lhsRecord) { const ObjCObjectType *LHSObjTy = LhsT->getAs(); const ObjCObjectType *RHSObjTy = RhsT->getAs(); if (!LHSObjTy || !RHSObjTy) return false; ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface(); ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface(); if (!BaseInterface || !DerivedInterface) return false; if (Self.RequireCompleteType( KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr)) return false; return BaseInterface->isSuperClassOf(DerivedInterface); } assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT) == (lhsRecord == rhsRecord)); // Unions are never base classes, and never have base classes. // It doesn't matter if they are complete or not. See PR#41843 if (lhsRecord && lhsRecord->getDecl()->isUnion()) return false; if (rhsRecord && rhsRecord->getDecl()->isUnion()) return false; if (lhsRecord == rhsRecord) return true; // C++0x [meta.rel]p2: // If Base and Derived are class types and are different types // (ignoring possible cv-qualifiers) then Derived shall be a // complete type. if (Self.RequireCompleteType(KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr)) return false; return cast(rhsRecord->getDecl()) ->isDerivedFrom(cast(lhsRecord->getDecl())); } case BTT_IsSame: return Self.Context.hasSameType(LhsT, RhsT); case BTT_TypeCompatible: { // GCC ignores cv-qualifiers on arrays for this builtin. Qualifiers LhsQuals, RhsQuals; QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals); QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals); return Self.Context.typesAreCompatible(Lhs, Rhs); } case BTT_IsConvertible: case BTT_IsConvertibleTo: { // C++0x [meta.rel]p4: // Given the following function prototype: // // template // typename add_rvalue_reference::type create(); // // the predicate condition for a template specialization // is_convertible shall be satisfied if and only if // the return expression in the following code would be // well-formed, including any implicit conversions to the return // type of the function: // // To test() { // return create(); // } // // Access checking is performed as if in a context unrelated to To and // From. Only the validity of the immediate context of the expression // of the return-statement (including conversions to the return type) // is considered. // // We model the initialization as a copy-initialization of a temporary // of the appropriate type, which for this expression is identical to the // return statement (since NRVO doesn't apply). // Functions aren't allowed to return function or array types. if (RhsT->isFunctionType() || RhsT->isArrayType()) return false; // A return statement in a void function must have void type. if (RhsT->isVoidType()) return LhsT->isVoidType(); // A function definition requires a complete, non-abstract return type. if (!Self.isCompleteType(KeyLoc, RhsT) || Self.isAbstractType(KeyLoc, RhsT)) return false; // Compute the result of add_rvalue_reference. if (LhsT->isObjectType() || LhsT->isFunctionType()) LhsT = Self.Context.getRValueReferenceType(LhsT); // Build a fake source and destination for initialization. InitializedEntity To(InitializedEntity::InitializeTemporary(RhsT)); OpaqueValueExpr From(KeyLoc, LhsT.getNonLValueExprType(Self.Context), Expr::getValueKindForType(LhsT)); Expr *FromPtr = &From; InitializationKind Kind(InitializationKind::CreateCopy(KeyLoc, SourceLocation())); // Perform the initialization in an unevaluated context within a SFINAE // trap at translation unit scope. EnterExpressionEvaluationContext Unevaluated( Self, Sema::ExpressionEvaluationContext::Unevaluated); Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true); Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl()); InitializationSequence Init(Self, To, Kind, FromPtr); if (Init.Failed()) return false; ExprResult Result = Init.Perform(Self, To, Kind, FromPtr); return !Result.isInvalid() && !SFINAE.hasErrorOccurred(); } case BTT_IsAssignable: case BTT_IsNothrowAssignable: case BTT_IsTriviallyAssignable: { // C++11 [meta.unary.prop]p3: // is_trivially_assignable is defined as: // is_assignable::value is true and the assignment, as defined by // is_assignable, is known to call no operation that is not trivial // // is_assignable is defined as: // The expression declval() = declval() is well-formed when // treated as an unevaluated operand (Clause 5). // // For both, T and U shall be complete types, (possibly cv-qualified) // void, or arrays of unknown bound. if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() && Self.RequireCompleteType(KeyLoc, LhsT, diag::err_incomplete_type_used_in_type_trait_expr)) return false; if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() && Self.RequireCompleteType(KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr)) return false; // cv void is never assignable. if (LhsT->isVoidType() || RhsT->isVoidType()) return false; // Build expressions that emulate the effect of declval() and // declval(). if (LhsT->isObjectType() || LhsT->isFunctionType()) LhsT = Self.Context.getRValueReferenceType(LhsT); if (RhsT->isObjectType() || RhsT->isFunctionType()) RhsT = Self.Context.getRValueReferenceType(RhsT); OpaqueValueExpr Lhs(KeyLoc, LhsT.getNonLValueExprType(Self.Context), Expr::getValueKindForType(LhsT)); OpaqueValueExpr Rhs(KeyLoc, RhsT.getNonLValueExprType(Self.Context), Expr::getValueKindForType(RhsT)); // Attempt the assignment in an unevaluated context within a SFINAE // trap at translation unit scope. EnterExpressionEvaluationContext Unevaluated( Self, Sema::ExpressionEvaluationContext::Unevaluated); Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true); Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl()); ExprResult Result = Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs); if (Result.isInvalid()) return false; // Treat the assignment as unused for the purpose of -Wdeprecated-volatile. Self.CheckUnusedVolatileAssignment(Result.get()); if (SFINAE.hasErrorOccurred()) return false; if (BTT == BTT_IsAssignable) return true; if (BTT == BTT_IsNothrowAssignable) return Self.canThrow(Result.get()) == CT_Cannot; if (BTT == BTT_IsTriviallyAssignable) { // Under Objective-C ARC and Weak, if the destination has non-trivial // Objective-C lifetime, this is a non-trivial assignment. if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime()) return false; return !Result.get()->hasNonTrivialCall(Self.Context); } llvm_unreachable("unhandled type trait"); return false; } default: llvm_unreachable("not a BTT"); } llvm_unreachable("Unknown type trait or not implemented"); } ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, ParsedType Ty, Expr* DimExpr, SourceLocation RParen) { TypeSourceInfo *TSInfo; QualType T = GetTypeFromParser(Ty, &TSInfo); if (!TSInfo) TSInfo = Context.getTrivialTypeSourceInfo(T); return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen); } static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT, QualType T, Expr *DimExpr, SourceLocation KeyLoc) { assert(!T->isDependentType() && "Cannot evaluate traits of dependent type"); switch(ATT) { case ATT_ArrayRank: if (T->isArrayType()) { unsigned Dim = 0; while (const ArrayType *AT = Self.Context.getAsArrayType(T)) { ++Dim; T = AT->getElementType(); } return Dim; } return 0; case ATT_ArrayExtent: { llvm::APSInt Value; uint64_t Dim; if (Self.VerifyIntegerConstantExpression(DimExpr, &Value, diag::err_dimension_expr_not_constant_integer, false).isInvalid()) return 0; if (Value.isSigned() && Value.isNegative()) { Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer) << DimExpr->getSourceRange(); return 0; } Dim = Value.getLimitedValue(); if (T->isArrayType()) { unsigned D = 0; bool Matched = false; while (const ArrayType *AT = Self.Context.getAsArrayType(T)) { if (Dim == D) { Matched = true; break; } ++D; T = AT->getElementType(); } if (Matched && T->isArrayType()) { if (const ConstantArrayType *CAT = Self.Context.getAsConstantArrayType(T)) return CAT->getSize().getLimitedValue(); } } return 0; } } llvm_unreachable("Unknown type trait or not implemented"); } ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, TypeSourceInfo *TSInfo, Expr* DimExpr, SourceLocation RParen) { QualType T = TSInfo->getType(); // FIXME: This should likely be tracked as an APInt to remove any host // assumptions about the width of size_t on the target. uint64_t Value = 0; if (!T->isDependentType()) Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc); // While the specification for these traits from the Embarcadero C++ // compiler's documentation says the return type is 'unsigned int', Clang // returns 'size_t'. On Windows, the primary platform for the Embarcadero // compiler, there is no difference. On several other platforms this is an // important distinction. return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr, RParen, Context.getSizeType()); } ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen) { // If error parsing the expression, ignore. if (!Queried) return ExprError(); ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen); return Result; } static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E) { switch (ET) { case ET_IsLValueExpr: return E->isLValue(); case ET_IsRValueExpr: return E->isRValue(); } llvm_unreachable("Expression trait not covered by switch"); } ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen) { if (Queried->isTypeDependent()) { // Delay type-checking for type-dependent expressions. } else if (Queried->getType()->isPlaceholderType()) { ExprResult PE = CheckPlaceholderExpr(Queried); if (PE.isInvalid()) return ExprError(); return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen); } bool Value = EvaluateExpressionTrait(ET, Queried); return new (Context) ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy); } QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, SourceLocation Loc, bool isIndirect) { assert(!LHS.get()->getType()->isPlaceholderType() && !RHS.get()->getType()->isPlaceholderType() && "placeholders should have been weeded out by now"); // The LHS undergoes lvalue conversions if this is ->*, and undergoes the // temporary materialization conversion otherwise. if (isIndirect) LHS = DefaultLvalueConversion(LHS.get()); else if (LHS.get()->isRValue()) LHS = TemporaryMaterializationConversion(LHS.get()); if (LHS.isInvalid()) return QualType(); // The RHS always undergoes lvalue conversions. RHS = DefaultLvalueConversion(RHS.get()); if (RHS.isInvalid()) return QualType(); const char *OpSpelling = isIndirect ? "->*" : ".*"; // C++ 5.5p2 // The binary operator .* [p3: ->*] binds its second operand, which shall // be of type "pointer to member of T" (where T is a completely-defined // class type) [...] QualType RHSType = RHS.get()->getType(); const MemberPointerType *MemPtr = RHSType->getAs(); if (!MemPtr) { Diag(Loc, diag::err_bad_memptr_rhs) << OpSpelling << RHSType << RHS.get()->getSourceRange(); return QualType(); } QualType Class(MemPtr->getClass(), 0); // Note: C++ [expr.mptr.oper]p2-3 says that the class type into which the // member pointer points must be completely-defined. However, there is no // reason for this semantic distinction, and the rule is not enforced by // other compilers. Therefore, we do not check this property, as it is // likely to be considered a defect. // C++ 5.5p2 // [...] to its first operand, which shall be of class T or of a class of // which T is an unambiguous and accessible base class. [p3: a pointer to // such a class] QualType LHSType = LHS.get()->getType(); if (isIndirect) { if (const PointerType *Ptr = LHSType->getAs()) LHSType = Ptr->getPointeeType(); else { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << 1 << LHSType << FixItHint::CreateReplacement(SourceRange(Loc), ".*"); return QualType(); } } if (!Context.hasSameUnqualifiedType(Class, LHSType)) { // If we want to check the hierarchy, we need a complete type. if (RequireCompleteType(Loc, LHSType, diag::err_bad_memptr_lhs, OpSpelling, (int)isIndirect)) { return QualType(); } if (!IsDerivedFrom(Loc, LHSType, Class)) { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << (int)isIndirect << LHS.get()->getType(); return QualType(); } CXXCastPath BasePath; if (CheckDerivedToBaseConversion( LHSType, Class, Loc, SourceRange(LHS.get()->getBeginLoc(), RHS.get()->getEndLoc()), &BasePath)) return QualType(); // Cast LHS to type of use. QualType UseType = Context.getQualifiedType(Class, LHSType.getQualifiers()); if (isIndirect) UseType = Context.getPointerType(UseType); ExprValueKind VK = isIndirect ? VK_RValue : LHS.get()->getValueKind(); LHS = ImpCastExprToType(LHS.get(), UseType, CK_DerivedToBase, VK, &BasePath); } if (isa(RHS.get()->IgnoreParens())) { // Diagnose use of pointer-to-member type which when used as // the functional cast in a pointer-to-member expression. Diag(Loc, diag::err_pointer_to_member_type) << isIndirect; return QualType(); } // C++ 5.5p2 // The result is an object or a function of the type specified by the // second operand. // The cv qualifiers are the union of those in the pointer and the left side, // in accordance with 5.5p5 and 5.2.5. QualType Result = MemPtr->getPointeeType(); Result = Context.getCVRQualifiedType(Result, LHSType.getCVRQualifiers()); // C++0x [expr.mptr.oper]p6: // In a .* expression whose object expression is an rvalue, the program is // ill-formed if the second operand is a pointer to member function with // ref-qualifier &. In a ->* expression or in a .* expression whose object // expression is an lvalue, the program is ill-formed if the second operand // is a pointer to member function with ref-qualifier &&. if (const FunctionProtoType *Proto = Result->getAs()) { switch (Proto->getRefQualifier()) { case RQ_None: // Do nothing break; case RQ_LValue: if (!isIndirect && !LHS.get()->Classify(Context).isLValue()) { // C++2a allows functions with ref-qualifier & if their cv-qualifier-seq // is (exactly) 'const'. if (Proto->isConst() && !Proto->isVolatile()) Diag(Loc, getLangOpts().CPlusPlus2a ? diag::warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue : diag::ext_pointer_to_const_ref_member_on_rvalue); else Diag(Loc, diag::err_pointer_to_member_oper_value_classify) << RHSType << 1 << LHS.get()->getSourceRange(); } break; case RQ_RValue: if (isIndirect || !LHS.get()->Classify(Context).isRValue()) Diag(Loc, diag::err_pointer_to_member_oper_value_classify) << RHSType << 0 << LHS.get()->getSourceRange(); break; } } // C++ [expr.mptr.oper]p6: // The result of a .* expression whose second operand is a pointer // to a data member is of the same value category as its // first operand. The result of a .* expression whose second // operand is a pointer to a member function is a prvalue. The // result of an ->* expression is an lvalue if its second operand // is a pointer to data member and a prvalue otherwise. if (Result->isFunctionType()) { VK = VK_RValue; return Context.BoundMemberTy; } else if (isIndirect) { VK = VK_LValue; } else { VK = LHS.get()->getValueKind(); } return Result; } /// Try to convert a type to another according to C++11 5.16p3. /// /// This is part of the parameter validation for the ? operator. If either /// value operand is a class type, the two operands are attempted to be /// converted to each other. This function does the conversion in one direction. /// It returns true if the program is ill-formed and has already been diagnosed /// as such. static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, SourceLocation QuestionLoc, bool &HaveConversion, QualType &ToType) { HaveConversion = false; ToType = To->getType(); InitializationKind Kind = InitializationKind::CreateCopy(To->getBeginLoc(), SourceLocation()); // C++11 5.16p3 // The process for determining whether an operand expression E1 of type T1 // can be converted to match an operand expression E2 of type T2 is defined // as follows: // -- If E2 is an lvalue: E1 can be converted to match E2 if E1 can be // implicitly converted to type "lvalue reference to T2", subject to the // constraint that in the conversion the reference must bind directly to // an lvalue. // -- If E2 is an xvalue: E1 can be converted to match E2 if E1 can be // implicitly converted to the type "rvalue reference to R2", subject to // the constraint that the reference must bind directly. if (To->isLValue() || To->isXValue()) { QualType T = To->isLValue() ? Self.Context.getLValueReferenceType(ToType) : Self.Context.getRValueReferenceType(ToType); InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); InitializationSequence InitSeq(Self, Entity, Kind, From); if (InitSeq.isDirectReferenceBinding()) { ToType = T; HaveConversion = true; return false; } if (InitSeq.isAmbiguous()) return InitSeq.Diagnose(Self, Entity, Kind, From); } // -- If E2 is an rvalue, or if the conversion above cannot be done: // -- if E1 and E2 have class type, and the underlying class types are // the same or one is a base class of the other: QualType FTy = From->getType(); QualType TTy = To->getType(); const RecordType *FRec = FTy->getAs(); const RecordType *TRec = TTy->getAs(); bool FDerivedFromT = FRec && TRec && FRec != TRec && Self.IsDerivedFrom(QuestionLoc, FTy, TTy); if (FRec && TRec && (FRec == TRec || FDerivedFromT || Self.IsDerivedFrom(QuestionLoc, TTy, FTy))) { // E1 can be converted to match E2 if the class of T2 is the // same type as, or a base class of, the class of T1, and // [cv2 > cv1]. if (FRec == TRec || FDerivedFromT) { if (TTy.isAtLeastAsQualifiedAs(FTy)) { InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy); InitializationSequence InitSeq(Self, Entity, Kind, From); if (InitSeq) { HaveConversion = true; return false; } if (InitSeq.isAmbiguous()) return InitSeq.Diagnose(Self, Entity, Kind, From); } } return false; } // -- Otherwise: E1 can be converted to match E2 if E1 can be // implicitly converted to the type that expression E2 would have // if E2 were converted to an rvalue (or the type it has, if E2 is // an rvalue). // // This actually refers very narrowly to the lvalue-to-rvalue conversion, not // to the array-to-pointer or function-to-pointer conversions. TTy = TTy.getNonLValueExprType(Self.Context); InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy); InitializationSequence InitSeq(Self, Entity, Kind, From); HaveConversion = !InitSeq.Failed(); ToType = TTy; if (InitSeq.isAmbiguous()) return InitSeq.Diagnose(Self, Entity, Kind, From); return false; } /// Try to find a common type for two according to C++0x 5.16p5. /// /// This is part of the parameter validation for the ? operator. If either /// value operand is a class type, overload resolution is used to find a /// conversion to a common type. static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc) { Expr *Args[2] = { LHS.get(), RHS.get() }; OverloadCandidateSet CandidateSet(QuestionLoc, OverloadCandidateSet::CSK_Operator); Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args, CandidateSet); OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(Self, QuestionLoc, Best)) { case OR_Success: { // We found a match. Perform the conversions on the arguments and move on. ExprResult LHSRes = Self.PerformImplicitConversion( LHS.get(), Best->BuiltinParamTypes[0], Best->Conversions[0], Sema::AA_Converting); if (LHSRes.isInvalid()) break; LHS = LHSRes; ExprResult RHSRes = Self.PerformImplicitConversion( RHS.get(), Best->BuiltinParamTypes[1], Best->Conversions[1], Sema::AA_Converting); if (RHSRes.isInvalid()) break; RHS = RHSRes; if (Best->Function) Self.MarkFunctionReferenced(QuestionLoc, Best->Function); return false; } case OR_No_Viable_Function: // Emit a better diagnostic if one of the expressions is a null pointer // constant and the other is a pointer type. In this case, the user most // likely forgot to take the address of the other expression. if (Self.DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc)) return true; Self.Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) << LHS.get()->getType() << RHS.get()->getType() << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return true; case OR_Ambiguous: Self.Diag(QuestionLoc, diag::err_conditional_ambiguous_ovl) << LHS.get()->getType() << RHS.get()->getType() << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); // FIXME: Print the possible common types by printing the return types of // the viable candidates. break; case OR_Deleted: llvm_unreachable("Conditional operator has only built-in overloads"); } return true; } /// Perform an "extended" implicit conversion as returned by /// TryClassUnification. static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) { InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); InitializationKind Kind = InitializationKind::CreateCopy(E.get()->getBeginLoc(), SourceLocation()); Expr *Arg = E.get(); InitializationSequence InitSeq(Self, Entity, Kind, Arg); ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg); if (Result.isInvalid()) return true; E = Result; return false; } // Check the condition operand of ?: to see if it is valid for the GCC // extension. static bool isValidVectorForConditionalCondition(ASTContext &Ctx, QualType CondTy) { if (!CondTy->isVectorType() || CondTy->isExtVectorType()) return false; const QualType EltTy = cast(CondTy.getCanonicalType())->getElementType(); assert(!EltTy->isBooleanType() && !EltTy->isEnumeralType() && "Vectors cant be boolean or enum types"); return EltTy->isIntegralType(Ctx); } QualType Sema::CheckGNUVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc) { LHS = DefaultFunctionArrayLvalueConversion(LHS.get()); RHS = DefaultFunctionArrayLvalueConversion(RHS.get()); QualType CondType = Cond.get()->getType(); const auto *CondVT = CondType->getAs(); QualType CondElementTy = CondVT->getElementType(); unsigned CondElementCount = CondVT->getNumElements(); QualType LHSType = LHS.get()->getType(); const auto *LHSVT = LHSType->getAs(); QualType RHSType = RHS.get()->getType(); const auto *RHSVT = RHSType->getAs(); QualType ResultType; // FIXME: In the future we should define what the Extvector conditional // operator looks like. if (LHSVT && isa(LHSVT)) { Diag(QuestionLoc, diag::err_conditional_vector_operand_type) << /*isExtVector*/ true << LHSType; return {}; } if (RHSVT && isa(RHSVT)) { Diag(QuestionLoc, diag::err_conditional_vector_operand_type) << /*isExtVector*/ true << RHSType; return {}; } if (LHSVT && RHSVT) { // If both are vector types, they must be the same type. if (!Context.hasSameType(LHSType, RHSType)) { Diag(QuestionLoc, diag::err_conditional_vector_mismatched_vectors) << LHSType << RHSType; return {}; } ResultType = LHSType; } else if (LHSVT || RHSVT) { ResultType = CheckVectorOperands( LHS, RHS, QuestionLoc, /*isCompAssign*/ false, /*AllowBothBool*/ true, /*AllowBoolConversions*/ false); if (ResultType.isNull()) return {}; } else { // Both are scalar. QualType ResultElementTy; LHSType = LHSType.getCanonicalType().getUnqualifiedType(); RHSType = RHSType.getCanonicalType().getUnqualifiedType(); if (Context.hasSameType(LHSType, RHSType)) ResultElementTy = LHSType; else ResultElementTy = UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional); if (ResultElementTy->isEnumeralType()) { Diag(QuestionLoc, diag::err_conditional_vector_operand_type) << /*isExtVector*/ false << ResultElementTy; return {}; } ResultType = Context.getVectorType( ResultElementTy, CondType->getAs()->getNumElements(), VectorType::GenericVector); LHS = ImpCastExprToType(LHS.get(), ResultType, CK_VectorSplat); RHS = ImpCastExprToType(RHS.get(), ResultType, CK_VectorSplat); } assert(!ResultType.isNull() && ResultType->isVectorType() && "Result should have been a vector type"); QualType ResultElementTy = ResultType->getAs()->getElementType(); unsigned ResultElementCount = ResultType->getAs()->getNumElements(); if (ResultElementCount != CondElementCount) { Diag(QuestionLoc, diag::err_conditional_vector_size) << CondType << ResultType; return {}; } if (Context.getTypeSize(ResultElementTy) != Context.getTypeSize(CondElementTy)) { Diag(QuestionLoc, diag::err_conditional_vector_element_size) << CondType << ResultType; return {}; } return ResultType; } /// Check the operands of ?: under C++ semantics. /// /// See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y /// extension. In this case, LHS == Cond. (But they're not aliases.) /// /// This function also implements GCC's vector extension for conditionals. /// GCC's vector extension permits the use of a?b:c where the type of /// a is that of a integer vector with the same number of elements and /// size as the vectors of b and c. If one of either b or c is a scalar /// it is implicitly converted to match the type of the vector. /// Otherwise the expression is ill-formed. If both b and c are scalars, /// then b and c are checked and converted to the type of a if possible. /// Unlike the OpenCL ?: operator, the expression is evaluated as /// (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]). QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc) { // FIXME: Handle C99's complex types, block pointers and Obj-C++ interface // pointers. // Assume r-value. VK = VK_RValue; OK = OK_Ordinary; bool IsVectorConditional = isValidVectorForConditionalCondition(Context, Cond.get()->getType()); // C++11 [expr.cond]p1 // The first expression is contextually converted to bool. if (!Cond.get()->isTypeDependent()) { ExprResult CondRes = IsVectorConditional ? DefaultFunctionArrayLvalueConversion(Cond.get()) : CheckCXXBooleanCondition(Cond.get()); if (CondRes.isInvalid()) return QualType(); Cond = CondRes; } else { // To implement C++, the first expression typically doesn't alter the result // type of the conditional, however the GCC compatible vector extension // changes the result type to be that of the conditional. Since we cannot // know if this is a vector extension here, delay the conversion of the // LHS/RHS below until later. return Context.DependentTy; } // Either of the arguments dependent? if (LHS.get()->isTypeDependent() || RHS.get()->isTypeDependent()) return Context.DependentTy; // C++11 [expr.cond]p2 // If either the second or the third operand has type (cv) void, ... QualType LTy = LHS.get()->getType(); QualType RTy = RHS.get()->getType(); bool LVoid = LTy->isVoidType(); bool RVoid = RTy->isVoidType(); if (LVoid || RVoid) { // ... one of the following shall hold: // -- The second or the third operand (but not both) is a (possibly // parenthesized) throw-expression; the result is of the type // and value category of the other. bool LThrow = isa(LHS.get()->IgnoreParenImpCasts()); bool RThrow = isa(RHS.get()->IgnoreParenImpCasts()); // Void expressions aren't legal in the vector-conditional expressions. if (IsVectorConditional) { SourceRange DiagLoc = LVoid ? LHS.get()->getSourceRange() : RHS.get()->getSourceRange(); bool IsThrow = LVoid ? LThrow : RThrow; Diag(DiagLoc.getBegin(), diag::err_conditional_vector_has_void) << DiagLoc << IsThrow; return QualType(); } if (LThrow != RThrow) { Expr *NonThrow = LThrow ? RHS.get() : LHS.get(); VK = NonThrow->getValueKind(); // DR (no number yet): the result is a bit-field if the // non-throw-expression operand is a bit-field. OK = NonThrow->getObjectKind(); return NonThrow->getType(); } // -- Both the second and third operands have type void; the result is of // type void and is a prvalue. if (LVoid && RVoid) return Context.VoidTy; // Neither holds, error. Diag(QuestionLoc, diag::err_conditional_void_nonvoid) << (LVoid ? RTy : LTy) << (LVoid ? 0 : 1) << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); } // Neither is void. if (IsVectorConditional) return CheckGNUVectorConditionalTypes(Cond, LHS, RHS, QuestionLoc); // C++11 [expr.cond]p3 // Otherwise, if the second and third operand have different types, and // either has (cv) class type [...] an attempt is made to convert each of // those operands to the type of the other. if (!Context.hasSameType(LTy, RTy) && (LTy->isRecordType() || RTy->isRecordType())) { // These return true if a single direction is already ambiguous. QualType L2RType, R2LType; bool HaveL2R, HaveR2L; if (TryClassUnification(*this, LHS.get(), RHS.get(), QuestionLoc, HaveL2R, L2RType)) return QualType(); if (TryClassUnification(*this, RHS.get(), LHS.get(), QuestionLoc, HaveR2L, R2LType)) return QualType(); // If both can be converted, [...] the program is ill-formed. if (HaveL2R && HaveR2L) { Diag(QuestionLoc, diag::err_conditional_ambiguous) << LTy << RTy << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); } // If exactly one conversion is possible, that conversion is applied to // the chosen operand and the converted operands are used in place of the // original operands for the remainder of this section. if (HaveL2R) { if (ConvertForConditional(*this, LHS, L2RType) || LHS.isInvalid()) return QualType(); LTy = LHS.get()->getType(); } else if (HaveR2L) { if (ConvertForConditional(*this, RHS, R2LType) || RHS.isInvalid()) return QualType(); RTy = RHS.get()->getType(); } } // C++11 [expr.cond]p3 // if both are glvalues of the same value category and the same type except // for cv-qualification, an attempt is made to convert each of those // operands to the type of the other. // FIXME: // Resolving a defect in P0012R1: we extend this to cover all cases where // one of the operands is reference-compatible with the other, in order // to support conditionals between functions differing in noexcept. This // will similarly cover difference in array bounds after P0388R4. // FIXME: If LTy and RTy have a composite pointer type, should we convert to // that instead? ExprValueKind LVK = LHS.get()->getValueKind(); ExprValueKind RVK = RHS.get()->getValueKind(); if (!Context.hasSameType(LTy, RTy) && LVK == RVK && LVK != VK_RValue) { // DerivedToBase was already handled by the class-specific case above. // FIXME: Should we allow ObjC conversions here? const ReferenceConversions AllowedConversions = ReferenceConversions::Qualification | ReferenceConversions::NestedQualification | ReferenceConversions::Function; ReferenceConversions RefConv; if (CompareReferenceRelationship(QuestionLoc, LTy, RTy, &RefConv) == Ref_Compatible && !(RefConv & ~AllowedConversions) && // [...] subject to the constraint that the reference must bind // directly [...] !RHS.get()->refersToBitField() && !RHS.get()->refersToVectorElement()) { RHS = ImpCastExprToType(RHS.get(), LTy, CK_NoOp, RVK); RTy = RHS.get()->getType(); } else if (CompareReferenceRelationship(QuestionLoc, RTy, LTy, &RefConv) == Ref_Compatible && !(RefConv & ~AllowedConversions) && !LHS.get()->refersToBitField() && !LHS.get()->refersToVectorElement()) { LHS = ImpCastExprToType(LHS.get(), RTy, CK_NoOp, LVK); LTy = LHS.get()->getType(); } } // C++11 [expr.cond]p4 // If the second and third operands are glvalues of the same value // category and have the same type, the result is of that type and // value category and it is a bit-field if the second or the third // operand is a bit-field, or if both are bit-fields. // We only extend this to bitfields, not to the crazy other kinds of // l-values. bool Same = Context.hasSameType(LTy, RTy); if (Same && LVK == RVK && LVK != VK_RValue && LHS.get()->isOrdinaryOrBitFieldObject() && RHS.get()->isOrdinaryOrBitFieldObject()) { VK = LHS.get()->getValueKind(); if (LHS.get()->getObjectKind() == OK_BitField || RHS.get()->getObjectKind() == OK_BitField) OK = OK_BitField; // If we have function pointer types, unify them anyway to unify their // exception specifications, if any. if (LTy->isFunctionPointerType() || LTy->isMemberFunctionPointerType()) { Qualifiers Qs = LTy.getQualifiers(); LTy = FindCompositePointerType(QuestionLoc, LHS, RHS, /*ConvertArgs*/false); LTy = Context.getQualifiedType(LTy, Qs); assert(!LTy.isNull() && "failed to find composite pointer type for " "canonically equivalent function ptr types"); assert(Context.hasSameType(LTy, RTy) && "bad composite pointer type"); } return LTy; } // C++11 [expr.cond]p5 // Otherwise, the result is a prvalue. If the second and third operands // do not have the same type, and either has (cv) class type, ... if (!Same && (LTy->isRecordType() || RTy->isRecordType())) { // ... overload resolution is used to determine the conversions (if any) // to be applied to the operands. If the overload resolution fails, the // program is ill-formed. if (FindConditionalOverload(*this, LHS, RHS, QuestionLoc)) return QualType(); } // C++11 [expr.cond]p6 // Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard // conversions are performed on the second and third operands. LHS = DefaultFunctionArrayLvalueConversion(LHS.get()); RHS = DefaultFunctionArrayLvalueConversion(RHS.get()); if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); LTy = LHS.get()->getType(); RTy = RHS.get()->getType(); // After those conversions, one of the following shall hold: // -- The second and third operands have the same type; the result // is of that type. If the operands have class type, the result // is a prvalue temporary of the result type, which is // copy-initialized from either the second operand or the third // operand depending on the value of the first operand. if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) { if (LTy->isRecordType()) { // The operands have class type. Make a temporary copy. InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy); ExprResult LHSCopy = PerformCopyInitialization(Entity, SourceLocation(), LHS); if (LHSCopy.isInvalid()) return QualType(); ExprResult RHSCopy = PerformCopyInitialization(Entity, SourceLocation(), RHS); if (RHSCopy.isInvalid()) return QualType(); LHS = LHSCopy; RHS = RHSCopy; } // If we have function pointer types, unify them anyway to unify their // exception specifications, if any. if (LTy->isFunctionPointerType() || LTy->isMemberFunctionPointerType()) { LTy = FindCompositePointerType(QuestionLoc, LHS, RHS); assert(!LTy.isNull() && "failed to find composite pointer type for " "canonically equivalent function ptr types"); } return LTy; } // Extension: conditional operator involving vector types. if (LTy->isVectorType() || RTy->isVectorType()) return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false, /*AllowBothBool*/true, /*AllowBoolConversions*/false); // -- The second and third operands have arithmetic or enumeration type; // the usual arithmetic conversions are performed to bring them to a // common type, and the result is of that type. if (LTy->isArithmeticType() && RTy->isArithmeticType()) { QualType ResTy = UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional); if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); if (ResTy.isNull()) { Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) << LTy << RTy << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); } LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy)); RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy)); return ResTy; } // -- The second and third operands have pointer type, or one has pointer // type and the other is a null pointer constant, or both are null // pointer constants, at least one of which is non-integral; pointer // conversions and qualification conversions are performed to bring them // to their composite pointer type. The result is of the composite // pointer type. // -- The second and third operands have pointer to member type, or one has // pointer to member type and the other is a null pointer constant; // pointer to member conversions and qualification conversions are // performed to bring them to a common type, whose cv-qualification // shall match the cv-qualification of either the second or the third // operand. The result is of the common type. QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS); if (!Composite.isNull()) return Composite; // Similarly, attempt to find composite type of two objective-c pointers. Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc); if (!Composite.isNull()) return Composite; // Check if we are using a null with a non-pointer type. if (DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc)) return QualType(); Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) << LHS.get()->getType() << RHS.get()->getType() << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); return QualType(); } static FunctionProtoType::ExceptionSpecInfo mergeExceptionSpecs(Sema &S, FunctionProtoType::ExceptionSpecInfo ESI1, FunctionProtoType::ExceptionSpecInfo ESI2, SmallVectorImpl &ExceptionTypeStorage) { ExceptionSpecificationType EST1 = ESI1.Type; ExceptionSpecificationType EST2 = ESI2.Type; // If either of them can throw anything, that is the result. if (EST1 == EST_None) return ESI1; if (EST2 == EST_None) return ESI2; if (EST1 == EST_MSAny) return ESI1; if (EST2 == EST_MSAny) return ESI2; if (EST1 == EST_NoexceptFalse) return ESI1; if (EST2 == EST_NoexceptFalse) return ESI2; // If either of them is non-throwing, the result is the other. if (EST1 == EST_NoThrow) return ESI2; if (EST2 == EST_NoThrow) return ESI1; if (EST1 == EST_DynamicNone) return ESI2; if (EST2 == EST_DynamicNone) return ESI1; if (EST1 == EST_BasicNoexcept) return ESI2; if (EST2 == EST_BasicNoexcept) return ESI1; if (EST1 == EST_NoexceptTrue) return ESI2; if (EST2 == EST_NoexceptTrue) return ESI1; // If we're left with value-dependent computed noexcept expressions, we're // stuck. Before C++17, we can just drop the exception specification entirely, // since it's not actually part of the canonical type. And this should never // happen in C++17, because it would mean we were computing the composite // pointer type of dependent types, which should never happen. if (EST1 == EST_DependentNoexcept || EST2 == EST_DependentNoexcept) { assert(!S.getLangOpts().CPlusPlus17 && "computing composite pointer type of dependent types"); return FunctionProtoType::ExceptionSpecInfo(); } // Switch over the possibilities so that people adding new values know to // update this function. switch (EST1) { case EST_None: case EST_DynamicNone: case EST_MSAny: case EST_BasicNoexcept: case EST_DependentNoexcept: case EST_NoexceptFalse: case EST_NoexceptTrue: case EST_NoThrow: llvm_unreachable("handled above"); case EST_Dynamic: { // This is the fun case: both exception specifications are dynamic. Form // the union of the two lists. assert(EST2 == EST_Dynamic && "other cases should already be handled"); llvm::SmallPtrSet Found; for (auto &Exceptions : {ESI1.Exceptions, ESI2.Exceptions}) for (QualType E : Exceptions) if (Found.insert(S.Context.getCanonicalType(E)).second) ExceptionTypeStorage.push_back(E); FunctionProtoType::ExceptionSpecInfo Result(EST_Dynamic); Result.Exceptions = ExceptionTypeStorage; return Result; } case EST_Unevaluated: case EST_Uninstantiated: case EST_Unparsed: llvm_unreachable("shouldn't see unresolved exception specifications here"); } llvm_unreachable("invalid ExceptionSpecificationType"); } /// Find a merged pointer type and convert the two expressions to it. /// /// This finds the composite pointer type for \p E1 and \p E2 according to /// C++2a [expr.type]p3. It converts both expressions to this type and returns /// it. It does not emit diagnostics (FIXME: that's not true if \p ConvertArgs /// is \c true). /// /// \param Loc The location of the operator requiring these two expressions to /// be converted to the composite pointer type. /// /// \param ConvertArgs If \c false, do not convert E1 and E2 to the target type. QualType Sema::FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2, bool ConvertArgs) { assert(getLangOpts().CPlusPlus && "This function assumes C++"); // C++1z [expr]p14: // The composite pointer type of two operands p1 and p2 having types T1 // and T2 QualType T1 = E1->getType(), T2 = E2->getType(); // where at least one is a pointer or pointer to member type or // std::nullptr_t is: bool T1IsPointerLike = T1->isAnyPointerType() || T1->isMemberPointerType() || T1->isNullPtrType(); bool T2IsPointerLike = T2->isAnyPointerType() || T2->isMemberPointerType() || T2->isNullPtrType(); if (!T1IsPointerLike && !T2IsPointerLike) return QualType(); // - if both p1 and p2 are null pointer constants, std::nullptr_t; // This can't actually happen, following the standard, but we also use this // to implement the end of [expr.conv], which hits this case. // // - if either p1 or p2 is a null pointer constant, T2 or T1, respectively; if (T1IsPointerLike && E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { if (ConvertArgs) E2 = ImpCastExprToType(E2, T1, T1->isMemberPointerType() ? CK_NullToMemberPointer : CK_NullToPointer).get(); return T1; } if (T2IsPointerLike && E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { if (ConvertArgs) E1 = ImpCastExprToType(E1, T2, T2->isMemberPointerType() ? CK_NullToMemberPointer : CK_NullToPointer).get(); return T2; } // Now both have to be pointers or member pointers. if (!T1IsPointerLike || !T2IsPointerLike) return QualType(); assert(!T1->isNullPtrType() && !T2->isNullPtrType() && "nullptr_t should be a null pointer constant"); struct Step { enum Kind { Pointer, ObjCPointer, MemberPointer, Array } K; // Qualifiers to apply under the step kind. Qualifiers Quals; /// The class for a pointer-to-member; a constant array type with a bound /// (if any) for an array. const Type *ClassOrBound; Step(Kind K, const Type *ClassOrBound = nullptr) : K(K), Quals(), ClassOrBound(ClassOrBound) {} QualType rebuild(ASTContext &Ctx, QualType T) const { T = Ctx.getQualifiedType(T, Quals); switch (K) { case Pointer: return Ctx.getPointerType(T); case MemberPointer: return Ctx.getMemberPointerType(T, ClassOrBound); case ObjCPointer: return Ctx.getObjCObjectPointerType(T); case Array: if (auto *CAT = cast_or_null(ClassOrBound)) return Ctx.getConstantArrayType(T, CAT->getSize(), nullptr, ArrayType::Normal, 0); else return Ctx.getIncompleteArrayType(T, ArrayType::Normal, 0); } llvm_unreachable("unknown step kind"); } }; SmallVector Steps; // - if T1 is "pointer to cv1 C1" and T2 is "pointer to cv2 C2", where C1 // is reference-related to C2 or C2 is reference-related to C1 (8.6.3), // the cv-combined type of T1 and T2 or the cv-combined type of T2 and T1, // respectively; // - if T1 is "pointer to member of C1 of type cv1 U1" and T2 is "pointer // to member of C2 of type cv2 U2" for some non-function type U, where // C1 is reference-related to C2 or C2 is reference-related to C1, the // cv-combined type of T2 and T1 or the cv-combined type of T1 and T2, // respectively; // - if T1 and T2 are similar types (4.5), the cv-combined type of T1 and // T2; // // Dismantle T1 and T2 to simultaneously determine whether they are similar // and to prepare to form the cv-combined type if so. QualType Composite1 = T1; QualType Composite2 = T2; unsigned NeedConstBefore = 0; while (true) { assert(!Composite1.isNull() && !Composite2.isNull()); Qualifiers Q1, Q2; Composite1 = Context.getUnqualifiedArrayType(Composite1, Q1); Composite2 = Context.getUnqualifiedArrayType(Composite2, Q2); // Top-level qualifiers are ignored. Merge at all lower levels. if (!Steps.empty()) { // Find the qualifier union: (approximately) the unique minimal set of // qualifiers that is compatible with both types. Qualifiers Quals = Qualifiers::fromCVRUMask(Q1.getCVRUQualifiers() | Q2.getCVRUQualifiers()); // Under one level of pointer or pointer-to-member, we can change to an // unambiguous compatible address space. if (Q1.getAddressSpace() == Q2.getAddressSpace()) { Quals.setAddressSpace(Q1.getAddressSpace()); } else if (Steps.size() == 1) { bool MaybeQ1 = Q1.isAddressSpaceSupersetOf(Q2); bool MaybeQ2 = Q2.isAddressSpaceSupersetOf(Q1); if (MaybeQ1 == MaybeQ2) return QualType(); // No unique best address space. Quals.setAddressSpace(MaybeQ1 ? Q1.getAddressSpace() : Q2.getAddressSpace()); } else { return QualType(); } // FIXME: In C, we merge __strong and none to __strong at the top level. if (Q1.getObjCGCAttr() == Q2.getObjCGCAttr()) Quals.setObjCGCAttr(Q1.getObjCGCAttr()); else return QualType(); // Mismatched lifetime qualifiers never compatibly include each other. if (Q1.getObjCLifetime() == Q2.getObjCLifetime()) Quals.setObjCLifetime(Q1.getObjCLifetime()); else return QualType(); Steps.back().Quals = Quals; if (Q1 != Quals || Q2 != Quals) NeedConstBefore = Steps.size() - 1; } // FIXME: Can we unify the following with UnwrapSimilarTypes? const PointerType *Ptr1, *Ptr2; if ((Ptr1 = Composite1->getAs()) && (Ptr2 = Composite2->getAs())) { Composite1 = Ptr1->getPointeeType(); Composite2 = Ptr2->getPointeeType(); Steps.emplace_back(Step::Pointer); continue; } const ObjCObjectPointerType *ObjPtr1, *ObjPtr2; if ((ObjPtr1 = Composite1->getAs()) && (ObjPtr2 = Composite2->getAs())) { Composite1 = ObjPtr1->getPointeeType(); Composite2 = ObjPtr2->getPointeeType(); Steps.emplace_back(Step::ObjCPointer); continue; } const MemberPointerType *MemPtr1, *MemPtr2; if ((MemPtr1 = Composite1->getAs()) && (MemPtr2 = Composite2->getAs())) { Composite1 = MemPtr1->getPointeeType(); Composite2 = MemPtr2->getPointeeType(); // At the top level, we can perform a base-to-derived pointer-to-member // conversion: // // - [...] where C1 is reference-related to C2 or C2 is // reference-related to C1 // // (Note that the only kinds of reference-relatedness in scope here are // "same type or derived from".) At any other level, the class must // exactly match. const Type *Class = nullptr; QualType Cls1(MemPtr1->getClass(), 0); QualType Cls2(MemPtr2->getClass(), 0); if (Context.hasSameType(Cls1, Cls2)) Class = MemPtr1->getClass(); else if (Steps.empty()) Class = IsDerivedFrom(Loc, Cls1, Cls2) ? MemPtr1->getClass() : IsDerivedFrom(Loc, Cls2, Cls1) ? MemPtr2->getClass() : nullptr; if (!Class) return QualType(); Steps.emplace_back(Step::MemberPointer, Class); continue; } // Special case: at the top level, we can decompose an Objective-C pointer // and a 'cv void *'. Unify the qualifiers. if (Steps.empty() && ((Composite1->isVoidPointerType() && Composite2->isObjCObjectPointerType()) || (Composite1->isObjCObjectPointerType() && Composite2->isVoidPointerType()))) { Composite1 = Composite1->getPointeeType(); Composite2 = Composite2->getPointeeType(); Steps.emplace_back(Step::Pointer); continue; } // FIXME: arrays // FIXME: block pointer types? // Cannot unwrap any more types. break; } // - if T1 or T2 is "pointer to noexcept function" and the other type is // "pointer to function", where the function types are otherwise the same, // "pointer to function"; // - if T1 or T2 is "pointer to member of C1 of type function", the other // type is "pointer to member of C2 of type noexcept function", and C1 // is reference-related to C2 or C2 is reference-related to C1, where // the function types are otherwise the same, "pointer to member of C2 of // type function" or "pointer to member of C1 of type function", // respectively; // // We also support 'noreturn' here, so as a Clang extension we generalize the // above to: // // - [Clang] If T1 and T2 are both of type "pointer to function" or // "pointer to member function" and the pointee types can be unified // by a function pointer conversion, that conversion is applied // before checking the following rules. // // We've already unwrapped down to the function types, and we want to merge // rather than just convert, so do this ourselves rather than calling // IsFunctionConversion. // // FIXME: In order to match the standard wording as closely as possible, we // currently only do this under a single level of pointers. Ideally, we would // allow this in general, and set NeedConstBefore to the relevant depth on // the side(s) where we changed anything. If we permit that, we should also // consider this conversion when determining type similarity and model it as // a qualification conversion. if (Steps.size() == 1) { if (auto *FPT1 = Composite1->getAs()) { if (auto *FPT2 = Composite2->getAs()) { FunctionProtoType::ExtProtoInfo EPI1 = FPT1->getExtProtoInfo(); FunctionProtoType::ExtProtoInfo EPI2 = FPT2->getExtProtoInfo(); // The result is noreturn if both operands are. bool Noreturn = EPI1.ExtInfo.getNoReturn() && EPI2.ExtInfo.getNoReturn(); EPI1.ExtInfo = EPI1.ExtInfo.withNoReturn(Noreturn); EPI2.ExtInfo = EPI2.ExtInfo.withNoReturn(Noreturn); // The result is nothrow if both operands are. SmallVector ExceptionTypeStorage; EPI1.ExceptionSpec = EPI2.ExceptionSpec = mergeExceptionSpecs(*this, EPI1.ExceptionSpec, EPI2.ExceptionSpec, ExceptionTypeStorage); Composite1 = Context.getFunctionType(FPT1->getReturnType(), FPT1->getParamTypes(), EPI1); Composite2 = Context.getFunctionType(FPT2->getReturnType(), FPT2->getParamTypes(), EPI2); } } } // There are some more conversions we can perform under exactly one pointer. if (Steps.size() == 1 && Steps.front().K == Step::Pointer && !Context.hasSameType(Composite1, Composite2)) { // - if T1 or T2 is "pointer to cv1 void" and the other type is // "pointer to cv2 T", where T is an object type or void, // "pointer to cv12 void", where cv12 is the union of cv1 and cv2; if (Composite1->isVoidType() && Composite2->isObjectType()) Composite2 = Composite1; else if (Composite2->isVoidType() && Composite1->isObjectType()) Composite1 = Composite2; // - if T1 is "pointer to cv1 C1" and T2 is "pointer to cv2 C2", where C1 // is reference-related to C2 or C2 is reference-related to C1 (8.6.3), // the cv-combined type of T1 and T2 or the cv-combined type of T2 and // T1, respectively; // // The "similar type" handling covers all of this except for the "T1 is a // base class of T2" case in the definition of reference-related. else if (IsDerivedFrom(Loc, Composite1, Composite2)) Composite1 = Composite2; else if (IsDerivedFrom(Loc, Composite2, Composite1)) Composite2 = Composite1; } // At this point, either the inner types are the same or we have failed to // find a composite pointer type. if (!Context.hasSameType(Composite1, Composite2)) return QualType(); // Per C++ [conv.qual]p3, add 'const' to every level before the last // differing qualifier. for (unsigned I = 0; I != NeedConstBefore; ++I) Steps[I].Quals.addConst(); // Rebuild the composite type. QualType Composite = Composite1; for (auto &S : llvm::reverse(Steps)) Composite = S.rebuild(Context, Composite); if (ConvertArgs) { // Convert the expressions to the composite pointer type. InitializedEntity Entity = InitializedEntity::InitializeTemporary(Composite); InitializationKind Kind = InitializationKind::CreateCopy(Loc, SourceLocation()); InitializationSequence E1ToC(*this, Entity, Kind, E1); if (!E1ToC) return QualType(); InitializationSequence E2ToC(*this, Entity, Kind, E2); if (!E2ToC) return QualType(); // FIXME: Let the caller know if these fail to avoid duplicate diagnostics. ExprResult E1Result = E1ToC.Perform(*this, Entity, Kind, E1); if (E1Result.isInvalid()) return QualType(); E1 = E1Result.get(); ExprResult E2Result = E2ToC.Perform(*this, Entity, Kind, E2); if (E2Result.isInvalid()) return QualType(); E2 = E2Result.get(); } return Composite; } ExprResult Sema::MaybeBindToTemporary(Expr *E) { if (!E) return ExprError(); assert(!isa(E) && "Double-bound temporary?"); // If the result is a glvalue, we shouldn't bind it. if (!E->isRValue()) return E; // In ARC, calls that return a retainable type can return retained, // in which case we have to insert a consuming cast. if (getLangOpts().ObjCAutoRefCount && E->getType()->isObjCRetainableType()) { bool ReturnsRetained; // For actual calls, we compute this by examining the type of the // called value. if (CallExpr *Call = dyn_cast(E)) { Expr *Callee = Call->getCallee()->IgnoreParens(); QualType T = Callee->getType(); if (T == Context.BoundMemberTy) { // Handle pointer-to-members. if (BinaryOperator *BinOp = dyn_cast(Callee)) T = BinOp->getRHS()->getType(); else if (MemberExpr *Mem = dyn_cast(Callee)) T = Mem->getMemberDecl()->getType(); } if (const PointerType *Ptr = T->getAs()) T = Ptr->getPointeeType(); else if (const BlockPointerType *Ptr = T->getAs()) T = Ptr->getPointeeType(); else if (const MemberPointerType *MemPtr = T->getAs()) T = MemPtr->getPointeeType(); const FunctionType *FTy = T->getAs(); assert(FTy && "call to value not of function type?"); ReturnsRetained = FTy->getExtInfo().getProducesResult(); // ActOnStmtExpr arranges things so that StmtExprs of retainable // type always produce a +1 object. } else if (isa(E)) { ReturnsRetained = true; // We hit this case with the lambda conversion-to-block optimization; // we don't want any extra casts here. } else if (isa(E) && isa(cast(E)->getSubExpr())) { return E; // For message sends and property references, we try to find an // actual method. FIXME: we should infer retention by selector in // cases where we don't have an actual method. } else { ObjCMethodDecl *D = nullptr; if (ObjCMessageExpr *Send = dyn_cast(E)) { D = Send->getMethodDecl(); } else if (ObjCBoxedExpr *BoxedExpr = dyn_cast(E)) { D = BoxedExpr->getBoxingMethod(); } else if (ObjCArrayLiteral *ArrayLit = dyn_cast(E)) { // Don't do reclaims if we're using the zero-element array // constant. if (ArrayLit->getNumElements() == 0 && Context.getLangOpts().ObjCRuntime.hasEmptyCollections()) return E; D = ArrayLit->getArrayWithObjectsMethod(); } else if (ObjCDictionaryLiteral *DictLit = dyn_cast(E)) { // Don't do reclaims if we're using the zero-element dictionary // constant. if (DictLit->getNumElements() == 0 && Context.getLangOpts().ObjCRuntime.hasEmptyCollections()) return E; D = DictLit->getDictWithObjectsMethod(); } ReturnsRetained = (D && D->hasAttr()); // Don't do reclaims on performSelector calls; despite their // return type, the invoked method doesn't necessarily actually // return an object. if (!ReturnsRetained && D && D->getMethodFamily() == OMF_performSelector) return E; } // Don't reclaim an object of Class type. if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType()) return E; Cleanup.setExprNeedsCleanups(true); CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject : CK_ARCReclaimReturnedObject); return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr, VK_RValue); } if (!getLangOpts().CPlusPlus) return E; // Search for the base element type (cf. ASTContext::getBaseElementType) with // a fast path for the common case that the type is directly a RecordType. const Type *T = Context.getCanonicalType(E->getType().getTypePtr()); const RecordType *RT = nullptr; while (!RT) { switch (T->getTypeClass()) { case Type::Record: RT = cast(T); break; case Type::ConstantArray: case Type::IncompleteArray: case Type::VariableArray: case Type::DependentSizedArray: T = cast(T)->getElementType().getTypePtr(); break; default: return E; } } // That should be enough to guarantee that this type is complete, if we're // not processing a decltype expression. CXXRecordDecl *RD = cast(RT->getDecl()); if (RD->isInvalidDecl() || RD->isDependentContext()) return E; bool IsDecltype = ExprEvalContexts.back().ExprContext == ExpressionEvaluationContextRecord::EK_Decltype; CXXDestructorDecl *Destructor = IsDecltype ? nullptr : LookupDestructor(RD); if (Destructor) { MarkFunctionReferenced(E->getExprLoc(), Destructor); CheckDestructorAccess(E->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_temp) << E->getType()); if (DiagnoseUseOfDecl(Destructor, E->getExprLoc())) return ExprError(); // If destructor is trivial, we can avoid the extra copy. if (Destructor->isTrivial()) return E; // We need a cleanup, but we don't need to remember the temporary. Cleanup.setExprNeedsCleanups(true); } CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor); CXXBindTemporaryExpr *Bind = CXXBindTemporaryExpr::Create(Context, Temp, E); if (IsDecltype) ExprEvalContexts.back().DelayedDecltypeBinds.push_back(Bind); return Bind; } ExprResult Sema::MaybeCreateExprWithCleanups(ExprResult SubExpr) { if (SubExpr.isInvalid()) return ExprError(); return MaybeCreateExprWithCleanups(SubExpr.get()); } Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) { assert(SubExpr && "subexpression can't be null!"); CleanupVarDeclMarking(); unsigned FirstCleanup = ExprEvalContexts.back().NumCleanupObjects; assert(ExprCleanupObjects.size() >= FirstCleanup); assert(Cleanup.exprNeedsCleanups() || ExprCleanupObjects.size() == FirstCleanup); if (!Cleanup.exprNeedsCleanups()) return SubExpr; auto Cleanups = llvm::makeArrayRef(ExprCleanupObjects.begin() + FirstCleanup, ExprCleanupObjects.size() - FirstCleanup); auto *E = ExprWithCleanups::Create( Context, SubExpr, Cleanup.cleanupsHaveSideEffects(), Cleanups); DiscardCleanupsInEvaluationContext(); return E; } Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) { assert(SubStmt && "sub-statement can't be null!"); CleanupVarDeclMarking(); if (!Cleanup.exprNeedsCleanups()) return SubStmt; // FIXME: In order to attach the temporaries, wrap the statement into // a StmtExpr; currently this is only used for asm statements. // This is hacky, either create a new CXXStmtWithTemporaries statement or // a new AsmStmtWithTemporaries. CompoundStmt *CompStmt = CompoundStmt::Create( Context, SubStmt, SourceLocation(), SourceLocation()); Expr *E = new (Context) StmtExpr(CompStmt, Context.VoidTy, SourceLocation(), SourceLocation(), /*FIXME TemplateDepth=*/0); return MaybeCreateExprWithCleanups(E); } /// Process the expression contained within a decltype. For such expressions, /// certain semantic checks on temporaries are delayed until this point, and /// are omitted for the 'topmost' call in the decltype expression. If the /// topmost call bound a temporary, strip that temporary off the expression. ExprResult Sema::ActOnDecltypeExpression(Expr *E) { assert(ExprEvalContexts.back().ExprContext == ExpressionEvaluationContextRecord::EK_Decltype && "not in a decltype expression"); ExprResult Result = CheckPlaceholderExpr(E); if (Result.isInvalid()) return ExprError(); E = Result.get(); // C++11 [expr.call]p11: // If a function call is a prvalue of object type, // -- if the function call is either // -- the operand of a decltype-specifier, or // -- the right operand of a comma operator that is the operand of a // decltype-specifier, // a temporary object is not introduced for the prvalue. // Recursively rebuild ParenExprs and comma expressions to strip out the // outermost CXXBindTemporaryExpr, if any. if (ParenExpr *PE = dyn_cast(E)) { ExprResult SubExpr = ActOnDecltypeExpression(PE->getSubExpr()); if (SubExpr.isInvalid()) return ExprError(); if (SubExpr.get() == PE->getSubExpr()) return E; return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.get()); } if (BinaryOperator *BO = dyn_cast(E)) { if (BO->getOpcode() == BO_Comma) { ExprResult RHS = ActOnDecltypeExpression(BO->getRHS()); if (RHS.isInvalid()) return ExprError(); if (RHS.get() == BO->getRHS()) return E; return new (Context) BinaryOperator( BO->getLHS(), RHS.get(), BO_Comma, BO->getType(), BO->getValueKind(), BO->getObjectKind(), BO->getOperatorLoc(), BO->getFPFeatures()); } } CXXBindTemporaryExpr *TopBind = dyn_cast(E); CallExpr *TopCall = TopBind ? dyn_cast(TopBind->getSubExpr()) : nullptr; if (TopCall) E = TopCall; else TopBind = nullptr; // Disable the special decltype handling now. ExprEvalContexts.back().ExprContext = ExpressionEvaluationContextRecord::EK_Other; Result = CheckUnevaluatedOperand(E); if (Result.isInvalid()) return ExprError(); E = Result.get(); // In MS mode, don't perform any extra checking of call return types within a // decltype expression. if (getLangOpts().MSVCCompat) return E; // Perform the semantic checks we delayed until this point. for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeCalls.size(); I != N; ++I) { CallExpr *Call = ExprEvalContexts.back().DelayedDecltypeCalls[I]; if (Call == TopCall) continue; if (CheckCallReturnType(Call->getCallReturnType(Context), Call->getBeginLoc(), Call, Call->getDirectCallee())) return ExprError(); } // Now all relevant types are complete, check the destructors are accessible // and non-deleted, and annotate them on the temporaries. for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeBinds.size(); I != N; ++I) { CXXBindTemporaryExpr *Bind = ExprEvalContexts.back().DelayedDecltypeBinds[I]; if (Bind == TopBind) continue; CXXTemporary *Temp = Bind->getTemporary(); CXXRecordDecl *RD = Bind->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl(); CXXDestructorDecl *Destructor = LookupDestructor(RD); Temp->setDestructor(Destructor); MarkFunctionReferenced(Bind->getExprLoc(), Destructor); CheckDestructorAccess(Bind->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_temp) << Bind->getType()); if (DiagnoseUseOfDecl(Destructor, Bind->getExprLoc())) return ExprError(); // We need a cleanup, but we don't need to remember the temporary. Cleanup.setExprNeedsCleanups(true); } // Possibly strip off the top CXXBindTemporaryExpr. return E; } /// Note a set of 'operator->' functions that were used for a member access. static void noteOperatorArrows(Sema &S, ArrayRef OperatorArrows) { unsigned SkipStart = OperatorArrows.size(), SkipCount = 0; // FIXME: Make this configurable? unsigned Limit = 9; if (OperatorArrows.size() > Limit) { // Produce Limit-1 normal notes and one 'skipping' note. SkipStart = (Limit - 1) / 2 + (Limit - 1) % 2; SkipCount = OperatorArrows.size() - (Limit - 1); } for (unsigned I = 0; I < OperatorArrows.size(); /**/) { if (I == SkipStart) { S.Diag(OperatorArrows[I]->getLocation(), diag::note_operator_arrows_suppressed) << SkipCount; I += SkipCount; } else { S.Diag(OperatorArrows[I]->getLocation(), diag::note_operator_arrow_here) << OperatorArrows[I]->getCallResultType(); ++I; } } } ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, ParsedType &ObjectType, bool &MayBePseudoDestructor) { // Since this might be a postfix expression, get rid of ParenListExprs. ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base); if (Result.isInvalid()) return ExprError(); Base = Result.get(); Result = CheckPlaceholderExpr(Base); if (Result.isInvalid()) return ExprError(); Base = Result.get(); QualType BaseType = Base->getType(); MayBePseudoDestructor = false; if (BaseType->isDependentType()) { // If we have a pointer to a dependent type and are using the -> operator, // the object type is the type that the pointer points to. We might still // have enough information about that type to do something useful. if (OpKind == tok::arrow) if (const PointerType *Ptr = BaseType->getAs()) BaseType = Ptr->getPointeeType(); ObjectType = ParsedType::make(BaseType); MayBePseudoDestructor = true; return Base; } // C++ [over.match.oper]p8: // [...] When operator->returns, the operator-> is applied to the value // returned, with the original second operand. if (OpKind == tok::arrow) { QualType StartingType = BaseType; bool NoArrowOperatorFound = false; bool FirstIteration = true; FunctionDecl *CurFD = dyn_cast(CurContext); // The set of types we've considered so far. llvm::SmallPtrSet CTypes; SmallVector OperatorArrows; CTypes.insert(Context.getCanonicalType(BaseType)); while (BaseType->isRecordType()) { if (OperatorArrows.size() >= getLangOpts().ArrowDepth) { Diag(OpLoc, diag::err_operator_arrow_depth_exceeded) << StartingType << getLangOpts().ArrowDepth << Base->getSourceRange(); noteOperatorArrows(*this, OperatorArrows); Diag(OpLoc, diag::note_operator_arrow_depth) << getLangOpts().ArrowDepth; return ExprError(); } Result = BuildOverloadedArrowExpr( S, Base, OpLoc, // When in a template specialization and on the first loop iteration, // potentially give the default diagnostic (with the fixit in a // separate note) instead of having the error reported back to here // and giving a diagnostic with a fixit attached to the error itself. (FirstIteration && CurFD && CurFD->isFunctionTemplateSpecialization()) ? nullptr : &NoArrowOperatorFound); if (Result.isInvalid()) { if (NoArrowOperatorFound) { if (FirstIteration) { Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) << BaseType << 1 << Base->getSourceRange() << FixItHint::CreateReplacement(OpLoc, "."); OpKind = tok::period; break; } Diag(OpLoc, diag::err_typecheck_member_reference_arrow) << BaseType << Base->getSourceRange(); CallExpr *CE = dyn_cast(Base); if (Decl *CD = (CE ? CE->getCalleeDecl() : nullptr)) { Diag(CD->getBeginLoc(), diag::note_member_reference_arrow_from_operator_arrow); } } return ExprError(); } Base = Result.get(); if (CXXOperatorCallExpr *OpCall = dyn_cast(Base)) OperatorArrows.push_back(OpCall->getDirectCallee()); BaseType = Base->getType(); CanQualType CBaseType = Context.getCanonicalType(BaseType); if (!CTypes.insert(CBaseType).second) { Diag(OpLoc, diag::err_operator_arrow_circular) << StartingType; noteOperatorArrows(*this, OperatorArrows); return ExprError(); } FirstIteration = false; } if (OpKind == tok::arrow) { if (BaseType->isPointerType()) BaseType = BaseType->getPointeeType(); else if (auto *AT = Context.getAsArrayType(BaseType)) BaseType = AT->getElementType(); } } // Objective-C properties allow "." access on Objective-C pointer types, // so adjust the base type to the object type itself. if (BaseType->isObjCObjectPointerType()) BaseType = BaseType->getPointeeType(); // C++ [basic.lookup.classref]p2: // [...] If the type of the object expression is of pointer to scalar // type, the unqualified-id is looked up in the context of the complete // postfix-expression. // // This also indicates that we could be parsing a pseudo-destructor-name. // Note that Objective-C class and object types can be pseudo-destructor // expressions or normal member (ivar or property) access expressions, and // it's legal for the type to be incomplete if this is a pseudo-destructor // call. We'll do more incomplete-type checks later in the lookup process, // so just skip this check for ObjC types. if (!BaseType->isRecordType()) { ObjectType = ParsedType::make(BaseType); MayBePseudoDestructor = true; return Base; } // The object type must be complete (or dependent), or // C++11 [expr.prim.general]p3: // Unlike the object expression in other contexts, *this is not required to // be of complete type for purposes of class member access (5.2.5) outside // the member function body. if (!BaseType->isDependentType() && !isThisOutsideMemberFunctionBody(BaseType) && RequireCompleteType(OpLoc, BaseType, diag::err_incomplete_member_access)) return ExprError(); // C++ [basic.lookup.classref]p2: // If the id-expression in a class member access (5.2.5) is an // unqualified-id, and the type of the object expression is of a class // type C (or of pointer to a class type C), the unqualified-id is looked // up in the scope of class C. [...] ObjectType = ParsedType::make(BaseType); return Base; } static bool CheckArrow(Sema& S, QualType& ObjectType, Expr *&Base, tok::TokenKind& OpKind, SourceLocation OpLoc) { if (Base->hasPlaceholderType()) { ExprResult result = S.CheckPlaceholderExpr(Base); if (result.isInvalid()) return true; Base = result.get(); } ObjectType = Base->getType(); // C++ [expr.pseudo]p2: // The left-hand side of the dot operator shall be of scalar type. The // left-hand side of the arrow operator shall be of pointer to scalar type. // This scalar type is the object type. // Note that this is rather different from the normal handling for the // arrow operator. if (OpKind == tok::arrow) { if (const PointerType *Ptr = ObjectType->getAs()) { ObjectType = Ptr->getPointeeType(); } else if (!Base->isTypeDependent()) { // The user wrote "p->" when they probably meant "p."; fix it. S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) << ObjectType << true << FixItHint::CreateReplacement(OpLoc, "."); if (S.isSFINAEContext()) return true; OpKind = tok::period; } } return false; } /// Check if it's ok to try and recover dot pseudo destructor calls on /// pointer objects. static bool canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema &SemaRef, QualType DestructedType) { // If this is a record type, check if its destructor is callable. if (auto *RD = DestructedType->getAsCXXRecordDecl()) { if (RD->hasDefinition()) if (CXXDestructorDecl *D = SemaRef.LookupDestructor(RD)) return SemaRef.CanUseDecl(D, /*TreatUnavailableAsInvalid=*/false); return false; } // Otherwise, check if it's a type for which it's valid to use a pseudo-dtor. return DestructedType->isDependentType() || DestructedType->isScalarType() || DestructedType->isVectorType(); } ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, const CXXScopeSpec &SS, TypeSourceInfo *ScopeTypeInfo, SourceLocation CCLoc, SourceLocation TildeLoc, PseudoDestructorTypeStorage Destructed) { TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo(); QualType ObjectType; if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc)) return ExprError(); if (!ObjectType->isDependentType() && !ObjectType->isScalarType() && !ObjectType->isVectorType()) { if (getLangOpts().MSVCCompat && ObjectType->isVoidType()) Diag(OpLoc, diag::ext_pseudo_dtor_on_void) << Base->getSourceRange(); else { Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar) << ObjectType << Base->getSourceRange(); return ExprError(); } } // C++ [expr.pseudo]p2: // [...] The cv-unqualified versions of the object type and of the type // designated by the pseudo-destructor-name shall be the same type. if (DestructedTypeInfo) { QualType DestructedType = DestructedTypeInfo->getType(); SourceLocation DestructedTypeStart = DestructedTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(); if (!DestructedType->isDependentType() && !ObjectType->isDependentType()) { if (!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) { // Detect dot pseudo destructor calls on pointer objects, e.g.: // Foo *foo; // foo.~Foo(); if (OpKind == tok::period && ObjectType->isPointerType() && Context.hasSameUnqualifiedType(DestructedType, ObjectType->getPointeeType())) { auto Diagnostic = Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) << ObjectType << /*IsArrow=*/0 << Base->getSourceRange(); // Issue a fixit only when the destructor is valid. if (canRecoverDotPseudoDestructorCallsOnPointerObjects( *this, DestructedType)) Diagnostic << FixItHint::CreateReplacement(OpLoc, "->"); // Recover by setting the object type to the destructed type and the // operator to '->'. ObjectType = DestructedType; OpKind = tok::arrow; } else { Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch) << ObjectType << DestructedType << Base->getSourceRange() << DestructedTypeInfo->getTypeLoc().getLocalSourceRange(); // Recover by setting the destructed type to the object type. DestructedType = ObjectType; DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart); Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo); } } else if (DestructedType.getObjCLifetime() != ObjectType.getObjCLifetime()) { if (DestructedType.getObjCLifetime() == Qualifiers::OCL_None) { // Okay: just pretend that the user provided the correctly-qualified // type. } else { Diag(DestructedTypeStart, diag::err_arc_pseudo_dtor_inconstant_quals) << ObjectType << DestructedType << Base->getSourceRange() << DestructedTypeInfo->getTypeLoc().getLocalSourceRange(); } // Recover by setting the destructed type to the object type. DestructedType = ObjectType; DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart); Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo); } } } // C++ [expr.pseudo]p2: // [...] Furthermore, the two type-names in a pseudo-destructor-name of the // form // // ::[opt] nested-name-specifier[opt] type-name :: ~ type-name // // shall designate the same scalar type. if (ScopeTypeInfo) { QualType ScopeType = ScopeTypeInfo->getType(); if (!ScopeType->isDependentType() && !ObjectType->isDependentType() && !Context.hasSameUnqualifiedType(ScopeType, ObjectType)) { Diag(ScopeTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(), diag::err_pseudo_dtor_type_mismatch) << ObjectType << ScopeType << Base->getSourceRange() << ScopeTypeInfo->getTypeLoc().getLocalSourceRange(); ScopeType = QualType(); ScopeTypeInfo = nullptr; } } Expr *Result = new (Context) CXXPseudoDestructorExpr(Context, Base, OpKind == tok::arrow, OpLoc, SS.getWithLocInContext(Context), ScopeTypeInfo, CCLoc, TildeLoc, Destructed); return Result; } ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, UnqualifiedId &FirstTypeName, SourceLocation CCLoc, SourceLocation TildeLoc, UnqualifiedId &SecondTypeName) { assert((FirstTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId || FirstTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) && "Invalid first type name in pseudo-destructor"); assert((SecondTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId || SecondTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) && "Invalid second type name in pseudo-destructor"); QualType ObjectType; if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc)) return ExprError(); // Compute the object type that we should use for name lookup purposes. Only // record types and dependent types matter. ParsedType ObjectTypePtrForLookup; if (!SS.isSet()) { if (ObjectType->isRecordType()) ObjectTypePtrForLookup = ParsedType::make(ObjectType); else if (ObjectType->isDependentType()) ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy); } // Convert the name of the type being destructed (following the ~) into a // type (with source-location information). QualType DestructedType; TypeSourceInfo *DestructedTypeInfo = nullptr; PseudoDestructorTypeStorage Destructed; if (SecondTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) { ParsedType T = getTypeName(*SecondTypeName.Identifier, SecondTypeName.StartLocation, S, &SS, true, false, ObjectTypePtrForLookup, /*IsCtorOrDtorName*/true); if (!T && ((SS.isSet() && !computeDeclContext(SS, false)) || (!SS.isSet() && ObjectType->isDependentType()))) { // The name of the type being destroyed is a dependent name, and we // couldn't find anything useful in scope. Just store the identifier and // it's location, and we'll perform (qualified) name lookup again at // template instantiation time. Destructed = PseudoDestructorTypeStorage(SecondTypeName.Identifier, SecondTypeName.StartLocation); } else if (!T) { Diag(SecondTypeName.StartLocation, diag::err_pseudo_dtor_destructor_non_type) << SecondTypeName.Identifier << ObjectType; if (isSFINAEContext()) return ExprError(); // Recover by assuming we had the right type all along. DestructedType = ObjectType; } else DestructedType = GetTypeFromParser(T, &DestructedTypeInfo); } else { // Resolve the template-id to a type. TemplateIdAnnotation *TemplateId = SecondTypeName.TemplateId; ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), TemplateId->NumArgs); TypeResult T = ActOnTemplateIdType(S, SS, TemplateId->TemplateKWLoc, TemplateId->Template, TemplateId->Name, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc, /*IsCtorOrDtorName*/true); if (T.isInvalid() || !T.get()) { // Recover by assuming we had the right type all along. DestructedType = ObjectType; } else DestructedType = GetTypeFromParser(T.get(), &DestructedTypeInfo); } // If we've performed some kind of recovery, (re-)build the type source // information. if (!DestructedType.isNull()) { if (!DestructedTypeInfo) DestructedTypeInfo = Context.getTrivialTypeSourceInfo(DestructedType, SecondTypeName.StartLocation); Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo); } // Convert the name of the scope type (the type prior to '::') into a type. TypeSourceInfo *ScopeTypeInfo = nullptr; QualType ScopeType; if (FirstTypeName.getKind() == UnqualifiedIdKind::IK_TemplateId || FirstTypeName.Identifier) { if (FirstTypeName.getKind() == UnqualifiedIdKind::IK_Identifier) { ParsedType T = getTypeName(*FirstTypeName.Identifier, FirstTypeName.StartLocation, S, &SS, true, false, ObjectTypePtrForLookup, /*IsCtorOrDtorName*/true); if (!T) { Diag(FirstTypeName.StartLocation, diag::err_pseudo_dtor_destructor_non_type) << FirstTypeName.Identifier << ObjectType; if (isSFINAEContext()) return ExprError(); // Just drop this type. It's unnecessary anyway. ScopeType = QualType(); } else ScopeType = GetTypeFromParser(T, &ScopeTypeInfo); } else { // Resolve the template-id to a type. TemplateIdAnnotation *TemplateId = FirstTypeName.TemplateId; ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), TemplateId->NumArgs); TypeResult T = ActOnTemplateIdType(S, SS, TemplateId->TemplateKWLoc, TemplateId->Template, TemplateId->Name, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc, /*IsCtorOrDtorName*/true); if (T.isInvalid() || !T.get()) { // Recover by dropping this type. ScopeType = QualType(); } else ScopeType = GetTypeFromParser(T.get(), &ScopeTypeInfo); } } if (!ScopeType.isNull() && !ScopeTypeInfo) ScopeTypeInfo = Context.getTrivialTypeSourceInfo(ScopeType, FirstTypeName.StartLocation); return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, SS, ScopeTypeInfo, CCLoc, TildeLoc, Destructed); } ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, SourceLocation TildeLoc, const DeclSpec& DS) { QualType ObjectType; if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc)) return ExprError(); QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc(), false); TypeLocBuilder TLB; DecltypeTypeLoc DecltypeTL = TLB.push(T); DecltypeTL.setNameLoc(DS.getTypeSpecTypeLoc()); TypeSourceInfo *DestructedTypeInfo = TLB.getTypeSourceInfo(Context, T); PseudoDestructorTypeStorage Destructed(DestructedTypeInfo); return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, CXXScopeSpec(), nullptr, SourceLocation(), TildeLoc, Destructed); } ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, CXXConversionDecl *Method, bool HadMultipleCandidates) { // Convert the expression to match the conversion function's implicit object // parameter. ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/nullptr, FoundDecl, Method); if (Exp.isInvalid()) return true; if (Method->getParent()->isLambda() && Method->getConversionType()->isBlockPointerType()) { // This is a lambda conversion to block pointer; check if the argument // was a LambdaExpr. Expr *SubE = E; CastExpr *CE = dyn_cast(SubE); if (CE && CE->getCastKind() == CK_NoOp) SubE = CE->getSubExpr(); SubE = SubE->IgnoreParens(); if (CXXBindTemporaryExpr *BE = dyn_cast(SubE)) SubE = BE->getSubExpr(); if (isa(SubE)) { // For the conversion to block pointer on a lambda expression, we // construct a special BlockLiteral instead; this doesn't really make // a difference in ARC, but outside of ARC the resulting block literal // follows the normal lifetime rules for block literals instead of being // autoreleased. DiagnosticErrorTrap Trap(Diags); PushExpressionEvaluationContext( ExpressionEvaluationContext::PotentiallyEvaluated); ExprResult BlockExp = BuildBlockForLambdaConversion( Exp.get()->getExprLoc(), Exp.get()->getExprLoc(), Method, Exp.get()); PopExpressionEvaluationContext(); if (BlockExp.isInvalid()) Diag(Exp.get()->getExprLoc(), diag::note_lambda_to_block_conv); return BlockExp; } } MemberExpr *ME = BuildMemberExpr(Exp.get(), /*IsArrow=*/false, SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), Method, DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()), HadMultipleCandidates, DeclarationNameInfo(), Context.BoundMemberTy, VK_RValue, OK_Ordinary); QualType ResultType = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultType); ResultType = ResultType.getNonLValueExprType(Context); CXXMemberCallExpr *CE = CXXMemberCallExpr::Create( Context, ME, /*Args=*/{}, ResultType, VK, Exp.get()->getEndLoc()); if (CheckFunctionCall(Method, CE, Method->getType()->castAs())) return ExprError(); return CE; } ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, SourceLocation RParen) { // If the operand is an unresolved lookup expression, the expression is ill- // formed per [over.over]p1, because overloaded function names cannot be used // without arguments except in explicit contexts. ExprResult R = CheckPlaceholderExpr(Operand); if (R.isInvalid()) return R; R = CheckUnevaluatedOperand(R.get()); if (R.isInvalid()) return ExprError(); Operand = R.get(); if (!inTemplateInstantiation() && Operand->HasSideEffects(Context, false)) { // The expression operand for noexcept is in an unevaluated expression // context, so side effects could result in unintended consequences. Diag(Operand->getExprLoc(), diag::warn_side_effects_unevaluated_context); } CanThrowResult CanThrow = canThrow(Operand); return new (Context) CXXNoexceptExpr(Context.BoolTy, Operand, CanThrow, KeyLoc, RParen); } ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation, Expr *Operand, SourceLocation RParen) { return BuildCXXNoexceptExpr(KeyLoc, Operand, RParen); } static bool IsSpecialDiscardedValue(Expr *E) { // In C++11, discarded-value expressions of a certain form are special, // according to [expr]p10: // The lvalue-to-rvalue conversion (4.1) is applied only if the // expression is an lvalue of volatile-qualified type and it has // one of the following forms: E = E->IgnoreParens(); // - id-expression (5.1.1), if (isa(E)) return true; // - subscripting (5.2.1), if (isa(E)) return true; // - class member access (5.2.5), if (isa(E)) return true; // - indirection (5.3.1), if (UnaryOperator *UO = dyn_cast(E)) if (UO->getOpcode() == UO_Deref) return true; if (BinaryOperator *BO = dyn_cast(E)) { // - pointer-to-member operation (5.5), if (BO->isPtrMemOp()) return true; // - comma expression (5.18) where the right operand is one of the above. if (BO->getOpcode() == BO_Comma) return IsSpecialDiscardedValue(BO->getRHS()); } // - conditional expression (5.16) where both the second and the third // operands are one of the above, or if (ConditionalOperator *CO = dyn_cast(E)) return IsSpecialDiscardedValue(CO->getTrueExpr()) && IsSpecialDiscardedValue(CO->getFalseExpr()); // The related edge case of "*x ?: *x". if (BinaryConditionalOperator *BCO = dyn_cast(E)) { if (OpaqueValueExpr *OVE = dyn_cast(BCO->getTrueExpr())) return IsSpecialDiscardedValue(OVE->getSourceExpr()) && IsSpecialDiscardedValue(BCO->getFalseExpr()); } // Objective-C++ extensions to the rule. if (isa(E) || isa(E)) return true; return false; } /// Perform the conversions required for an expression used in a /// context that ignores the result. ExprResult Sema::IgnoredValueConversions(Expr *E) { if (E->hasPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(E); if (result.isInvalid()) return E; E = result.get(); } // C99 6.3.2.1: // [Except in specific positions,] an lvalue that does not have // array type is converted to the value stored in the // designated object (and is no longer an lvalue). if (E->isRValue()) { // In C, function designators (i.e. expressions of function type) // are r-values, but we still want to do function-to-pointer decay // on them. This is both technically correct and convenient for // some clients. if (!getLangOpts().CPlusPlus && E->getType()->isFunctionType()) return DefaultFunctionArrayConversion(E); return E; } if (getLangOpts().CPlusPlus) { // The C++11 standard defines the notion of a discarded-value expression; // normally, we don't need to do anything to handle it, but if it is a // volatile lvalue with a special form, we perform an lvalue-to-rvalue // conversion. if (getLangOpts().CPlusPlus11 && E->isGLValue() && E->getType().isVolatileQualified()) { if (IsSpecialDiscardedValue(E)) { ExprResult Res = DefaultLvalueConversion(E); if (Res.isInvalid()) return E; E = Res.get(); } else { // Per C++2a [expr.ass]p5, a volatile assignment is not deprecated if // it occurs as a discarded-value expression. CheckUnusedVolatileAssignment(E); } } // C++1z: // If the expression is a prvalue after this optional conversion, the // temporary materialization conversion is applied. // // We skip this step: IR generation is able to synthesize the storage for // itself in the aggregate case, and adding the extra node to the AST is // just clutter. // FIXME: We don't emit lifetime markers for the temporaries due to this. // FIXME: Do any other AST consumers care about this? return E; } // GCC seems to also exclude expressions of incomplete enum type. if (const EnumType *T = E->getType()->getAs()) { if (!T->getDecl()->isComplete()) { // FIXME: stupid workaround for a codegen bug! E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get(); return E; } } ExprResult Res = DefaultFunctionArrayLvalueConversion(E); if (Res.isInvalid()) return E; E = Res.get(); if (!E->getType()->isVoidType()) RequireCompleteType(E->getExprLoc(), E->getType(), diag::err_incomplete_type); return E; } ExprResult Sema::CheckUnevaluatedOperand(Expr *E) { // Per C++2a [expr.ass]p5, a volatile assignment is not deprecated if // it occurs as an unevaluated operand. CheckUnusedVolatileAssignment(E); return E; } // If we can unambiguously determine whether Var can never be used // in a constant expression, return true. // - if the variable and its initializer are non-dependent, then // we can unambiguously check if the variable is a constant expression. // - if the initializer is not value dependent - we can determine whether // it can be used to initialize a constant expression. If Init can not // be used to initialize a constant expression we conclude that Var can // never be a constant expression. // - FXIME: if the initializer is dependent, we can still do some analysis and // identify certain cases unambiguously as non-const by using a Visitor: // - such as those that involve odr-use of a ParmVarDecl, involve a new // delete, lambda-expr, dynamic-cast, reinterpret-cast etc... static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var, ASTContext &Context) { if (isa(Var)) return true; const VarDecl *DefVD = nullptr; // If there is no initializer - this can not be a constant expression. if (!Var->getAnyInitializer(DefVD)) return true; assert(DefVD); if (DefVD->isWeak()) return false; EvaluatedStmt *Eval = DefVD->ensureEvaluatedStmt(); Expr *Init = cast(Eval->Value); if (Var->getType()->isDependentType() || Init->isValueDependent()) { // FIXME: Teach the constant evaluator to deal with the non-dependent parts // of value-dependent expressions, and use it here to determine whether the // initializer is a potential constant expression. return false; } return !Var->isUsableInConstantExpressions(Context); } /// Check if the current lambda has any potential captures /// that must be captured by any of its enclosing lambdas that are ready to /// capture. If there is a lambda that can capture a nested /// potential-capture, go ahead and do so. Also, check to see if any /// variables are uncaptureable or do not involve an odr-use so do not /// need to be captured. static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures( Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S) { assert(!S.isUnevaluatedContext()); assert(S.CurContext->isDependentContext()); #ifndef NDEBUG DeclContext *DC = S.CurContext; while (DC && isa(DC)) DC = DC->getParent(); assert( CurrentLSI->CallOperator == DC && "The current call operator must be synchronized with Sema's CurContext"); #endif // NDEBUG const bool IsFullExprInstantiationDependent = FE->isInstantiationDependent(); // All the potentially captureable variables in the current nested // lambda (within a generic outer lambda), must be captured by an // outer lambda that is enclosed within a non-dependent context. CurrentLSI->visitPotentialCaptures([&] (VarDecl *Var, Expr *VarExpr) { // If the variable is clearly identified as non-odr-used and the full // expression is not instantiation dependent, only then do we not // need to check enclosing lambda's for speculative captures. // For e.g.: // Even though 'x' is not odr-used, it should be captured. // int test() { // const int x = 10; // auto L = [=](auto a) { // (void) +x + a; // }; // } if (CurrentLSI->isVariableExprMarkedAsNonODRUsed(VarExpr) && !IsFullExprInstantiationDependent) return; // If we have a capture-capable lambda for the variable, go ahead and // capture the variable in that lambda (and all its enclosing lambdas). if (const Optional Index = getStackIndexOfNearestEnclosingCaptureCapableLambda( S.FunctionScopes, Var, S)) S.MarkCaptureUsedInEnclosingContext(Var, VarExpr->getExprLoc(), Index.getValue()); const bool IsVarNeverAConstantExpression = VariableCanNeverBeAConstantExpression(Var, S.Context); if (!IsFullExprInstantiationDependent || IsVarNeverAConstantExpression) { // This full expression is not instantiation dependent or the variable // can not be used in a constant expression - which means // this variable must be odr-used here, so diagnose a // capture violation early, if the variable is un-captureable. // This is purely for diagnosing errors early. Otherwise, this // error would get diagnosed when the lambda becomes capture ready. QualType CaptureType, DeclRefType; SourceLocation ExprLoc = VarExpr->getExprLoc(); if (S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit, /*EllipsisLoc*/ SourceLocation(), /*BuildAndDiagnose*/false, CaptureType, DeclRefType, nullptr)) { // We will never be able to capture this variable, and we need // to be able to in any and all instantiations, so diagnose it. S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit, /*EllipsisLoc*/ SourceLocation(), /*BuildAndDiagnose*/true, CaptureType, DeclRefType, nullptr); } } }); // Check if 'this' needs to be captured. if (CurrentLSI->hasPotentialThisCapture()) { // If we have a capture-capable lambda for 'this', go ahead and capture // 'this' in that lambda (and all its enclosing lambdas). if (const Optional Index = getStackIndexOfNearestEnclosingCaptureCapableLambda( S.FunctionScopes, /*0 is 'this'*/ nullptr, S)) { const unsigned FunctionScopeIndexOfCapturableLambda = Index.getValue(); S.CheckCXXThisCapture(CurrentLSI->PotentialThisCaptureLocation, /*Explicit*/ false, /*BuildAndDiagnose*/ true, &FunctionScopeIndexOfCapturableLambda); } } // Reset all the potential captures at the end of each full-expression. CurrentLSI->clearPotentialCaptures(); } static ExprResult attemptRecovery(Sema &SemaRef, const TypoCorrectionConsumer &Consumer, const TypoCorrection &TC) { LookupResult R(SemaRef, Consumer.getLookupResult().getLookupNameInfo(), Consumer.getLookupResult().getLookupKind()); const CXXScopeSpec *SS = Consumer.getSS(); CXXScopeSpec NewSS; // Use an approprate CXXScopeSpec for building the expr. if (auto *NNS = TC.getCorrectionSpecifier()) NewSS.MakeTrivial(SemaRef.Context, NNS, TC.getCorrectionRange()); else if (SS && !TC.WillReplaceSpecifier()) NewSS = *SS; if (auto *ND = TC.getFoundDecl()) { R.setLookupName(ND->getDeclName()); R.addDecl(ND); if (ND->isCXXClassMember()) { // Figure out the correct naming class to add to the LookupResult. CXXRecordDecl *Record = nullptr; if (auto *NNS = TC.getCorrectionSpecifier()) Record = NNS->getAsType()->getAsCXXRecordDecl(); if (!Record) Record = dyn_cast(ND->getDeclContext()->getRedeclContext()); if (Record) R.setNamingClass(Record); // Detect and handle the case where the decl might be an implicit // member. bool MightBeImplicitMember; if (!Consumer.isAddressOfOperand()) MightBeImplicitMember = true; else if (!NewSS.isEmpty()) MightBeImplicitMember = false; else if (R.isOverloadedResult()) MightBeImplicitMember = false; else if (R.isUnresolvableResult()) MightBeImplicitMember = true; else MightBeImplicitMember = isa(ND) || isa(ND) || isa(ND); if (MightBeImplicitMember) return SemaRef.BuildPossibleImplicitMemberExpr( NewSS, /*TemplateKWLoc*/ SourceLocation(), R, /*TemplateArgs*/ nullptr, /*S*/ nullptr); } else if (auto *Ivar = dyn_cast(ND)) { return SemaRef.LookupInObjCMethod(R, Consumer.getScope(), Ivar->getIdentifier()); } } return SemaRef.BuildDeclarationNameExpr(NewSS, R, /*NeedsADL*/ false, /*AcceptInvalidDecl*/ true); } namespace { class FindTypoExprs : public RecursiveASTVisitor { llvm::SmallSetVector &TypoExprs; public: explicit FindTypoExprs(llvm::SmallSetVector &TypoExprs) : TypoExprs(TypoExprs) {} bool VisitTypoExpr(TypoExpr *TE) { TypoExprs.insert(TE); return true; } }; class TransformTypos : public TreeTransform { typedef TreeTransform BaseTransform; VarDecl *InitDecl; // A decl to avoid as a correction because it is in the // process of being initialized. llvm::function_ref ExprFilter; llvm::SmallSetVector TypoExprs, AmbiguousTypoExprs; llvm::SmallDenseMap TransformCache; llvm::SmallDenseMap OverloadResolution; /// Emit diagnostics for all of the TypoExprs encountered. /// /// If the TypoExprs were successfully corrected, then the diagnostics should /// suggest the corrections. Otherwise the diagnostics will not suggest /// anything (having been passed an empty TypoCorrection). /// /// If we've failed to correct due to ambiguous corrections, we need to /// be sure to pass empty corrections and replacements. Otherwise it's /// possible that the Consumer has a TypoCorrection that failed to ambiguity /// and we don't want to report those diagnostics. void EmitAllDiagnostics(bool IsAmbiguous) { for (TypoExpr *TE : TypoExprs) { auto &State = SemaRef.getTypoExprState(TE); if (State.DiagHandler) { TypoCorrection TC = IsAmbiguous ? TypoCorrection() : State.Consumer->getCurrentCorrection(); ExprResult Replacement = IsAmbiguous ? ExprError() : TransformCache[TE]; // Extract the NamedDecl from the transformed TypoExpr and add it to the // TypoCorrection, replacing the existing decls. This ensures the right // NamedDecl is used in diagnostics e.g. in the case where overload // resolution was used to select one from several possible decls that // had been stored in the TypoCorrection. if (auto *ND = getDeclFromExpr( Replacement.isInvalid() ? nullptr : Replacement.get())) TC.setCorrectionDecl(ND); State.DiagHandler(TC); } SemaRef.clearDelayedTypo(TE); } } /// If corrections for the first TypoExpr have been exhausted for a /// given combination of the other TypoExprs, retry those corrections against /// the next combination of substitutions for the other TypoExprs by advancing /// to the next potential correction of the second TypoExpr. For the second /// and subsequent TypoExprs, if its stream of corrections has been exhausted, /// the stream is reset and the next TypoExpr's stream is advanced by one (a /// TypoExpr's correction stream is advanced by removing the TypoExpr from the /// TransformCache). Returns true if there is still any untried combinations /// of corrections. bool CheckAndAdvanceTypoExprCorrectionStreams() { for (auto TE : TypoExprs) { auto &State = SemaRef.getTypoExprState(TE); TransformCache.erase(TE); if (!State.Consumer->finished()) return true; State.Consumer->resetCorrectionStream(); } return false; } NamedDecl *getDeclFromExpr(Expr *E) { if (auto *OE = dyn_cast_or_null(E)) E = OverloadResolution[OE]; if (!E) return nullptr; if (auto *DRE = dyn_cast(E)) return DRE->getFoundDecl(); if (auto *ME = dyn_cast(E)) return ME->getFoundDecl(); // FIXME: Add any other expr types that could be be seen by the delayed typo // correction TreeTransform for which the corresponding TypoCorrection could // contain multiple decls. return nullptr; } ExprResult TryTransform(Expr *E) { Sema::SFINAETrap Trap(SemaRef); ExprResult Res = TransformExpr(E); if (Trap.hasErrorOccurred() || Res.isInvalid()) return ExprError(); return ExprFilter(Res.get()); } // Since correcting typos may intoduce new TypoExprs, this function // checks for new TypoExprs and recurses if it finds any. Note that it will // only succeed if it is able to correct all typos in the given expression. ExprResult CheckForRecursiveTypos(ExprResult Res, bool &IsAmbiguous) { if (Res.isInvalid()) { return Res; } // Check to see if any new TypoExprs were created. If so, we need to recurse // to check their validity. Expr *FixedExpr = Res.get(); auto SavedTypoExprs = std::move(TypoExprs); auto SavedAmbiguousTypoExprs = std::move(AmbiguousTypoExprs); TypoExprs.clear(); AmbiguousTypoExprs.clear(); FindTypoExprs(TypoExprs).TraverseStmt(FixedExpr); if (!TypoExprs.empty()) { // Recurse to handle newly created TypoExprs. If we're not able to // handle them, discard these TypoExprs. ExprResult RecurResult = RecursiveTransformLoop(FixedExpr, IsAmbiguous); if (RecurResult.isInvalid()) { Res = ExprError(); // Recursive corrections didn't work, wipe them away and don't add // them to the TypoExprs set. Remove them from Sema's TypoExpr list // since we don't want to clear them twice. Note: it's possible the // TypoExprs were created recursively and thus won't be in our // Sema's TypoExprs - they were created in our `RecursiveTransformLoop`. auto &SemaTypoExprs = SemaRef.TypoExprs; for (auto TE : TypoExprs) { TransformCache.erase(TE); SemaRef.clearDelayedTypo(TE); auto SI = find(SemaTypoExprs, TE); if (SI != SemaTypoExprs.end()) { SemaTypoExprs.erase(SI); } } } else { // TypoExpr is valid: add newly created TypoExprs since we were // able to correct them. Res = RecurResult; SavedTypoExprs.set_union(TypoExprs); } } TypoExprs = std::move(SavedTypoExprs); AmbiguousTypoExprs = std::move(SavedAmbiguousTypoExprs); return Res; } // Try to transform the given expression, looping through the correction // candidates with `CheckAndAdvanceTypoExprCorrectionStreams`. // // If valid ambiguous typo corrections are seen, `IsAmbiguous` is set to // true and this method immediately will return an `ExprError`. ExprResult RecursiveTransformLoop(Expr *E, bool &IsAmbiguous) { ExprResult Res; auto SavedTypoExprs = std::move(SemaRef.TypoExprs); SemaRef.TypoExprs.clear(); while (true) { Res = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous); // Recursion encountered an ambiguous correction. This means that our // correction itself is ambiguous, so stop now. if (IsAmbiguous) break; // If the transform is still valid after checking for any new typos, // it's good to go. if (!Res.isInvalid()) break; // The transform was invalid, see if we have any TypoExprs with untried // correction candidates. if (!CheckAndAdvanceTypoExprCorrectionStreams()) break; } // If we found a valid result, double check to make sure it's not ambiguous. if (!IsAmbiguous && !Res.isInvalid() && !AmbiguousTypoExprs.empty()) { auto SavedTransformCache = llvm::SmallDenseMap(TransformCache); // Ensure none of the TypoExprs have multiple typo correction candidates // with the same edit length that pass all the checks and filters. while (!AmbiguousTypoExprs.empty()) { auto TE = AmbiguousTypoExprs.back(); // TryTransform itself can create new Typos, adding them to the TypoExpr map // and invalidating our TypoExprState, so always fetch it instead of storing. SemaRef.getTypoExprState(TE).Consumer->saveCurrentPosition(); TypoCorrection TC = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection(); TypoCorrection Next; do { // Fetch the next correction by erasing the typo from the cache and calling // `TryTransform` which will iterate through corrections in // `TransformTypoExpr`. TransformCache.erase(TE); ExprResult AmbigRes = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous); if (!AmbigRes.isInvalid() || IsAmbiguous) { SemaRef.getTypoExprState(TE).Consumer->resetCorrectionStream(); SavedTransformCache.erase(TE); Res = ExprError(); IsAmbiguous = true; break; } } while ((Next = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection()) && Next.getEditDistance(false) == TC.getEditDistance(false)); if (IsAmbiguous) break; AmbiguousTypoExprs.remove(TE); SemaRef.getTypoExprState(TE).Consumer->restoreSavedPosition(); } TransformCache = std::move(SavedTransformCache); } // Wipe away any newly created TypoExprs that we don't know about. Since we // clear any invalid TypoExprs in `CheckForRecursiveTypos`, this is only // possible if a `TypoExpr` is created during a transformation but then // fails before we can discover it. auto &SemaTypoExprs = SemaRef.TypoExprs; for (auto Iterator = SemaTypoExprs.begin(); Iterator != SemaTypoExprs.end();) { auto TE = *Iterator; auto FI = find(TypoExprs, TE); if (FI != TypoExprs.end()) { Iterator++; continue; } SemaRef.clearDelayedTypo(TE); Iterator = SemaTypoExprs.erase(Iterator); } SemaRef.TypoExprs = std::move(SavedTypoExprs); return Res; } public: TransformTypos(Sema &SemaRef, VarDecl *InitDecl, llvm::function_ref Filter) : BaseTransform(SemaRef), InitDecl(InitDecl), ExprFilter(Filter) {} ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig = nullptr) { auto Result = BaseTransform::RebuildCallExpr(Callee, LParenLoc, Args, RParenLoc, ExecConfig); if (auto *OE = dyn_cast(Callee)) { if (Result.isUsable()) { Expr *ResultCall = Result.get(); if (auto *BE = dyn_cast(ResultCall)) ResultCall = BE->getSubExpr(); if (auto *CE = dyn_cast(ResultCall)) OverloadResolution[OE] = CE->getCallee(); } } return Result; } ExprResult TransformLambdaExpr(LambdaExpr *E) { return Owned(E); } ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); } ExprResult Transform(Expr *E) { bool IsAmbiguous = false; ExprResult Res = RecursiveTransformLoop(E, IsAmbiguous); if (!Res.isUsable()) FindTypoExprs(TypoExprs).TraverseStmt(E); EmitAllDiagnostics(IsAmbiguous); return Res; } ExprResult TransformTypoExpr(TypoExpr *E) { // If the TypoExpr hasn't been seen before, record it. Otherwise, return the // cached transformation result if there is one and the TypoExpr isn't the // first one that was encountered. auto &CacheEntry = TransformCache[E]; if (!TypoExprs.insert(E) && !CacheEntry.isUnset()) { return CacheEntry; } auto &State = SemaRef.getTypoExprState(E); assert(State.Consumer && "Cannot transform a cleared TypoExpr"); // For the first TypoExpr and an uncached TypoExpr, find the next likely // typo correction and return it. while (TypoCorrection TC = State.Consumer->getNextCorrection()) { if (InitDecl && TC.getFoundDecl() == InitDecl) continue; // FIXME: If we would typo-correct to an invalid declaration, it's // probably best to just suppress all errors from this typo correction. ExprResult NE = State.RecoveryHandler ? State.RecoveryHandler(SemaRef, E, TC) : attemptRecovery(SemaRef, *State.Consumer, TC); if (!NE.isInvalid()) { // Check whether there may be a second viable correction with the same // edit distance; if so, remember this TypoExpr may have an ambiguous // correction so it can be more thoroughly vetted later. TypoCorrection Next; if ((Next = State.Consumer->peekNextCorrection()) && Next.getEditDistance(false) == TC.getEditDistance(false)) { AmbiguousTypoExprs.insert(E); } else { AmbiguousTypoExprs.remove(E); } assert(!NE.isUnset() && "Typo was transformed into a valid-but-null ExprResult"); return CacheEntry = NE; } } return CacheEntry = ExprError(); } }; } ExprResult Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl, llvm::function_ref Filter) { // If the current evaluation context indicates there are uncorrected typos // and the current expression isn't guaranteed to not have typos, try to // resolve any TypoExpr nodes that might be in the expression. if (E && !ExprEvalContexts.empty() && ExprEvalContexts.back().NumTypos && (E->isTypeDependent() || E->isValueDependent() || E->isInstantiationDependent())) { auto TyposResolved = DelayedTypos.size(); auto Result = TransformTypos(*this, InitDecl, Filter).Transform(E); TyposResolved -= DelayedTypos.size(); if (Result.isInvalid() || Result.get() != E) { ExprEvalContexts.back().NumTypos -= TyposResolved; return Result; } assert(TyposResolved == 0 && "Corrected typo but got same Expr back?"); } return E; } ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, bool DiscardedValue, bool IsConstexpr) { ExprResult FullExpr = FE; if (!FullExpr.get()) return ExprError(); if (DiagnoseUnexpandedParameterPack(FullExpr.get())) return ExprError(); if (DiscardedValue) { // Top-level expressions default to 'id' when we're in a debugger. if (getLangOpts().DebuggerCastResultToId && FullExpr.get()->getType() == Context.UnknownAnyTy) { FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType()); if (FullExpr.isInvalid()) return ExprError(); } FullExpr = CheckPlaceholderExpr(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); FullExpr = IgnoredValueConversions(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); DiagnoseUnusedExprResult(FullExpr.get()); } FullExpr = CorrectDelayedTyposInExpr(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); CheckCompletedExpr(FullExpr.get(), CC, IsConstexpr); // At the end of this full expression (which could be a deeply nested // lambda), if there is a potential capture within the nested lambda, // have the outer capture-able lambda try and capture it. // Consider the following code: // void f(int, int); // void f(const int&, double); // void foo() { // const int x = 10, y = 20; // auto L = [=](auto a) { // auto M = [=](auto b) { // f(x, b); <-- requires x to be captured by L and M // f(y, a); <-- requires y to be captured by L, but not all Ms // }; // }; // } // FIXME: Also consider what happens for something like this that involves // the gnu-extension statement-expressions or even lambda-init-captures: // void f() { // const int n = 0; // auto L = [&](auto a) { // +n + ({ 0; a; }); // }; // } // // Here, we see +n, and then the full-expression 0; ends, so we don't // capture n (and instead remove it from our list of potential captures), // and then the full-expression +n + ({ 0; }); ends, but it's too late // for us to see that we need to capture n after all. LambdaScopeInfo *const CurrentLSI = getCurLambda(/*IgnoreCapturedRegions=*/true); // FIXME: PR 17877 showed that getCurLambda() can return a valid pointer // even if CurContext is not a lambda call operator. Refer to that Bug Report // for an example of the code that might cause this asynchrony. // By ensuring we are in the context of a lambda's call operator // we can fix the bug (we only need to check whether we need to capture // if we are within a lambda's body); but per the comments in that // PR, a proper fix would entail : // "Alternative suggestion: // - Add to Sema an integer holding the smallest (outermost) scope // index that we are *lexically* within, and save/restore/set to // FunctionScopes.size() in InstantiatingTemplate's // constructor/destructor. // - Teach the handful of places that iterate over FunctionScopes to // stop at the outermost enclosing lexical scope." DeclContext *DC = CurContext; while (DC && isa(DC)) DC = DC->getParent(); const bool IsInLambdaDeclContext = isLambdaCallOperator(DC); if (IsInLambdaDeclContext && CurrentLSI && CurrentLSI->hasPotentialCaptures() && !FullExpr.isInvalid()) CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(FE, CurrentLSI, *this); return MaybeCreateExprWithCleanups(FullExpr); } StmtResult Sema::ActOnFinishFullStmt(Stmt *FullStmt) { if (!FullStmt) return StmtError(); return MaybeCreateStmtWithCleanups(FullStmt); } Sema::IfExistsResult Sema::CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS, const DeclarationNameInfo &TargetNameInfo) { DeclarationName TargetName = TargetNameInfo.getName(); if (!TargetName) return IER_DoesNotExist; // If the name itself is dependent, then the result is dependent. if (TargetName.isDependentName()) return IER_Dependent; // Do the redeclaration lookup in the current scope. LookupResult R(*this, TargetNameInfo, Sema::LookupAnyName, Sema::NotForRedeclaration); LookupParsedName(R, S, &SS); R.suppressDiagnostics(); switch (R.getResultKind()) { case LookupResult::Found: case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: case LookupResult::Ambiguous: return IER_Exists; case LookupResult::NotFound: return IER_DoesNotExist; case LookupResult::NotFoundInCurrentInstantiation: return IER_Dependent; } llvm_unreachable("Invalid LookupResult Kind!"); } Sema::IfExistsResult Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc, bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name) { DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name); // Check for an unexpanded parameter pack. auto UPPC = IsIfExists ? UPPC_IfExists : UPPC_IfNotExists; if (DiagnoseUnexpandedParameterPack(SS, UPPC) || DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC)) return IER_Error; return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo); } concepts::Requirement *Sema::ActOnSimpleRequirement(Expr *E) { return BuildExprRequirement(E, /*IsSimple=*/true, /*NoexceptLoc=*/SourceLocation(), /*ReturnTypeRequirement=*/{}); } concepts::Requirement * Sema::ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc, IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId) { assert(((!TypeName && TemplateId) || (TypeName && !TemplateId)) && "Exactly one of TypeName and TemplateId must be specified."); TypeSourceInfo *TSI = nullptr; if (TypeName) { QualType T = CheckTypenameType(ETK_Typename, TypenameKWLoc, SS.getWithLocInContext(Context), *TypeName, NameLoc, &TSI, /*DeducedTypeContext=*/false); if (T.isNull()) return nullptr; } else { ASTTemplateArgsPtr ArgsPtr(TemplateId->getTemplateArgs(), TemplateId->NumArgs); TypeResult T = ActOnTypenameType(CurScope, TypenameKWLoc, SS, TemplateId->TemplateKWLoc, TemplateId->Template, TemplateId->Name, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, ArgsPtr, TemplateId->RAngleLoc); if (T.isInvalid()) return nullptr; if (GetTypeFromParser(T.get(), &TSI).isNull()) return nullptr; } return BuildTypeRequirement(TSI); } concepts::Requirement * Sema::ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc) { return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc, /*ReturnTypeRequirement=*/{}); } concepts::Requirement * Sema::ActOnCompoundRequirement( Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS, TemplateIdAnnotation *TypeConstraint, unsigned Depth) { // C++2a [expr.prim.req.compound] p1.3.3 // [..] the expression is deduced against an invented function template // F [...] F is a void function template with a single type template // parameter T declared with the constrained-parameter. Form a new // cv-qualifier-seq cv by taking the union of const and volatile specifiers // around the constrained-parameter. F has a single parameter whose // type-specifier is cv T followed by the abstract-declarator. [...] // // The cv part is done in the calling function - we get the concept with // arguments and the abstract declarator with the correct CV qualification and // have to synthesize T and the single parameter of F. auto &II = Context.Idents.get("expr-type"); auto *TParam = TemplateTypeParmDecl::Create(Context, CurContext, SourceLocation(), SourceLocation(), Depth, /*Index=*/0, &II, /*Typename=*/true, /*ParameterPack=*/false, /*HasTypeConstraint=*/true); if (ActOnTypeConstraint(SS, TypeConstraint, TParam, /*EllpsisLoc=*/SourceLocation())) // Just produce a requirement with no type requirements. return BuildExprRequirement(E, /*IsSimple=*/false, NoexceptLoc, {}); auto *TPL = TemplateParameterList::Create(Context, SourceLocation(), SourceLocation(), ArrayRef(TParam), SourceLocation(), /*RequiresClause=*/nullptr); return BuildExprRequirement( E, /*IsSimple=*/false, NoexceptLoc, concepts::ExprRequirement::ReturnTypeRequirement(TPL)); } concepts::ExprRequirement * Sema::BuildExprRequirement( Expr *E, bool IsSimple, SourceLocation NoexceptLoc, concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) { auto Status = concepts::ExprRequirement::SS_Satisfied; ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr; if (E->isInstantiationDependent() || ReturnTypeRequirement.isDependent()) Status = concepts::ExprRequirement::SS_Dependent; else if (NoexceptLoc.isValid() && canThrow(E) == CanThrowResult::CT_Can) Status = concepts::ExprRequirement::SS_NoexceptNotMet; else if (ReturnTypeRequirement.isSubstitutionFailure()) Status = concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure; else if (ReturnTypeRequirement.isTypeConstraint()) { // C++2a [expr.prim.req]p1.3.3 // The immediately-declared constraint ([temp]) of decltype((E)) shall // be satisfied. TemplateParameterList *TPL = ReturnTypeRequirement.getTypeConstraintTemplateParameterList(); QualType MatchedType = BuildDecltypeType(E, E->getBeginLoc()).getCanonicalType(); llvm::SmallVector Args; Args.push_back(TemplateArgument(MatchedType)); TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args); MultiLevelTemplateArgumentList MLTAL(TAL); for (unsigned I = 0; I < TPL->getDepth(); ++I) MLTAL.addOuterRetainedLevel(); Expr *IDC = cast(TPL->getParam(0))->getTypeConstraint() ->getImmediatelyDeclaredConstraint(); ExprResult Constraint = SubstExpr(IDC, MLTAL); assert(!Constraint.isInvalid() && "Substitution cannot fail as it is simply putting a type template " "argument into a concept specialization expression's parameter."); SubstitutedConstraintExpr = cast(Constraint.get()); if (!SubstitutedConstraintExpr->isSatisfied()) Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied; } return new (Context) concepts::ExprRequirement(E, IsSimple, NoexceptLoc, ReturnTypeRequirement, Status, SubstitutedConstraintExpr); } concepts::ExprRequirement * Sema::BuildExprRequirement( concepts::Requirement::SubstitutionDiagnostic *ExprSubstitutionDiagnostic, bool IsSimple, SourceLocation NoexceptLoc, concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) { return new (Context) concepts::ExprRequirement(ExprSubstitutionDiagnostic, IsSimple, NoexceptLoc, ReturnTypeRequirement); } concepts::TypeRequirement * Sema::BuildTypeRequirement(TypeSourceInfo *Type) { return new (Context) concepts::TypeRequirement(Type); } concepts::TypeRequirement * Sema::BuildTypeRequirement( concepts::Requirement::SubstitutionDiagnostic *SubstDiag) { return new (Context) concepts::TypeRequirement(SubstDiag); } concepts::Requirement *Sema::ActOnNestedRequirement(Expr *Constraint) { return BuildNestedRequirement(Constraint); } concepts::NestedRequirement * Sema::BuildNestedRequirement(Expr *Constraint) { ConstraintSatisfaction Satisfaction; if (!Constraint->isInstantiationDependent() && CheckConstraintSatisfaction(nullptr, {Constraint}, /*TemplateArgs=*/{}, Constraint->getSourceRange(), Satisfaction)) return nullptr; return new (Context) concepts::NestedRequirement(Context, Constraint, Satisfaction); } concepts::NestedRequirement * Sema::BuildNestedRequirement( concepts::Requirement::SubstitutionDiagnostic *SubstDiag) { return new (Context) concepts::NestedRequirement(SubstDiag); } RequiresExprBodyDecl * Sema::ActOnStartRequiresExpr(SourceLocation RequiresKWLoc, ArrayRef LocalParameters, Scope *BodyScope) { assert(BodyScope); RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(Context, CurContext, RequiresKWLoc); PushDeclContext(BodyScope, Body); for (ParmVarDecl *Param : LocalParameters) { if (Param->hasDefaultArg()) // C++2a [expr.prim.req] p4 // [...] A local parameter of a requires-expression shall not have a // default argument. [...] Diag(Param->getDefaultArgRange().getBegin(), diag::err_requires_expr_local_parameter_default_argument); // Ignore default argument and move on Param->setDeclContext(Body); // If this has an identifier, add it to the scope stack. if (Param->getIdentifier()) { CheckShadow(BodyScope, Param); PushOnScopeChains(Param, BodyScope); } } return Body; } void Sema::ActOnFinishRequiresExpr() { assert(CurContext && "DeclContext imbalance!"); CurContext = CurContext->getLexicalParent(); assert(CurContext && "Popped translation unit!"); } ExprResult Sema::ActOnRequiresExpr(SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, ArrayRef LocalParameters, ArrayRef Requirements, SourceLocation ClosingBraceLoc) { return RequiresExpr::Create(Context, RequiresKWLoc, Body, LocalParameters, Requirements, ClosingBraceLoc); } Index: stable/12/contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp =================================================================== --- stable/12/contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp (revision 363091) +++ stable/12/contrib/llvm-project/clang/lib/Sema/SemaOverload.cpp (revision 363092) @@ -1,14779 +1,14779 @@ //===--- SemaOverload.cpp - C++ Overloading -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file provides Sema routines for C++ overloading. // //===----------------------------------------------------------------------===// #include "clang/Sema/Overload.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/TypeOrdering.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include #include using namespace clang; using namespace sema; static bool functionHasPassObjectSizeParams(const FunctionDecl *FD) { return llvm::any_of(FD->parameters(), [](const ParmVarDecl *P) { return P->hasAttr(); }); } /// A convenience routine for creating a decayed reference to a function. static ExprResult CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl, const Expr *Base, bool HadMultipleCandidates, SourceLocation Loc = SourceLocation(), const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){ if (S.DiagnoseUseOfDecl(FoundDecl, Loc)) return ExprError(); // If FoundDecl is different from Fn (such as if one is a template // and the other a specialization), make sure DiagnoseUseOfDecl is // called on both. // FIXME: This would be more comprehensively addressed by modifying // DiagnoseUseOfDecl to accept both the FoundDecl and the decl // being used. if (FoundDecl != Fn && S.DiagnoseUseOfDecl(Fn, Loc)) return ExprError(); DeclRefExpr *DRE = new (S.Context) DeclRefExpr(S.Context, Fn, false, Fn->getType(), VK_LValue, Loc, LocInfo); if (HadMultipleCandidates) DRE->setHadMultipleCandidates(true); S.MarkDeclRefReferenced(DRE, Base); if (auto *FPT = DRE->getType()->getAs()) { if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) { S.ResolveExceptionSpec(Loc, FPT); DRE->setType(Fn->getType()); } } return S.ImpCastExprToType(DRE, S.Context.getPointerType(DRE->getType()), CK_FunctionToPointerDecay); } static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle, bool AllowObjCWritebackConversion); static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From, QualType &ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle); static OverloadingResult IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, UserDefinedConversionSequence& User, OverloadCandidateSet& Conversions, bool AllowExplicit, bool AllowObjCConversionOnExplicit); static ImplicitConversionSequence::CompareKind CompareStandardConversionSequences(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2); static ImplicitConversionSequence::CompareKind CompareQualificationConversions(Sema &S, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2); static ImplicitConversionSequence::CompareKind CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2); /// GetConversionRank - Retrieve the implicit conversion rank /// corresponding to the given implicit conversion kind. ImplicitConversionRank clang::GetConversionRank(ImplicitConversionKind Kind) { static const ImplicitConversionRank Rank[(int)ICK_Num_Conversion_Kinds] = { ICR_Exact_Match, ICR_Exact_Match, ICR_Exact_Match, ICR_Exact_Match, ICR_Exact_Match, ICR_Exact_Match, ICR_Promotion, ICR_Promotion, ICR_Promotion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_OCL_Scalar_Widening, ICR_Complex_Real_Conversion, ICR_Conversion, ICR_Conversion, ICR_Writeback_Conversion, ICR_Exact_Match, // NOTE(gbiv): This may not be completely right -- // it was omitted by the patch that added // ICK_Zero_Event_Conversion ICR_C_Conversion, ICR_C_Conversion_Extension }; return Rank[(int)Kind]; } /// GetImplicitConversionName - Return the name of this kind of /// implicit conversion. static const char* GetImplicitConversionName(ImplicitConversionKind Kind) { static const char* const Name[(int)ICK_Num_Conversion_Kinds] = { "No conversion", "Lvalue-to-rvalue", "Array-to-pointer", "Function-to-pointer", "Function pointer conversion", "Qualification", "Integral promotion", "Floating point promotion", "Complex promotion", "Integral conversion", "Floating conversion", "Complex conversion", "Floating-integral conversion", "Pointer conversion", "Pointer-to-member conversion", "Boolean conversion", "Compatible-types conversion", "Derived-to-base conversion", "Vector conversion", "Vector splat", "Complex-real conversion", "Block Pointer conversion", "Transparent Union Conversion", "Writeback conversion", "OpenCL Zero Event Conversion", "C specific type conversion", "Incompatible pointer conversion" }; return Name[Kind]; } /// StandardConversionSequence - Set the standard conversion /// sequence to the identity conversion. void StandardConversionSequence::setAsIdentityConversion() { First = ICK_Identity; Second = ICK_Identity; Third = ICK_Identity; DeprecatedStringLiteralToCharPtr = false; QualificationIncludesObjCLifetime = false; ReferenceBinding = false; DirectBinding = false; IsLvalueReference = true; BindsToFunctionLvalue = false; BindsToRvalue = false; BindsImplicitObjectArgumentWithoutRefQualifier = false; ObjCLifetimeConversionBinding = false; CopyConstructor = nullptr; } /// getRank - Retrieve the rank of this standard conversion sequence /// (C++ 13.3.3.1.1p3). The rank is the largest rank of each of the /// implicit conversions. ImplicitConversionRank StandardConversionSequence::getRank() const { ImplicitConversionRank Rank = ICR_Exact_Match; if (GetConversionRank(First) > Rank) Rank = GetConversionRank(First); if (GetConversionRank(Second) > Rank) Rank = GetConversionRank(Second); if (GetConversionRank(Third) > Rank) Rank = GetConversionRank(Third); return Rank; } /// isPointerConversionToBool - Determines whether this conversion is /// a conversion of a pointer or pointer-to-member to bool. This is /// used as part of the ranking of standard conversion sequences /// (C++ 13.3.3.2p4). bool StandardConversionSequence::isPointerConversionToBool() const { // Note that FromType has not necessarily been transformed by the // array-to-pointer or function-to-pointer implicit conversions, so // check for their presence as well as checking whether FromType is // a pointer. if (getToType(1)->isBooleanType() && (getFromType()->isPointerType() || getFromType()->isMemberPointerType() || getFromType()->isObjCObjectPointerType() || getFromType()->isBlockPointerType() || getFromType()->isNullPtrType() || First == ICK_Array_To_Pointer || First == ICK_Function_To_Pointer)) return true; return false; } /// isPointerConversionToVoidPointer - Determines whether this /// conversion is a conversion of a pointer to a void pointer. This is /// used as part of the ranking of standard conversion sequences (C++ /// 13.3.3.2p4). bool StandardConversionSequence:: isPointerConversionToVoidPointer(ASTContext& Context) const { QualType FromType = getFromType(); QualType ToType = getToType(1); // Note that FromType has not necessarily been transformed by the // array-to-pointer implicit conversion, so check for its presence // and redo the conversion to get a pointer. if (First == ICK_Array_To_Pointer) FromType = Context.getArrayDecayedType(FromType); if (Second == ICK_Pointer_Conversion && FromType->isAnyPointerType()) if (const PointerType* ToPtrType = ToType->getAs()) return ToPtrType->getPointeeType()->isVoidType(); return false; } /// Skip any implicit casts which could be either part of a narrowing conversion /// or after one in an implicit conversion. static const Expr *IgnoreNarrowingConversion(ASTContext &Ctx, const Expr *Converted) { // We can have cleanups wrapping the converted expression; these need to be // preserved so that destructors run if necessary. if (auto *EWC = dyn_cast(Converted)) { Expr *Inner = const_cast(IgnoreNarrowingConversion(Ctx, EWC->getSubExpr())); return ExprWithCleanups::Create(Ctx, Inner, EWC->cleanupsHaveSideEffects(), EWC->getObjects()); } while (auto *ICE = dyn_cast(Converted)) { switch (ICE->getCastKind()) { case CK_NoOp: case CK_IntegralCast: case CK_IntegralToBoolean: case CK_IntegralToFloating: case CK_BooleanToSignedIntegral: case CK_FloatingToIntegral: case CK_FloatingToBoolean: case CK_FloatingCast: Converted = ICE->getSubExpr(); continue; default: return Converted; } } return Converted; } /// Check if this standard conversion sequence represents a narrowing /// conversion, according to C++11 [dcl.init.list]p7. /// /// \param Ctx The AST context. /// \param Converted The result of applying this standard conversion sequence. /// \param ConstantValue If this is an NK_Constant_Narrowing conversion, the /// value of the expression prior to the narrowing conversion. /// \param ConstantType If this is an NK_Constant_Narrowing conversion, the /// type of the expression prior to the narrowing conversion. /// \param IgnoreFloatToIntegralConversion If true type-narrowing conversions /// from floating point types to integral types should be ignored. NarrowingKind StandardConversionSequence::getNarrowingKind( ASTContext &Ctx, const Expr *Converted, APValue &ConstantValue, QualType &ConstantType, bool IgnoreFloatToIntegralConversion) const { assert(Ctx.getLangOpts().CPlusPlus && "narrowing check outside C++"); // C++11 [dcl.init.list]p7: // A narrowing conversion is an implicit conversion ... QualType FromType = getToType(0); QualType ToType = getToType(1); // A conversion to an enumeration type is narrowing if the conversion to // the underlying type is narrowing. This only arises for expressions of // the form 'Enum{init}'. if (auto *ET = ToType->getAs()) ToType = ET->getDecl()->getIntegerType(); switch (Second) { // 'bool' is an integral type; dispatch to the right place to handle it. case ICK_Boolean_Conversion: if (FromType->isRealFloatingType()) goto FloatingIntegralConversion; if (FromType->isIntegralOrUnscopedEnumerationType()) goto IntegralConversion; // Boolean conversions can be from pointers and pointers to members // [conv.bool], and those aren't considered narrowing conversions. return NK_Not_Narrowing; // -- from a floating-point type to an integer type, or // // -- from an integer type or unscoped enumeration type to a floating-point // type, except where the source is a constant expression and the actual // value after conversion will fit into the target type and will produce // the original value when converted back to the original type, or case ICK_Floating_Integral: FloatingIntegralConversion: if (FromType->isRealFloatingType() && ToType->isIntegralType(Ctx)) { return NK_Type_Narrowing; } else if (FromType->isIntegralOrUnscopedEnumerationType() && ToType->isRealFloatingType()) { if (IgnoreFloatToIntegralConversion) return NK_Not_Narrowing; llvm::APSInt IntConstantValue; const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted); assert(Initializer && "Unknown conversion expression"); // If it's value-dependent, we can't tell whether it's narrowing. if (Initializer->isValueDependent()) return NK_Dependent_Narrowing; if (Initializer->isIntegerConstantExpr(IntConstantValue, Ctx)) { // Convert the integer to the floating type. llvm::APFloat Result(Ctx.getFloatTypeSemantics(ToType)); Result.convertFromAPInt(IntConstantValue, IntConstantValue.isSigned(), llvm::APFloat::rmNearestTiesToEven); // And back. llvm::APSInt ConvertedValue = IntConstantValue; bool ignored; Result.convertToInteger(ConvertedValue, llvm::APFloat::rmTowardZero, &ignored); // If the resulting value is different, this was a narrowing conversion. if (IntConstantValue != ConvertedValue) { ConstantValue = APValue(IntConstantValue); ConstantType = Initializer->getType(); return NK_Constant_Narrowing; } } else { // Variables are always narrowings. return NK_Variable_Narrowing; } } return NK_Not_Narrowing; // -- from long double to double or float, or from double to float, except // where the source is a constant expression and the actual value after // conversion is within the range of values that can be represented (even // if it cannot be represented exactly), or case ICK_Floating_Conversion: if (FromType->isRealFloatingType() && ToType->isRealFloatingType() && Ctx.getFloatingTypeOrder(FromType, ToType) == 1) { // FromType is larger than ToType. const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted); // If it's value-dependent, we can't tell whether it's narrowing. if (Initializer->isValueDependent()) return NK_Dependent_Narrowing; if (Initializer->isCXX11ConstantExpr(Ctx, &ConstantValue)) { // Constant! assert(ConstantValue.isFloat()); llvm::APFloat FloatVal = ConstantValue.getFloat(); // Convert the source value into the target type. bool ignored; llvm::APFloat::opStatus ConvertStatus = FloatVal.convert( Ctx.getFloatTypeSemantics(ToType), llvm::APFloat::rmNearestTiesToEven, &ignored); // If there was no overflow, the source value is within the range of // values that can be represented. if (ConvertStatus & llvm::APFloat::opOverflow) { ConstantType = Initializer->getType(); return NK_Constant_Narrowing; } } else { return NK_Variable_Narrowing; } } return NK_Not_Narrowing; // -- from an integer type or unscoped enumeration type to an integer type // that cannot represent all the values of the original type, except where // the source is a constant expression and the actual value after // conversion will fit into the target type and will produce the original // value when converted back to the original type. case ICK_Integral_Conversion: IntegralConversion: { assert(FromType->isIntegralOrUnscopedEnumerationType()); assert(ToType->isIntegralOrUnscopedEnumerationType()); const bool FromSigned = FromType->isSignedIntegerOrEnumerationType(); const unsigned FromWidth = Ctx.getIntWidth(FromType); const bool ToSigned = ToType->isSignedIntegerOrEnumerationType(); const unsigned ToWidth = Ctx.getIntWidth(ToType); if (FromWidth > ToWidth || (FromWidth == ToWidth && FromSigned != ToSigned) || (FromSigned && !ToSigned)) { // Not all values of FromType can be represented in ToType. llvm::APSInt InitializerValue; const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted); // If it's value-dependent, we can't tell whether it's narrowing. if (Initializer->isValueDependent()) return NK_Dependent_Narrowing; if (!Initializer->isIntegerConstantExpr(InitializerValue, Ctx)) { // Such conversions on variables are always narrowing. return NK_Variable_Narrowing; } bool Narrowing = false; if (FromWidth < ToWidth) { // Negative -> unsigned is narrowing. Otherwise, more bits is never // narrowing. if (InitializerValue.isSigned() && InitializerValue.isNegative()) Narrowing = true; } else { // Add a bit to the InitializerValue so we don't have to worry about // signed vs. unsigned comparisons. InitializerValue = InitializerValue.extend( InitializerValue.getBitWidth() + 1); // Convert the initializer to and from the target width and signed-ness. llvm::APSInt ConvertedValue = InitializerValue; ConvertedValue = ConvertedValue.trunc(ToWidth); ConvertedValue.setIsSigned(ToSigned); ConvertedValue = ConvertedValue.extend(InitializerValue.getBitWidth()); ConvertedValue.setIsSigned(InitializerValue.isSigned()); // If the result is different, this was a narrowing conversion. if (ConvertedValue != InitializerValue) Narrowing = true; } if (Narrowing) { ConstantType = Initializer->getType(); ConstantValue = APValue(InitializerValue); return NK_Constant_Narrowing; } } return NK_Not_Narrowing; } default: // Other kinds of conversions are not narrowings. return NK_Not_Narrowing; } } /// dump - Print this standard conversion sequence to standard /// error. Useful for debugging overloading issues. LLVM_DUMP_METHOD void StandardConversionSequence::dump() const { raw_ostream &OS = llvm::errs(); bool PrintedSomething = false; if (First != ICK_Identity) { OS << GetImplicitConversionName(First); PrintedSomething = true; } if (Second != ICK_Identity) { if (PrintedSomething) { OS << " -> "; } OS << GetImplicitConversionName(Second); if (CopyConstructor) { OS << " (by copy constructor)"; } else if (DirectBinding) { OS << " (direct reference binding)"; } else if (ReferenceBinding) { OS << " (reference binding)"; } PrintedSomething = true; } if (Third != ICK_Identity) { if (PrintedSomething) { OS << " -> "; } OS << GetImplicitConversionName(Third); PrintedSomething = true; } if (!PrintedSomething) { OS << "No conversions required"; } } /// dump - Print this user-defined conversion sequence to standard /// error. Useful for debugging overloading issues. void UserDefinedConversionSequence::dump() const { raw_ostream &OS = llvm::errs(); if (Before.First || Before.Second || Before.Third) { Before.dump(); OS << " -> "; } if (ConversionFunction) OS << '\'' << *ConversionFunction << '\''; else OS << "aggregate initialization"; if (After.First || After.Second || After.Third) { OS << " -> "; After.dump(); } } /// dump - Print this implicit conversion sequence to standard /// error. Useful for debugging overloading issues. void ImplicitConversionSequence::dump() const { raw_ostream &OS = llvm::errs(); if (isStdInitializerListElement()) OS << "Worst std::initializer_list element conversion: "; switch (ConversionKind) { case StandardConversion: OS << "Standard conversion: "; Standard.dump(); break; case UserDefinedConversion: OS << "User-defined conversion: "; UserDefined.dump(); break; case EllipsisConversion: OS << "Ellipsis conversion"; break; case AmbiguousConversion: OS << "Ambiguous conversion"; break; case BadConversion: OS << "Bad conversion"; break; } OS << "\n"; } void AmbiguousConversionSequence::construct() { new (&conversions()) ConversionSet(); } void AmbiguousConversionSequence::destruct() { conversions().~ConversionSet(); } void AmbiguousConversionSequence::copyFrom(const AmbiguousConversionSequence &O) { FromTypePtr = O.FromTypePtr; ToTypePtr = O.ToTypePtr; new (&conversions()) ConversionSet(O.conversions()); } namespace { // Structure used by DeductionFailureInfo to store // template argument information. struct DFIArguments { TemplateArgument FirstArg; TemplateArgument SecondArg; }; // Structure used by DeductionFailureInfo to store // template parameter and template argument information. struct DFIParamWithArguments : DFIArguments { TemplateParameter Param; }; // Structure used by DeductionFailureInfo to store template argument // information and the index of the problematic call argument. struct DFIDeducedMismatchArgs : DFIArguments { TemplateArgumentList *TemplateArgs; unsigned CallArgIndex; }; // Structure used by DeductionFailureInfo to store information about // unsatisfied constraints. struct CNSInfo { TemplateArgumentList *TemplateArgs; ConstraintSatisfaction Satisfaction; }; } /// Convert from Sema's representation of template deduction information /// to the form used in overload-candidate information. DeductionFailureInfo clang::MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK, TemplateDeductionInfo &Info) { DeductionFailureInfo Result; Result.Result = static_cast(TDK); Result.HasDiagnostic = false; switch (TDK) { case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_MiscellaneousDeductionFailure: case Sema::TDK_CUDATargetMismatch: Result.Data = nullptr; break; case Sema::TDK_Incomplete: case Sema::TDK_InvalidExplicitArguments: Result.Data = Info.Param.getOpaqueValue(); break; case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: { // FIXME: Should allocate from normal heap so that we can free this later. auto *Saved = new (Context) DFIDeducedMismatchArgs; Saved->FirstArg = Info.FirstArg; Saved->SecondArg = Info.SecondArg; Saved->TemplateArgs = Info.take(); Saved->CallArgIndex = Info.CallArgIndex; Result.Data = Saved; break; } case Sema::TDK_NonDeducedMismatch: { // FIXME: Should allocate from normal heap so that we can free this later. DFIArguments *Saved = new (Context) DFIArguments; Saved->FirstArg = Info.FirstArg; Saved->SecondArg = Info.SecondArg; Result.Data = Saved; break; } case Sema::TDK_IncompletePack: // FIXME: It's slightly wasteful to allocate two TemplateArguments for this. case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: { // FIXME: Should allocate from normal heap so that we can free this later. DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments; Saved->Param = Info.Param; Saved->FirstArg = Info.FirstArg; Saved->SecondArg = Info.SecondArg; Result.Data = Saved; break; } case Sema::TDK_SubstitutionFailure: Result.Data = Info.take(); if (Info.hasSFINAEDiagnostic()) { PartialDiagnosticAt *Diag = new (Result.Diagnostic) PartialDiagnosticAt( SourceLocation(), PartialDiagnostic::NullDiagnostic()); Info.takeSFINAEDiagnostic(*Diag); Result.HasDiagnostic = true; } break; case Sema::TDK_ConstraintsNotSatisfied: { CNSInfo *Saved = new (Context) CNSInfo; Saved->TemplateArgs = Info.take(); Saved->Satisfaction = Info.AssociatedConstraintsSatisfaction; Result.Data = Saved; break; } case Sema::TDK_Success: case Sema::TDK_NonDependentConversionFailure: llvm_unreachable("not a deduction failure"); } return Result; } void DeductionFailureInfo::Destroy() { switch (static_cast(Result)) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_Incomplete: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_CUDATargetMismatch: case Sema::TDK_NonDependentConversionFailure: break; case Sema::TDK_IncompletePack: case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: // FIXME: Destroy the data? Data = nullptr; break; case Sema::TDK_SubstitutionFailure: // FIXME: Destroy the template argument list? Data = nullptr; if (PartialDiagnosticAt *Diag = getSFINAEDiagnostic()) { Diag->~PartialDiagnosticAt(); HasDiagnostic = false; } break; case Sema::TDK_ConstraintsNotSatisfied: // FIXME: Destroy the template argument list? Data = nullptr; if (PartialDiagnosticAt *Diag = getSFINAEDiagnostic()) { Diag->~PartialDiagnosticAt(); HasDiagnostic = false; } break; // Unhandled case Sema::TDK_MiscellaneousDeductionFailure: break; } } PartialDiagnosticAt *DeductionFailureInfo::getSFINAEDiagnostic() { if (HasDiagnostic) return static_cast(static_cast(Diagnostic)); return nullptr; } TemplateParameter DeductionFailureInfo::getTemplateParameter() { switch (static_cast(Result)) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_SubstitutionFailure: case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_CUDATargetMismatch: case Sema::TDK_NonDependentConversionFailure: case Sema::TDK_ConstraintsNotSatisfied: return TemplateParameter(); case Sema::TDK_Incomplete: case Sema::TDK_InvalidExplicitArguments: return TemplateParameter::getFromOpaqueValue(Data); case Sema::TDK_IncompletePack: case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: return static_cast(Data)->Param; // Unhandled case Sema::TDK_MiscellaneousDeductionFailure: break; } return TemplateParameter(); } TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { switch (static_cast(Result)) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_Incomplete: case Sema::TDK_IncompletePack: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_CUDATargetMismatch: case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: return static_cast(Data)->TemplateArgs; case Sema::TDK_SubstitutionFailure: return static_cast(Data); case Sema::TDK_ConstraintsNotSatisfied: return static_cast(Data)->TemplateArgs; // Unhandled case Sema::TDK_MiscellaneousDeductionFailure: break; } return nullptr; } const TemplateArgument *DeductionFailureInfo::getFirstArg() { switch (static_cast(Result)) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_Incomplete: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_SubstitutionFailure: case Sema::TDK_CUDATargetMismatch: case Sema::TDK_NonDependentConversionFailure: case Sema::TDK_ConstraintsNotSatisfied: return nullptr; case Sema::TDK_IncompletePack: case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: return &static_cast(Data)->FirstArg; // Unhandled case Sema::TDK_MiscellaneousDeductionFailure: break; } return nullptr; } const TemplateArgument *DeductionFailureInfo::getSecondArg() { switch (static_cast(Result)) { case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_Incomplete: case Sema::TDK_IncompletePack: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_SubstitutionFailure: case Sema::TDK_CUDATargetMismatch: case Sema::TDK_NonDependentConversionFailure: case Sema::TDK_ConstraintsNotSatisfied: return nullptr; case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: return &static_cast(Data)->SecondArg; // Unhandled case Sema::TDK_MiscellaneousDeductionFailure: break; } return nullptr; } llvm::Optional DeductionFailureInfo::getCallArgIndex() { switch (static_cast(Result)) { case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: return static_cast(Data)->CallArgIndex; default: return llvm::None; } } bool OverloadCandidateSet::OperatorRewriteInfo::shouldAddReversed( OverloadedOperatorKind Op) { if (!AllowRewrittenCandidates) return false; return Op == OO_EqualEqual || Op == OO_Spaceship; } bool OverloadCandidateSet::OperatorRewriteInfo::shouldAddReversed( ASTContext &Ctx, const FunctionDecl *FD) { if (!shouldAddReversed(FD->getDeclName().getCXXOverloadedOperator())) return false; // Don't bother adding a reversed candidate that can never be a better // match than the non-reversed version. return FD->getNumParams() != 2 || !Ctx.hasSameUnqualifiedType(FD->getParamDecl(0)->getType(), FD->getParamDecl(1)->getType()) || FD->hasAttr(); } void OverloadCandidateSet::destroyCandidates() { for (iterator i = begin(), e = end(); i != e; ++i) { for (auto &C : i->Conversions) C.~ImplicitConversionSequence(); if (!i->Viable && i->FailureKind == ovl_fail_bad_deduction) i->DeductionFailure.Destroy(); } } void OverloadCandidateSet::clear(CandidateSetKind CSK) { destroyCandidates(); SlabAllocator.Reset(); NumInlineBytesUsed = 0; Candidates.clear(); Functions.clear(); Kind = CSK; } namespace { class UnbridgedCastsSet { struct Entry { Expr **Addr; Expr *Saved; }; SmallVector Entries; public: void save(Sema &S, Expr *&E) { assert(E->hasPlaceholderType(BuiltinType::ARCUnbridgedCast)); Entry entry = { &E, E }; Entries.push_back(entry); E = S.stripARCUnbridgedCast(E); } void restore() { for (SmallVectorImpl::iterator i = Entries.begin(), e = Entries.end(); i != e; ++i) *i->Addr = i->Saved; } }; } /// checkPlaceholderForOverload - Do any interesting placeholder-like /// preprocessing on the given expression. /// /// \param unbridgedCasts a collection to which to add unbridged casts; /// without this, they will be immediately diagnosed as errors /// /// Return true on unrecoverable error. static bool checkPlaceholderForOverload(Sema &S, Expr *&E, UnbridgedCastsSet *unbridgedCasts = nullptr) { if (const BuiltinType *placeholder = E->getType()->getAsPlaceholderType()) { // We can't handle overloaded expressions here because overload // resolution might reasonably tweak them. if (placeholder->getKind() == BuiltinType::Overload) return false; // If the context potentially accepts unbridged ARC casts, strip // the unbridged cast and add it to the collection for later restoration. if (placeholder->getKind() == BuiltinType::ARCUnbridgedCast && unbridgedCasts) { unbridgedCasts->save(S, E); return false; } // Go ahead and check everything else. ExprResult result = S.CheckPlaceholderExpr(E); if (result.isInvalid()) return true; E = result.get(); return false; } // Nothing to do. return false; } /// checkArgPlaceholdersForOverload - Check a set of call operands for /// placeholders. static bool checkArgPlaceholdersForOverload(Sema &S, MultiExprArg Args, UnbridgedCastsSet &unbridged) { for (unsigned i = 0, e = Args.size(); i != e; ++i) if (checkPlaceholderForOverload(S, Args[i], &unbridged)) return true; return false; } /// Determine whether the given New declaration is an overload of the /// declarations in Old. This routine returns Ovl_Match or Ovl_NonFunction if /// New and Old cannot be overloaded, e.g., if New has the same signature as /// some function in Old (C++ 1.3.10) or if the Old declarations aren't /// functions (or function templates) at all. When it does return Ovl_Match or /// Ovl_NonFunction, MatchedDecl will point to the decl that New cannot be /// overloaded with. This decl may be a UsingShadowDecl on top of the underlying /// declaration. /// /// Example: Given the following input: /// /// void f(int, float); // #1 /// void f(int, int); // #2 /// int f(int, int); // #3 /// /// When we process #1, there is no previous declaration of "f", so IsOverload /// will not be used. /// /// When we process #2, Old contains only the FunctionDecl for #1. By comparing /// the parameter types, we see that #1 and #2 are overloaded (since they have /// different signatures), so this routine returns Ovl_Overload; MatchedDecl is /// unchanged. /// /// When we process #3, Old is an overload set containing #1 and #2. We compare /// the signatures of #3 to #1 (they're overloaded, so we do nothing) and then /// #3 to #2. Since the signatures of #3 and #2 are identical (return types of /// functions are not part of the signature), IsOverload returns Ovl_Match and /// MatchedDecl will be set to point to the FunctionDecl for #2. /// /// 'NewIsUsingShadowDecl' indicates that 'New' is being introduced into a class /// by a using declaration. The rules for whether to hide shadow declarations /// ignore some properties which otherwise figure into a function template's /// signature. Sema::OverloadKind Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old, NamedDecl *&Match, bool NewIsUsingDecl) { for (LookupResult::iterator I = Old.begin(), E = Old.end(); I != E; ++I) { NamedDecl *OldD = *I; bool OldIsUsingDecl = false; if (isa(OldD)) { OldIsUsingDecl = true; // We can always introduce two using declarations into the same // context, even if they have identical signatures. if (NewIsUsingDecl) continue; OldD = cast(OldD)->getTargetDecl(); } // A using-declaration does not conflict with another declaration // if one of them is hidden. if ((OldIsUsingDecl || NewIsUsingDecl) && !isVisible(*I)) continue; // If either declaration was introduced by a using declaration, // we'll need to use slightly different rules for matching. // Essentially, these rules are the normal rules, except that // function templates hide function templates with different // return types or template parameter lists. bool UseMemberUsingDeclRules = (OldIsUsingDecl || NewIsUsingDecl) && CurContext->isRecord() && !New->getFriendObjectKind(); if (FunctionDecl *OldF = OldD->getAsFunction()) { if (!IsOverload(New, OldF, UseMemberUsingDeclRules)) { if (UseMemberUsingDeclRules && OldIsUsingDecl) { HideUsingShadowDecl(S, cast(*I)); continue; } if (!isa(OldD) && !shouldLinkPossiblyHiddenDecl(*I, New)) continue; Match = *I; return Ovl_Match; } // Builtins that have custom typechecking or have a reference should // not be overloadable or redeclarable. if (!getASTContext().canBuiltinBeRedeclared(OldF)) { Match = *I; return Ovl_NonFunction; } } else if (isa(OldD) || isa(OldD)) { // We can overload with these, which can show up when doing // redeclaration checks for UsingDecls. assert(Old.getLookupKind() == LookupUsingDeclName); } else if (isa(OldD)) { // We can always overload with tags by hiding them. } else if (auto *UUD = dyn_cast(OldD)) { // Optimistically assume that an unresolved using decl will // overload; if it doesn't, we'll have to diagnose during // template instantiation. // // Exception: if the scope is dependent and this is not a class // member, the using declaration can only introduce an enumerator. if (UUD->getQualifier()->isDependent() && !UUD->isCXXClassMember()) { Match = *I; return Ovl_NonFunction; } } else { // (C++ 13p1): // Only function declarations can be overloaded; object and type // declarations cannot be overloaded. Match = *I; return Ovl_NonFunction; } } // C++ [temp.friend]p1: // For a friend function declaration that is not a template declaration: // -- if the name of the friend is a qualified or unqualified template-id, // [...], otherwise // -- if the name of the friend is a qualified-id and a matching // non-template function is found in the specified class or namespace, // the friend declaration refers to that function, otherwise, // -- if the name of the friend is a qualified-id and a matching function // template is found in the specified class or namespace, the friend // declaration refers to the deduced specialization of that function // template, otherwise // -- the name shall be an unqualified-id [...] // If we get here for a qualified friend declaration, we've just reached the // third bullet. If the type of the friend is dependent, skip this lookup // until instantiation. if (New->getFriendObjectKind() && New->getQualifier() && !New->getDescribedFunctionTemplate() && !New->getDependentSpecializationInfo() && !New->getType()->isDependentType()) { LookupResult TemplateSpecResult(LookupResult::Temporary, Old); TemplateSpecResult.addAllDecls(Old); if (CheckFunctionTemplateSpecialization(New, nullptr, TemplateSpecResult, /*QualifiedFriend*/true)) { New->setInvalidDecl(); return Ovl_Overload; } Match = TemplateSpecResult.getAsSingle(); return Ovl_Match; } return Ovl_Overload; } bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, bool UseMemberUsingDeclRules, bool ConsiderCudaAttrs, bool ConsiderRequiresClauses) { // C++ [basic.start.main]p2: This function shall not be overloaded. if (New->isMain()) return false; // MSVCRT user defined entry points cannot be overloaded. if (New->isMSVCRTEntryPoint()) return false; FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate(); FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate(); // C++ [temp.fct]p2: // A function template can be overloaded with other function templates // and with normal (non-template) functions. if ((OldTemplate == nullptr) != (NewTemplate == nullptr)) return true; // Is the function New an overload of the function Old? QualType OldQType = Context.getCanonicalType(Old->getType()); QualType NewQType = Context.getCanonicalType(New->getType()); // Compare the signatures (C++ 1.3.10) of the two functions to // determine whether they are overloads. If we find any mismatch // in the signature, they are overloads. // If either of these functions is a K&R-style function (no // prototype), then we consider them to have matching signatures. if (isa(OldQType.getTypePtr()) || isa(NewQType.getTypePtr())) return false; const FunctionProtoType *OldType = cast(OldQType); const FunctionProtoType *NewType = cast(NewQType); // The signature of a function includes the types of its // parameters (C++ 1.3.10), which includes the presence or absence // of the ellipsis; see C++ DR 357). if (OldQType != NewQType && (OldType->getNumParams() != NewType->getNumParams() || OldType->isVariadic() != NewType->isVariadic() || !FunctionParamTypesAreEqual(OldType, NewType))) return true; // C++ [temp.over.link]p4: // The signature of a function template consists of its function // signature, its return type and its template parameter list. The names // of the template parameters are significant only for establishing the // relationship between the template parameters and the rest of the // signature. // // We check the return type and template parameter lists for function // templates first; the remaining checks follow. // // However, we don't consider either of these when deciding whether // a member introduced by a shadow declaration is hidden. if (!UseMemberUsingDeclRules && NewTemplate && (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), OldTemplate->getTemplateParameters(), false, TPL_TemplateMatch) || !Context.hasSameType(Old->getDeclaredReturnType(), New->getDeclaredReturnType()))) return true; // If the function is a class member, its signature includes the // cv-qualifiers (if any) and ref-qualifier (if any) on the function itself. // // As part of this, also check whether one of the member functions // is static, in which case they are not overloads (C++ // 13.1p2). While not part of the definition of the signature, // this check is important to determine whether these functions // can be overloaded. CXXMethodDecl *OldMethod = dyn_cast(Old); CXXMethodDecl *NewMethod = dyn_cast(New); if (OldMethod && NewMethod && !OldMethod->isStatic() && !NewMethod->isStatic()) { if (OldMethod->getRefQualifier() != NewMethod->getRefQualifier()) { if (!UseMemberUsingDeclRules && (OldMethod->getRefQualifier() == RQ_None || NewMethod->getRefQualifier() == RQ_None)) { // C++0x [over.load]p2: // - Member function declarations with the same name and the same // parameter-type-list as well as member function template // declarations with the same name, the same parameter-type-list, and // the same template parameter lists cannot be overloaded if any of // them, but not all, have a ref-qualifier (8.3.5). Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload) << NewMethod->getRefQualifier() << OldMethod->getRefQualifier(); Diag(OldMethod->getLocation(), diag::note_previous_declaration); } return true; } // We may not have applied the implicit const for a constexpr member // function yet (because we haven't yet resolved whether this is a static // or non-static member function). Add it now, on the assumption that this // is a redeclaration of OldMethod. auto OldQuals = OldMethod->getMethodQualifiers(); auto NewQuals = NewMethod->getMethodQualifiers(); if (!getLangOpts().CPlusPlus14 && NewMethod->isConstexpr() && !isa(NewMethod)) NewQuals.addConst(); // We do not allow overloading based off of '__restrict'. OldQuals.removeRestrict(); NewQuals.removeRestrict(); if (OldQuals != NewQuals) return true; } // Though pass_object_size is placed on parameters and takes an argument, we // consider it to be a function-level modifier for the sake of function // identity. Either the function has one or more parameters with // pass_object_size or it doesn't. if (functionHasPassObjectSizeParams(New) != functionHasPassObjectSizeParams(Old)) return true; // enable_if attributes are an order-sensitive part of the signature. for (specific_attr_iterator NewI = New->specific_attr_begin(), NewE = New->specific_attr_end(), OldI = Old->specific_attr_begin(), OldE = Old->specific_attr_end(); NewI != NewE || OldI != OldE; ++NewI, ++OldI) { if (NewI == NewE || OldI == OldE) return true; llvm::FoldingSetNodeID NewID, OldID; NewI->getCond()->Profile(NewID, Context, true); OldI->getCond()->Profile(OldID, Context, true); if (NewID != OldID) return true; } if (getLangOpts().CUDA && ConsiderCudaAttrs) { // Don't allow overloading of destructors. (In theory we could, but it // would be a giant change to clang.) if (!isa(New)) { CUDAFunctionTarget NewTarget = IdentifyCUDATarget(New), OldTarget = IdentifyCUDATarget(Old); if (NewTarget != CFT_InvalidTarget) { assert((OldTarget != CFT_InvalidTarget) && "Unexpected invalid target."); // Allow overloading of functions with same signature and different CUDA // target attributes. if (NewTarget != OldTarget) return true; } } } if (ConsiderRequiresClauses) { Expr *NewRC = New->getTrailingRequiresClause(), *OldRC = Old->getTrailingRequiresClause(); if ((NewRC != nullptr) != (OldRC != nullptr)) // RC are most certainly different - these are overloads. return true; if (NewRC) { llvm::FoldingSetNodeID NewID, OldID; NewRC->Profile(NewID, Context, /*Canonical=*/true); OldRC->Profile(OldID, Context, /*Canonical=*/true); if (NewID != OldID) // RCs are not equivalent - these are overloads. return true; } } // The signatures match; this is not an overload. return false; } /// Tries a user-defined conversion from From to ToType. /// /// Produces an implicit conversion sequence for when a standard conversion /// is not an option. See TryImplicitConversion for more information. static ImplicitConversionSequence TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType, bool SuppressUserConversions, bool AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion, bool AllowObjCConversionOnExplicit) { ImplicitConversionSequence ICS; if (SuppressUserConversions) { // We're not in the case above, so there is no conversion that // we can perform. ICS.setBad(BadConversionSequence::no_conversion, From, ToType); return ICS; } // Attempt user-defined conversion. OverloadCandidateSet Conversions(From->getExprLoc(), OverloadCandidateSet::CSK_Normal); switch (IsUserDefinedConversion(S, From, ToType, ICS.UserDefined, Conversions, AllowExplicit, AllowObjCConversionOnExplicit)) { case OR_Success: case OR_Deleted: ICS.setUserDefined(); // C++ [over.ics.user]p4: // A conversion of an expression of class type to the same class // type is given Exact Match rank, and a conversion of an // expression of class type to a base class of that type is // given Conversion rank, in spite of the fact that a copy // constructor (i.e., a user-defined conversion function) is // called for those cases. if (CXXConstructorDecl *Constructor = dyn_cast(ICS.UserDefined.ConversionFunction)) { QualType FromCanon = S.Context.getCanonicalType(From->getType().getUnqualifiedType()); QualType ToCanon = S.Context.getCanonicalType(ToType).getUnqualifiedType(); if (Constructor->isCopyConstructor() && (FromCanon == ToCanon || S.IsDerivedFrom(From->getBeginLoc(), FromCanon, ToCanon))) { // Turn this into a "standard" conversion sequence, so that it // gets ranked with standard conversion sequences. DeclAccessPair Found = ICS.UserDefined.FoundConversionFunction; ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); ICS.Standard.setFromType(From->getType()); ICS.Standard.setAllToTypes(ToType); ICS.Standard.CopyConstructor = Constructor; ICS.Standard.FoundCopyConstructor = Found; if (ToCanon != FromCanon) ICS.Standard.Second = ICK_Derived_To_Base; } } break; case OR_Ambiguous: ICS.setAmbiguous(); ICS.Ambiguous.setFromType(From->getType()); ICS.Ambiguous.setToType(ToType); for (OverloadCandidateSet::iterator Cand = Conversions.begin(); Cand != Conversions.end(); ++Cand) if (Cand->Best) ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function); break; // Fall through. case OR_No_Viable_Function: ICS.setBad(BadConversionSequence::no_conversion, From, ToType); break; } return ICS; } /// TryImplicitConversion - Attempt to perform an implicit conversion /// from the given expression (Expr) to the given type (ToType). This /// function returns an implicit conversion sequence that can be used /// to perform the initialization. Given /// /// void f(float f); /// void g(int i) { f(i); } /// /// this routine would produce an implicit conversion sequence to /// describe the initialization of f from i, which will be a standard /// conversion sequence containing an lvalue-to-rvalue conversion (C++ /// 4.1) followed by a floating-integral conversion (C++ 4.9). // /// Note that this routine only determines how the conversion can be /// performed; it does not actually perform the conversion. As such, /// it will not produce any diagnostics if no conversion is available, /// but will instead return an implicit conversion sequence of kind /// "BadConversion". /// /// If @p SuppressUserConversions, then user-defined conversions are /// not permitted. /// If @p AllowExplicit, then explicit user-defined conversions are /// permitted. /// /// \param AllowObjCWritebackConversion Whether we allow the Objective-C /// writeback conversion, which allows __autoreleasing id* parameters to /// be initialized with __strong id* or __weak id* arguments. static ImplicitConversionSequence TryImplicitConversion(Sema &S, Expr *From, QualType ToType, bool SuppressUserConversions, bool AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion, bool AllowObjCConversionOnExplicit) { ImplicitConversionSequence ICS; if (IsStandardConversion(S, From, ToType, InOverloadResolution, ICS.Standard, CStyle, AllowObjCWritebackConversion)){ ICS.setStandard(); return ICS; } if (!S.getLangOpts().CPlusPlus) { ICS.setBad(BadConversionSequence::no_conversion, From, ToType); return ICS; } // C++ [over.ics.user]p4: // A conversion of an expression of class type to the same class // type is given Exact Match rank, and a conversion of an // expression of class type to a base class of that type is // given Conversion rank, in spite of the fact that a copy/move // constructor (i.e., a user-defined conversion function) is // called for those cases. QualType FromType = From->getType(); if (ToType->getAs() && FromType->getAs() && (S.Context.hasSameUnqualifiedType(FromType, ToType) || S.IsDerivedFrom(From->getBeginLoc(), FromType, ToType))) { ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); ICS.Standard.setFromType(FromType); ICS.Standard.setAllToTypes(ToType); // We don't actually check at this point whether there is a valid // copy/move constructor, since overloading just assumes that it // exists. When we actually perform initialization, we'll find the // appropriate constructor to copy the returned object, if needed. ICS.Standard.CopyConstructor = nullptr; // Determine whether this is considered a derived-to-base conversion. if (!S.Context.hasSameUnqualifiedType(FromType, ToType)) ICS.Standard.Second = ICK_Derived_To_Base; return ICS; } return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions, AllowExplicit, InOverloadResolution, CStyle, AllowObjCWritebackConversion, AllowObjCConversionOnExplicit); } ImplicitConversionSequence Sema::TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, bool AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion) { return ::TryImplicitConversion(*this, From, ToType, SuppressUserConversions, AllowExplicit, InOverloadResolution, CStyle, AllowObjCWritebackConversion, /*AllowObjCConversionOnExplicit=*/false); } /// PerformImplicitConversion - Perform an implicit conversion of the /// expression From to the type ToType. Returns the /// converted expression. Flavor is the kind of conversion we're /// performing, used in the error message. If @p AllowExplicit, /// explicit user-defined conversions are permitted. ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit) { ImplicitConversionSequence ICS; return PerformImplicitConversion(From, ToType, Action, AllowExplicit, ICS); } ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit, ImplicitConversionSequence& ICS) { if (checkPlaceholderForOverload(*this, From)) return ExprError(); // Objective-C ARC: Determine whether we will allow the writeback conversion. bool AllowObjCWritebackConversion = getLangOpts().ObjCAutoRefCount && (Action == AA_Passing || Action == AA_Sending); if (getLangOpts().ObjC) CheckObjCBridgeRelatedConversions(From->getBeginLoc(), ToType, From->getType(), From); ICS = ::TryImplicitConversion(*this, From, ToType, /*SuppressUserConversions=*/false, AllowExplicit, /*InOverloadResolution=*/false, /*CStyle=*/false, AllowObjCWritebackConversion, /*AllowObjCConversionOnExplicit=*/false); return PerformImplicitConversion(From, ToType, ICS, Action); } /// Determine whether the conversion from FromType to ToType is a valid /// conversion that strips "noexcept" or "noreturn" off the nested function /// type. bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, QualType &ResultTy) { if (Context.hasSameUnqualifiedType(FromType, ToType)) return false; // Permit the conversion F(t __attribute__((noreturn))) -> F(t) // or F(t noexcept) -> F(t) // where F adds one of the following at most once: // - a pointer // - a member pointer // - a block pointer // Changes here need matching changes in FindCompositePointerType. CanQualType CanTo = Context.getCanonicalType(ToType); CanQualType CanFrom = Context.getCanonicalType(FromType); Type::TypeClass TyClass = CanTo->getTypeClass(); if (TyClass != CanFrom->getTypeClass()) return false; if (TyClass != Type::FunctionProto && TyClass != Type::FunctionNoProto) { if (TyClass == Type::Pointer) { CanTo = CanTo.castAs()->getPointeeType(); CanFrom = CanFrom.castAs()->getPointeeType(); } else if (TyClass == Type::BlockPointer) { CanTo = CanTo.castAs()->getPointeeType(); CanFrom = CanFrom.castAs()->getPointeeType(); } else if (TyClass == Type::MemberPointer) { auto ToMPT = CanTo.castAs(); auto FromMPT = CanFrom.castAs(); // A function pointer conversion cannot change the class of the function. if (ToMPT->getClass() != FromMPT->getClass()) return false; CanTo = ToMPT->getPointeeType(); CanFrom = FromMPT->getPointeeType(); } else { return false; } TyClass = CanTo->getTypeClass(); if (TyClass != CanFrom->getTypeClass()) return false; if (TyClass != Type::FunctionProto && TyClass != Type::FunctionNoProto) return false; } const auto *FromFn = cast(CanFrom); FunctionType::ExtInfo FromEInfo = FromFn->getExtInfo(); const auto *ToFn = cast(CanTo); FunctionType::ExtInfo ToEInfo = ToFn->getExtInfo(); bool Changed = false; // Drop 'noreturn' if not present in target type. if (FromEInfo.getNoReturn() && !ToEInfo.getNoReturn()) { FromFn = Context.adjustFunctionType(FromFn, FromEInfo.withNoReturn(false)); Changed = true; } // Drop 'noexcept' if not present in target type. if (const auto *FromFPT = dyn_cast(FromFn)) { const auto *ToFPT = cast(ToFn); if (FromFPT->isNothrow() && !ToFPT->isNothrow()) { FromFn = cast( Context.getFunctionTypeWithExceptionSpec(QualType(FromFPT, 0), EST_None) .getTypePtr()); Changed = true; } // Convert FromFPT's ExtParameterInfo if necessary. The conversion is valid // only if the ExtParameterInfo lists of the two function prototypes can be // merged and the merged list is identical to ToFPT's ExtParameterInfo list. SmallVector NewParamInfos; bool CanUseToFPT, CanUseFromFPT; if (Context.mergeExtParameterInfo(ToFPT, FromFPT, CanUseToFPT, CanUseFromFPT, NewParamInfos) && CanUseToFPT && !CanUseFromFPT) { FunctionProtoType::ExtProtoInfo ExtInfo = FromFPT->getExtProtoInfo(); ExtInfo.ExtParameterInfos = NewParamInfos.empty() ? nullptr : NewParamInfos.data(); QualType QT = Context.getFunctionType(FromFPT->getReturnType(), FromFPT->getParamTypes(), ExtInfo); FromFn = QT->getAs(); Changed = true; } } if (!Changed) return false; assert(QualType(FromFn, 0).isCanonical()); if (QualType(FromFn, 0) != CanTo) return false; ResultTy = ToType; return true; } /// Determine whether the conversion from FromType to ToType is a valid /// vector conversion. /// /// \param ICK Will be set to the vector conversion kind, if this is a vector /// conversion. static bool IsVectorConversion(Sema &S, QualType FromType, QualType ToType, ImplicitConversionKind &ICK) { // We need at least one of these types to be a vector type to have a vector // conversion. if (!ToType->isVectorType() && !FromType->isVectorType()) return false; // Identical types require no conversions. if (S.Context.hasSameUnqualifiedType(FromType, ToType)) return false; // There are no conversions between extended vector types, only identity. if (ToType->isExtVectorType()) { // There are no conversions between extended vector types other than the // identity conversion. if (FromType->isExtVectorType()) return false; // Vector splat from any arithmetic type to a vector. if (FromType->isArithmeticType()) { ICK = ICK_Vector_Splat; return true; } } // We can perform the conversion between vector types in the following cases: // 1)vector types are equivalent AltiVec and GCC vector types // 2)lax vector conversions are permitted and the vector types are of the // same size if (ToType->isVectorType() && FromType->isVectorType()) { if (S.Context.areCompatibleVectorTypes(FromType, ToType) || S.isLaxVectorConversion(FromType, ToType)) { ICK = ICK_Vector_Conversion; return true; } } return false; } static bool tryAtomicConversion(Sema &S, Expr *From, QualType ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle); /// IsStandardConversion - Determines whether there is a standard /// conversion sequence (C++ [conv], C++ [over.ics.scs]) from the /// expression From to the type ToType. Standard conversion sequences /// only consider non-class types; for conversions that involve class /// types, use TryImplicitConversion. If a conversion exists, SCS will /// contain the standard conversion sequence required to perform this /// conversion and this routine will return true. Otherwise, this /// routine will return false and the value of SCS is unspecified. static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle, bool AllowObjCWritebackConversion) { QualType FromType = From->getType(); // Standard conversions (C++ [conv]) SCS.setAsIdentityConversion(); SCS.IncompatibleObjC = false; SCS.setFromType(FromType); SCS.CopyConstructor = nullptr; // There are no standard conversions for class types in C++, so // abort early. When overloading in C, however, we do permit them. if (S.getLangOpts().CPlusPlus && (FromType->isRecordType() || ToType->isRecordType())) return false; // The first conversion can be an lvalue-to-rvalue conversion, // array-to-pointer conversion, or function-to-pointer conversion // (C++ 4p1). if (FromType == S.Context.OverloadTy) { DeclAccessPair AccessPair; if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(From, ToType, false, AccessPair)) { // We were able to resolve the address of the overloaded function, // so we can convert to the type of that function. FromType = Fn->getType(); SCS.setFromType(FromType); // we can sometimes resolve &foo regardless of ToType, so check // if the type matches (identity) or we are converting to bool if (!S.Context.hasSameUnqualifiedType( S.ExtractUnqualifiedFunctionType(ToType), FromType)) { QualType resultTy; // if the function type matches except for [[noreturn]], it's ok if (!S.IsFunctionConversion(FromType, S.ExtractUnqualifiedFunctionType(ToType), resultTy)) // otherwise, only a boolean conversion is standard if (!ToType->isBooleanType()) return false; } // Check if the "from" expression is taking the address of an overloaded // function and recompute the FromType accordingly. Take advantage of the // fact that non-static member functions *must* have such an address-of // expression. CXXMethodDecl *Method = dyn_cast(Fn); if (Method && !Method->isStatic()) { assert(isa(From->IgnoreParens()) && "Non-unary operator on non-static member address"); assert(cast(From->IgnoreParens())->getOpcode() == UO_AddrOf && "Non-address-of operator on non-static member address"); const Type *ClassType = S.Context.getTypeDeclType(Method->getParent()).getTypePtr(); FromType = S.Context.getMemberPointerType(FromType, ClassType); } else if (isa(From->IgnoreParens())) { assert(cast(From->IgnoreParens())->getOpcode() == UO_AddrOf && "Non-address-of operator for overloaded function expression"); FromType = S.Context.getPointerType(FromType); } // Check that we've computed the proper type after overload resolution. // FIXME: FixOverloadedFunctionReference has side-effects; we shouldn't // be calling it from within an NDEBUG block. assert(S.Context.hasSameType( FromType, S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType())); } else { return false; } } // Lvalue-to-rvalue conversion (C++11 4.1): // A glvalue (3.10) of a non-function, non-array type T can // be converted to a prvalue. bool argIsLValue = From->isGLValue(); if (argIsLValue && !FromType->isFunctionType() && !FromType->isArrayType() && S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) { SCS.First = ICK_Lvalue_To_Rvalue; // C11 6.3.2.1p2: // ... if the lvalue has atomic type, the value has the non-atomic version // of the type of the lvalue ... if (const AtomicType *Atomic = FromType->getAs()) FromType = Atomic->getValueType(); // If T is a non-class type, the type of the rvalue is the // cv-unqualified version of T. Otherwise, the type of the rvalue // is T (C++ 4.1p1). C++ can't get here with class types; in C, we // just strip the qualifiers because they don't matter. FromType = FromType.getUnqualifiedType(); } else if (FromType->isArrayType()) { // Array-to-pointer conversion (C++ 4.2) SCS.First = ICK_Array_To_Pointer; // An lvalue or rvalue of type "array of N T" or "array of unknown // bound of T" can be converted to an rvalue of type "pointer to // T" (C++ 4.2p1). FromType = S.Context.getArrayDecayedType(FromType); if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) { // This conversion is deprecated in C++03 (D.4) SCS.DeprecatedStringLiteralToCharPtr = true; // For the purpose of ranking in overload resolution // (13.3.3.1.1), this conversion is considered an // array-to-pointer conversion followed by a qualification // conversion (4.4). (C++ 4.2p2) SCS.Second = ICK_Identity; SCS.Third = ICK_Qualification; SCS.QualificationIncludesObjCLifetime = false; SCS.setAllToTypes(FromType); return true; } } else if (FromType->isFunctionType() && argIsLValue) { // Function-to-pointer conversion (C++ 4.3). SCS.First = ICK_Function_To_Pointer; if (auto *DRE = dyn_cast(From->IgnoreParenCasts())) if (auto *FD = dyn_cast(DRE->getDecl())) if (!S.checkAddressOfFunctionIsAvailable(FD)) return false; // An lvalue of function type T can be converted to an rvalue of // type "pointer to T." The result is a pointer to the // function. (C++ 4.3p1). FromType = S.Context.getPointerType(FromType); } else { // We don't require any conversions for the first step. SCS.First = ICK_Identity; } SCS.setToType(0, FromType); // The second conversion can be an integral promotion, floating // point promotion, integral conversion, floating point conversion, // floating-integral conversion, pointer conversion, // pointer-to-member conversion, or boolean conversion (C++ 4p1). // For overloading in C, this can also be a "compatible-type" // conversion. bool IncompatibleObjC = false; ImplicitConversionKind SecondICK = ICK_Identity; if (S.Context.hasSameUnqualifiedType(FromType, ToType)) { // The unqualified versions of the types are the same: there's no // conversion to do. SCS.Second = ICK_Identity; } else if (S.IsIntegralPromotion(From, FromType, ToType)) { // Integral promotion (C++ 4.5). SCS.Second = ICK_Integral_Promotion; FromType = ToType.getUnqualifiedType(); } else if (S.IsFloatingPointPromotion(FromType, ToType)) { // Floating point promotion (C++ 4.6). SCS.Second = ICK_Floating_Promotion; FromType = ToType.getUnqualifiedType(); } else if (S.IsComplexPromotion(FromType, ToType)) { // Complex promotion (Clang extension) SCS.Second = ICK_Complex_Promotion; FromType = ToType.getUnqualifiedType(); } else if (ToType->isBooleanType() && (FromType->isArithmeticType() || FromType->isAnyPointerType() || FromType->isBlockPointerType() || FromType->isMemberPointerType() || FromType->isNullPtrType())) { // Boolean conversions (C++ 4.12). SCS.Second = ICK_Boolean_Conversion; FromType = S.Context.BoolTy; } else if (FromType->isIntegralOrUnscopedEnumerationType() && ToType->isIntegralType(S.Context)) { // Integral conversions (C++ 4.7). SCS.Second = ICK_Integral_Conversion; FromType = ToType.getUnqualifiedType(); } else if (FromType->isAnyComplexType() && ToType->isAnyComplexType()) { // Complex conversions (C99 6.3.1.6) SCS.Second = ICK_Complex_Conversion; FromType = ToType.getUnqualifiedType(); } else if ((FromType->isAnyComplexType() && ToType->isArithmeticType()) || (ToType->isAnyComplexType() && FromType->isArithmeticType())) { // Complex-real conversions (C99 6.3.1.7) SCS.Second = ICK_Complex_Real; FromType = ToType.getUnqualifiedType(); } else if (FromType->isRealFloatingType() && ToType->isRealFloatingType()) { // FIXME: disable conversions between long double and __float128 if // their representation is different until there is back end support // We of course allow this conversion if long double is really double. if (&S.Context.getFloatTypeSemantics(FromType) != &S.Context.getFloatTypeSemantics(ToType)) { bool Float128AndLongDouble = ((FromType == S.Context.Float128Ty && ToType == S.Context.LongDoubleTy) || (FromType == S.Context.LongDoubleTy && ToType == S.Context.Float128Ty)); if (Float128AndLongDouble && (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) == &llvm::APFloat::PPCDoubleDouble())) return false; } // Floating point conversions (C++ 4.8). SCS.Second = ICK_Floating_Conversion; FromType = ToType.getUnqualifiedType(); } else if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || (FromType->isIntegralOrUnscopedEnumerationType() && ToType->isRealFloatingType())) { // Floating-integral conversions (C++ 4.9). SCS.Second = ICK_Floating_Integral; FromType = ToType.getUnqualifiedType(); } else if (S.IsBlockPointerConversion(FromType, ToType, FromType)) { SCS.Second = ICK_Block_Pointer_Conversion; } else if (AllowObjCWritebackConversion && S.isObjCWritebackConversion(FromType, ToType, FromType)) { SCS.Second = ICK_Writeback_Conversion; } else if (S.IsPointerConversion(From, FromType, ToType, InOverloadResolution, FromType, IncompatibleObjC)) { // Pointer conversions (C++ 4.10). SCS.Second = ICK_Pointer_Conversion; SCS.IncompatibleObjC = IncompatibleObjC; FromType = FromType.getUnqualifiedType(); } else if (S.IsMemberPointerConversion(From, FromType, ToType, InOverloadResolution, FromType)) { // Pointer to member conversions (4.11). SCS.Second = ICK_Pointer_Member; } else if (IsVectorConversion(S, FromType, ToType, SecondICK)) { SCS.Second = SecondICK; FromType = ToType.getUnqualifiedType(); } else if (!S.getLangOpts().CPlusPlus && S.Context.typesAreCompatible(ToType, FromType)) { // Compatible conversions (Clang extension for C function overloading) SCS.Second = ICK_Compatible_Conversion; FromType = ToType.getUnqualifiedType(); } else if (IsTransparentUnionStandardConversion(S, From, ToType, InOverloadResolution, SCS, CStyle)) { SCS.Second = ICK_TransparentUnionConversion; FromType = ToType; } else if (tryAtomicConversion(S, From, ToType, InOverloadResolution, SCS, CStyle)) { // tryAtomicConversion has updated the standard conversion sequence // appropriately. return true; } else if (ToType->isEventT() && From->isIntegerConstantExpr(S.getASTContext()) && From->EvaluateKnownConstInt(S.getASTContext()) == 0) { SCS.Second = ICK_Zero_Event_Conversion; FromType = ToType; } else if (ToType->isQueueT() && From->isIntegerConstantExpr(S.getASTContext()) && (From->EvaluateKnownConstInt(S.getASTContext()) == 0)) { SCS.Second = ICK_Zero_Queue_Conversion; FromType = ToType; } else if (ToType->isSamplerT() && From->isIntegerConstantExpr(S.getASTContext())) { SCS.Second = ICK_Compatible_Conversion; FromType = ToType; } else { // No second conversion required. SCS.Second = ICK_Identity; } SCS.setToType(1, FromType); // The third conversion can be a function pointer conversion or a // qualification conversion (C++ [conv.fctptr], [conv.qual]). bool ObjCLifetimeConversion; if (S.IsFunctionConversion(FromType, ToType, FromType)) { // Function pointer conversions (removing 'noexcept') including removal of // 'noreturn' (Clang extension). SCS.Third = ICK_Function_Conversion; } else if (S.IsQualificationConversion(FromType, ToType, CStyle, ObjCLifetimeConversion)) { SCS.Third = ICK_Qualification; SCS.QualificationIncludesObjCLifetime = ObjCLifetimeConversion; FromType = ToType; } else { // No conversion required SCS.Third = ICK_Identity; } // C++ [over.best.ics]p6: // [...] Any difference in top-level cv-qualification is // subsumed by the initialization itself and does not constitute // a conversion. [...] QualType CanonFrom = S.Context.getCanonicalType(FromType); QualType CanonTo = S.Context.getCanonicalType(ToType); if (CanonFrom.getLocalUnqualifiedType() == CanonTo.getLocalUnqualifiedType() && CanonFrom.getLocalQualifiers() != CanonTo.getLocalQualifiers()) { FromType = ToType; CanonFrom = CanonTo; } SCS.setToType(2, FromType); if (CanonFrom == CanonTo) return true; // If we have not converted the argument type to the parameter type, // this is a bad conversion sequence, unless we're resolving an overload in C. if (S.getLangOpts().CPlusPlus || !InOverloadResolution) return false; ExprResult ER = ExprResult{From}; Sema::AssignConvertType Conv = S.CheckSingleAssignmentConstraints(ToType, ER, /*Diagnose=*/false, /*DiagnoseCFAudited=*/false, /*ConvertRHS=*/false); ImplicitConversionKind SecondConv; switch (Conv) { case Sema::Compatible: SecondConv = ICK_C_Only_Conversion; break; // For our purposes, discarding qualifiers is just as bad as using an // incompatible pointer. Note that an IncompatiblePointer conversion can drop // qualifiers, as well. case Sema::CompatiblePointerDiscardsQualifiers: case Sema::IncompatiblePointer: case Sema::IncompatiblePointerSign: SecondConv = ICK_Incompatible_Pointer_Conversion; break; default: return false; } // First can only be an lvalue conversion, so we pretend that this was the // second conversion. First should already be valid from earlier in the // function. SCS.Second = SecondConv; SCS.setToType(1, ToType); // Third is Identity, because Second should rank us worse than any other // conversion. This could also be ICK_Qualification, but it's simpler to just // lump everything in with the second conversion, and we don't gain anything // from making this ICK_Qualification. SCS.Third = ICK_Identity; SCS.setToType(2, ToType); return true; } static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From, QualType &ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle) { const RecordType *UT = ToType->getAsUnionType(); if (!UT || !UT->getDecl()->hasAttr()) return false; // The field to initialize within the transparent union. RecordDecl *UD = UT->getDecl(); // It's compatible if the expression matches any of the fields. for (const auto *it : UD->fields()) { if (IsStandardConversion(S, From, it->getType(), InOverloadResolution, SCS, CStyle, /*AllowObjCWritebackConversion=*/false)) { ToType = it->getType(); return true; } } return false; } /// IsIntegralPromotion - Determines whether the conversion from the /// expression From (whose potentially-adjusted type is FromType) to /// ToType is an integral promotion (C++ 4.5). If so, returns true and /// sets PromotedType to the promoted type. bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { const BuiltinType *To = ToType->getAs(); // All integers are built-in. if (!To) { return false; } // An rvalue of type char, signed char, unsigned char, short int, or // unsigned short int can be converted to an rvalue of type int if // int can represent all the values of the source type; otherwise, // the source rvalue can be converted to an rvalue of type unsigned // int (C++ 4.5p1). if (FromType->isPromotableIntegerType() && !FromType->isBooleanType() && !FromType->isEnumeralType()) { if (// We can promote any signed, promotable integer type to an int (FromType->isSignedIntegerType() || // We can promote any unsigned integer type whose size is // less than int to an int. Context.getTypeSize(FromType) < Context.getTypeSize(ToType))) { return To->getKind() == BuiltinType::Int; } return To->getKind() == BuiltinType::UInt; } // C++11 [conv.prom]p3: // A prvalue of an unscoped enumeration type whose underlying type is not // fixed (7.2) can be converted to an rvalue a prvalue of the first of the // following types that can represent all the values of the enumeration // (i.e., the values in the range bmin to bmax as described in 7.2): int, // unsigned int, long int, unsigned long int, long long int, or unsigned // long long int. If none of the types in that list can represent all the // values of the enumeration, an rvalue a prvalue of an unscoped enumeration // type can be converted to an rvalue a prvalue of the extended integer type // with lowest integer conversion rank (4.13) greater than the rank of long // long in which all the values of the enumeration can be represented. If // there are two such extended types, the signed one is chosen. // C++11 [conv.prom]p4: // A prvalue of an unscoped enumeration type whose underlying type is fixed // can be converted to a prvalue of its underlying type. Moreover, if // integral promotion can be applied to its underlying type, a prvalue of an // unscoped enumeration type whose underlying type is fixed can also be // converted to a prvalue of the promoted underlying type. if (const EnumType *FromEnumType = FromType->getAs()) { // C++0x 7.2p9: Note that this implicit enum to int conversion is not // provided for a scoped enumeration. if (FromEnumType->getDecl()->isScoped()) return false; // We can perform an integral promotion to the underlying type of the enum, // even if that's not the promoted type. Note that the check for promoting // the underlying type is based on the type alone, and does not consider // the bitfield-ness of the actual source expression. if (FromEnumType->getDecl()->isFixed()) { QualType Underlying = FromEnumType->getDecl()->getIntegerType(); return Context.hasSameUnqualifiedType(Underlying, ToType) || IsIntegralPromotion(nullptr, Underlying, ToType); } // We have already pre-calculated the promotion type, so this is trivial. if (ToType->isIntegerType() && isCompleteType(From->getBeginLoc(), FromType)) return Context.hasSameUnqualifiedType( ToType, FromEnumType->getDecl()->getPromotionType()); // C++ [conv.prom]p5: // If the bit-field has an enumerated type, it is treated as any other // value of that type for promotion purposes. // // ... so do not fall through into the bit-field checks below in C++. if (getLangOpts().CPlusPlus) return false; } // C++0x [conv.prom]p2: // A prvalue of type char16_t, char32_t, or wchar_t (3.9.1) can be converted // to an rvalue a prvalue of the first of the following types that can // represent all the values of its underlying type: int, unsigned int, // long int, unsigned long int, long long int, or unsigned long long int. // If none of the types in that list can represent all the values of its // underlying type, an rvalue a prvalue of type char16_t, char32_t, // or wchar_t can be converted to an rvalue a prvalue of its underlying // type. if (FromType->isAnyCharacterType() && !FromType->isCharType() && ToType->isIntegerType()) { // Determine whether the type we're converting from is signed or // unsigned. bool FromIsSigned = FromType->isSignedIntegerType(); uint64_t FromSize = Context.getTypeSize(FromType); // The types we'll try to promote to, in the appropriate // order. Try each of these types. QualType PromoteTypes[6] = { Context.IntTy, Context.UnsignedIntTy, Context.LongTy, Context.UnsignedLongTy , Context.LongLongTy, Context.UnsignedLongLongTy }; for (int Idx = 0; Idx < 6; ++Idx) { uint64_t ToSize = Context.getTypeSize(PromoteTypes[Idx]); if (FromSize < ToSize || (FromSize == ToSize && FromIsSigned == PromoteTypes[Idx]->isSignedIntegerType())) { // We found the type that we can promote to. If this is the // type we wanted, we have a promotion. Otherwise, no // promotion. return Context.hasSameUnqualifiedType(ToType, PromoteTypes[Idx]); } } } // An rvalue for an integral bit-field (9.6) can be converted to an // rvalue of type int if int can represent all the values of the // bit-field; otherwise, it can be converted to unsigned int if // unsigned int can represent all the values of the bit-field. If // the bit-field is larger yet, no integral promotion applies to // it. If the bit-field has an enumerated type, it is treated as any // other value of that type for promotion purposes (C++ 4.5p3). // FIXME: We should delay checking of bit-fields until we actually perform the // conversion. // // FIXME: In C, only bit-fields of types _Bool, int, or unsigned int may be // promoted, per C11 6.3.1.1/2. We promote all bit-fields (including enum // bit-fields and those whose underlying type is larger than int) for GCC // compatibility. if (From) { if (FieldDecl *MemberDecl = From->getSourceBitField()) { llvm::APSInt BitWidth; if (FromType->isIntegralType(Context) && MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) { llvm::APSInt ToSize(BitWidth.getBitWidth(), BitWidth.isUnsigned()); ToSize = Context.getTypeSize(ToType); // Are we promoting to an int from a bitfield that fits in an int? if (BitWidth < ToSize || (FromType->isSignedIntegerType() && BitWidth <= ToSize)) { return To->getKind() == BuiltinType::Int; } // Are we promoting to an unsigned int from an unsigned bitfield // that fits into an unsigned int? if (FromType->isUnsignedIntegerType() && BitWidth <= ToSize) { return To->getKind() == BuiltinType::UInt; } return false; } } } // An rvalue of type bool can be converted to an rvalue of type int, // with false becoming zero and true becoming one (C++ 4.5p4). if (FromType->isBooleanType() && To->getKind() == BuiltinType::Int) { return true; } return false; } /// IsFloatingPointPromotion - Determines whether the conversion from /// FromType to ToType is a floating point promotion (C++ 4.6). If so, /// returns true and sets PromotedType to the promoted type. bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType) { if (const BuiltinType *FromBuiltin = FromType->getAs()) if (const BuiltinType *ToBuiltin = ToType->getAs()) { /// An rvalue of type float can be converted to an rvalue of type /// double. (C++ 4.6p1). if (FromBuiltin->getKind() == BuiltinType::Float && ToBuiltin->getKind() == BuiltinType::Double) return true; // C99 6.3.1.5p1: // When a float is promoted to double or long double, or a // double is promoted to long double [...]. if (!getLangOpts().CPlusPlus && (FromBuiltin->getKind() == BuiltinType::Float || FromBuiltin->getKind() == BuiltinType::Double) && (ToBuiltin->getKind() == BuiltinType::LongDouble || ToBuiltin->getKind() == BuiltinType::Float128)) return true; // Half can be promoted to float. if (!getLangOpts().NativeHalfType && FromBuiltin->getKind() == BuiltinType::Half && ToBuiltin->getKind() == BuiltinType::Float) return true; } return false; } /// Determine if a conversion is a complex promotion. /// /// A complex promotion is defined as a complex -> complex conversion /// where the conversion between the underlying real types is a /// floating-point or integral promotion. bool Sema::IsComplexPromotion(QualType FromType, QualType ToType) { const ComplexType *FromComplex = FromType->getAs(); if (!FromComplex) return false; const ComplexType *ToComplex = ToType->getAs(); if (!ToComplex) return false; return IsFloatingPointPromotion(FromComplex->getElementType(), ToComplex->getElementType()) || IsIntegralPromotion(nullptr, FromComplex->getElementType(), ToComplex->getElementType()); } /// BuildSimilarlyQualifiedPointerType - In a pointer conversion from /// the pointer type FromPtr to a pointer to type ToPointee, with the /// same type qualifiers as FromPtr has on its pointee type. ToType, /// if non-empty, will be a pointer to ToType that may or may not have /// the right set of qualifiers on its pointee. /// static QualType BuildSimilarlyQualifiedPointerType(const Type *FromPtr, QualType ToPointee, QualType ToType, ASTContext &Context, bool StripObjCLifetime = false) { assert((FromPtr->getTypeClass() == Type::Pointer || FromPtr->getTypeClass() == Type::ObjCObjectPointer) && "Invalid similarly-qualified pointer type"); /// Conversions to 'id' subsume cv-qualifier conversions. if (ToType->isObjCIdType() || ToType->isObjCQualifiedIdType()) return ToType.getUnqualifiedType(); QualType CanonFromPointee = Context.getCanonicalType(FromPtr->getPointeeType()); QualType CanonToPointee = Context.getCanonicalType(ToPointee); Qualifiers Quals = CanonFromPointee.getQualifiers(); if (StripObjCLifetime) Quals.removeObjCLifetime(); // Exact qualifier match -> return the pointer type we're converting to. if (CanonToPointee.getLocalQualifiers() == Quals) { // ToType is exactly what we need. Return it. if (!ToType.isNull()) return ToType.getUnqualifiedType(); // Build a pointer to ToPointee. It has the right qualifiers // already. if (isa(ToType)) return Context.getObjCObjectPointerType(ToPointee); return Context.getPointerType(ToPointee); } // Just build a canonical type that has the right qualifiers. QualType QualifiedCanonToPointee = Context.getQualifiedType(CanonToPointee.getLocalUnqualifiedType(), Quals); if (isa(ToType)) return Context.getObjCObjectPointerType(QualifiedCanonToPointee); return Context.getPointerType(QualifiedCanonToPointee); } static bool isNullPointerConstantForConversion(Expr *Expr, bool InOverloadResolution, ASTContext &Context) { // Handle value-dependent integral null pointer constants correctly. // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903 if (Expr->isValueDependent() && !Expr->isTypeDependent() && Expr->getType()->isIntegerType() && !Expr->getType()->isEnumeralType()) return !InOverloadResolution; return Expr->isNullPointerConstant(Context, InOverloadResolution? Expr::NPC_ValueDependentIsNotNull : Expr::NPC_ValueDependentIsNull); } /// IsPointerConversion - Determines whether the conversion of the /// expression From, which has the (possibly adjusted) type FromType, /// can be converted to the type ToType via a pointer conversion (C++ /// 4.10). If so, returns true and places the converted type (that /// might differ from ToType in its cv-qualifiers at some level) into /// ConvertedType. /// /// This routine also supports conversions to and from block pointers /// and conversions with Objective-C's 'id', 'id', and /// pointers to interfaces. FIXME: Once we've determined the /// appropriate overloading rules for Objective-C, we may want to /// split the Objective-C checks into a different routine; however, /// GCC seems to consider all of these conversions to be pointer /// conversions, so for now they live here. IncompatibleObjC will be /// set if the conversion is an allowed Objective-C conversion that /// should result in a warning. bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType, bool InOverloadResolution, QualType& ConvertedType, bool &IncompatibleObjC) { IncompatibleObjC = false; if (isObjCPointerConversion(FromType, ToType, ConvertedType, IncompatibleObjC)) return true; // Conversion from a null pointer constant to any Objective-C pointer type. if (ToType->isObjCObjectPointerType() && isNullPointerConstantForConversion(From, InOverloadResolution, Context)) { ConvertedType = ToType; return true; } // Blocks: Block pointers can be converted to void*. if (FromType->isBlockPointerType() && ToType->isPointerType() && ToType->castAs()->getPointeeType()->isVoidType()) { ConvertedType = ToType; return true; } // Blocks: A null pointer constant can be converted to a block // pointer type. if (ToType->isBlockPointerType() && isNullPointerConstantForConversion(From, InOverloadResolution, Context)) { ConvertedType = ToType; return true; } // If the left-hand-side is nullptr_t, the right side can be a null // pointer constant. if (ToType->isNullPtrType() && isNullPointerConstantForConversion(From, InOverloadResolution, Context)) { ConvertedType = ToType; return true; } const PointerType* ToTypePtr = ToType->getAs(); if (!ToTypePtr) return false; // A null pointer constant can be converted to a pointer type (C++ 4.10p1). if (isNullPointerConstantForConversion(From, InOverloadResolution, Context)) { ConvertedType = ToType; return true; } // Beyond this point, both types need to be pointers // , including objective-c pointers. QualType ToPointeeType = ToTypePtr->getPointeeType(); if (FromType->isObjCObjectPointerType() && ToPointeeType->isVoidType() && !getLangOpts().ObjCAutoRefCount) { ConvertedType = BuildSimilarlyQualifiedPointerType( FromType->getAs(), ToPointeeType, ToType, Context); return true; } const PointerType *FromTypePtr = FromType->getAs(); if (!FromTypePtr) return false; QualType FromPointeeType = FromTypePtr->getPointeeType(); // If the unqualified pointee types are the same, this can't be a // pointer conversion, so don't do all of the work below. if (Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) return false; // An rvalue of type "pointer to cv T," where T is an object type, // can be converted to an rvalue of type "pointer to cv void" (C++ // 4.10p2). if (FromPointeeType->isIncompleteOrObjectType() && ToPointeeType->isVoidType()) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context, /*StripObjCLifetime=*/true); return true; } // MSVC allows implicit function to void* type conversion. if (getLangOpts().MSVCCompat && FromPointeeType->isFunctionType() && ToPointeeType->isVoidType()) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context); return true; } // When we're overloading in C, we allow a special kind of pointer // conversion for compatible-but-not-identical pointee types. if (!getLangOpts().CPlusPlus && Context.typesAreCompatible(FromPointeeType, ToPointeeType)) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context); return true; } // C++ [conv.ptr]p3: // // An rvalue of type "pointer to cv D," where D is a class type, // can be converted to an rvalue of type "pointer to cv B," where // B is a base class (clause 10) of D. If B is an inaccessible // (clause 11) or ambiguous (10.2) base class of D, a program that // necessitates this conversion is ill-formed. The result of the // conversion is a pointer to the base class sub-object of the // derived class object. The null pointer value is converted to // the null pointer value of the destination type. // // Note that we do not check for ambiguity or inaccessibility // here. That is handled by CheckPointerConversion. if (getLangOpts().CPlusPlus && FromPointeeType->isRecordType() && ToPointeeType->isRecordType() && !Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType) && IsDerivedFrom(From->getBeginLoc(), FromPointeeType, ToPointeeType)) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context); return true; } if (FromPointeeType->isVectorType() && ToPointeeType->isVectorType() && Context.areCompatibleVectorTypes(FromPointeeType, ToPointeeType)) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context); return true; } return false; } /// Adopt the given qualifiers for the given type. static QualType AdoptQualifiers(ASTContext &Context, QualType T, Qualifiers Qs){ Qualifiers TQs = T.getQualifiers(); // Check whether qualifiers already match. if (TQs == Qs) return T; if (Qs.compatiblyIncludes(TQs)) return Context.getQualifiedType(T, Qs); return Context.getQualifiedType(T.getUnqualifiedType(), Qs); } /// isObjCPointerConversion - Determines whether this is an /// Objective-C pointer conversion. Subroutine of IsPointerConversion, /// with the same arguments and return values. bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, QualType& ConvertedType, bool &IncompatibleObjC) { if (!getLangOpts().ObjC) return false; // The set of qualifiers on the type we're converting from. Qualifiers FromQualifiers = FromType.getQualifiers(); // First, we handle all conversions on ObjC object pointer types. const ObjCObjectPointerType* ToObjCPtr = ToType->getAs(); const ObjCObjectPointerType *FromObjCPtr = FromType->getAs(); if (ToObjCPtr && FromObjCPtr) { // If the pointee types are the same (ignoring qualifications), // then this is not a pointer conversion. if (Context.hasSameUnqualifiedType(ToObjCPtr->getPointeeType(), FromObjCPtr->getPointeeType())) return false; // Conversion between Objective-C pointers. if (Context.canAssignObjCInterfaces(ToObjCPtr, FromObjCPtr)) { const ObjCInterfaceType* LHS = ToObjCPtr->getInterfaceType(); const ObjCInterfaceType* RHS = FromObjCPtr->getInterfaceType(); if (getLangOpts().CPlusPlus && LHS && RHS && !ToObjCPtr->getPointeeType().isAtLeastAsQualifiedAs( FromObjCPtr->getPointeeType())) return false; ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr, ToObjCPtr->getPointeeType(), ToType, Context); ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers); return true; } if (Context.canAssignObjCInterfaces(FromObjCPtr, ToObjCPtr)) { // Okay: this is some kind of implicit downcast of Objective-C // interfaces, which is permitted. However, we're going to // complain about it. IncompatibleObjC = true; ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr, ToObjCPtr->getPointeeType(), ToType, Context); ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers); return true; } } // Beyond this point, both types need to be C pointers or block pointers. QualType ToPointeeType; if (const PointerType *ToCPtr = ToType->getAs()) ToPointeeType = ToCPtr->getPointeeType(); else if (const BlockPointerType *ToBlockPtr = ToType->getAs()) { // Objective C++: We're able to convert from a pointer to any object // to a block pointer type. if (FromObjCPtr && FromObjCPtr->isObjCBuiltinType()) { ConvertedType = AdoptQualifiers(Context, ToType, FromQualifiers); return true; } ToPointeeType = ToBlockPtr->getPointeeType(); } else if (FromType->getAs() && ToObjCPtr && ToObjCPtr->isObjCBuiltinType()) { // Objective C++: We're able to convert from a block pointer type to a // pointer to any object. ConvertedType = AdoptQualifiers(Context, ToType, FromQualifiers); return true; } else return false; QualType FromPointeeType; if (const PointerType *FromCPtr = FromType->getAs()) FromPointeeType = FromCPtr->getPointeeType(); else if (const BlockPointerType *FromBlockPtr = FromType->getAs()) FromPointeeType = FromBlockPtr->getPointeeType(); else return false; // If we have pointers to pointers, recursively check whether this // is an Objective-C conversion. if (FromPointeeType->isPointerType() && ToPointeeType->isPointerType() && isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType, IncompatibleObjC)) { // We always complain about this conversion. IncompatibleObjC = true; ConvertedType = Context.getPointerType(ConvertedType); ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers); return true; } // Allow conversion of pointee being objective-c pointer to another one; // as in I* to id. if (FromPointeeType->getAs() && ToPointeeType->getAs() && isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType, IncompatibleObjC)) { ConvertedType = Context.getPointerType(ConvertedType); ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers); return true; } // If we have pointers to functions or blocks, check whether the only // differences in the argument and result types are in Objective-C // pointer conversions. If so, we permit the conversion (but // complain about it). const FunctionProtoType *FromFunctionType = FromPointeeType->getAs(); const FunctionProtoType *ToFunctionType = ToPointeeType->getAs(); if (FromFunctionType && ToFunctionType) { // If the function types are exactly the same, this isn't an // Objective-C pointer conversion. if (Context.getCanonicalType(FromPointeeType) == Context.getCanonicalType(ToPointeeType)) return false; // Perform the quick checks that will tell us whether these // function types are obviously different. if (FromFunctionType->getNumParams() != ToFunctionType->getNumParams() || FromFunctionType->isVariadic() != ToFunctionType->isVariadic() || FromFunctionType->getMethodQuals() != ToFunctionType->getMethodQuals()) return false; bool HasObjCConversion = false; if (Context.getCanonicalType(FromFunctionType->getReturnType()) == Context.getCanonicalType(ToFunctionType->getReturnType())) { // Okay, the types match exactly. Nothing to do. } else if (isObjCPointerConversion(FromFunctionType->getReturnType(), ToFunctionType->getReturnType(), ConvertedType, IncompatibleObjC)) { // Okay, we have an Objective-C pointer conversion. HasObjCConversion = true; } else { // Function types are too different. Abort. return false; } // Check argument types. for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumParams(); ArgIdx != NumArgs; ++ArgIdx) { QualType FromArgType = FromFunctionType->getParamType(ArgIdx); QualType ToArgType = ToFunctionType->getParamType(ArgIdx); if (Context.getCanonicalType(FromArgType) == Context.getCanonicalType(ToArgType)) { // Okay, the types match exactly. Nothing to do. } else if (isObjCPointerConversion(FromArgType, ToArgType, ConvertedType, IncompatibleObjC)) { // Okay, we have an Objective-C pointer conversion. HasObjCConversion = true; } else { // Argument types are too different. Abort. return false; } } if (HasObjCConversion) { // We had an Objective-C conversion. Allow this pointer // conversion, but complain about it. ConvertedType = AdoptQualifiers(Context, ToType, FromQualifiers); IncompatibleObjC = true; return true; } } return false; } /// Determine whether this is an Objective-C writeback conversion, /// used for parameter passing when performing automatic reference counting. /// /// \param FromType The type we're converting form. /// /// \param ToType The type we're converting to. /// /// \param ConvertedType The type that will be produced after applying /// this conversion. bool Sema::isObjCWritebackConversion(QualType FromType, QualType ToType, QualType &ConvertedType) { if (!getLangOpts().ObjCAutoRefCount || Context.hasSameUnqualifiedType(FromType, ToType)) return false; // Parameter must be a pointer to __autoreleasing (with no other qualifiers). QualType ToPointee; if (const PointerType *ToPointer = ToType->getAs()) ToPointee = ToPointer->getPointeeType(); else return false; Qualifiers ToQuals = ToPointee.getQualifiers(); if (!ToPointee->isObjCLifetimeType() || ToQuals.getObjCLifetime() != Qualifiers::OCL_Autoreleasing || !ToQuals.withoutObjCLifetime().empty()) return false; // Argument must be a pointer to __strong to __weak. QualType FromPointee; if (const PointerType *FromPointer = FromType->getAs()) FromPointee = FromPointer->getPointeeType(); else return false; Qualifiers FromQuals = FromPointee.getQualifiers(); if (!FromPointee->isObjCLifetimeType() || (FromQuals.getObjCLifetime() != Qualifiers::OCL_Strong && FromQuals.getObjCLifetime() != Qualifiers::OCL_Weak)) return false; // Make sure that we have compatible qualifiers. FromQuals.setObjCLifetime(Qualifiers::OCL_Autoreleasing); if (!ToQuals.compatiblyIncludes(FromQuals)) return false; // Remove qualifiers from the pointee type we're converting from; they // aren't used in the compatibility check belong, and we'll be adding back // qualifiers (with __autoreleasing) if the compatibility check succeeds. FromPointee = FromPointee.getUnqualifiedType(); // The unqualified form of the pointee types must be compatible. ToPointee = ToPointee.getUnqualifiedType(); bool IncompatibleObjC; if (Context.typesAreCompatible(FromPointee, ToPointee)) FromPointee = ToPointee; else if (!isObjCPointerConversion(FromPointee, ToPointee, FromPointee, IncompatibleObjC)) return false; /// Construct the type we're converting to, which is a pointer to /// __autoreleasing pointee. FromPointee = Context.getQualifiedType(FromPointee, FromQuals); ConvertedType = Context.getPointerType(FromPointee); return true; } bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType, QualType& ConvertedType) { QualType ToPointeeType; if (const BlockPointerType *ToBlockPtr = ToType->getAs()) ToPointeeType = ToBlockPtr->getPointeeType(); else return false; QualType FromPointeeType; if (const BlockPointerType *FromBlockPtr = FromType->getAs()) FromPointeeType = FromBlockPtr->getPointeeType(); else return false; // We have pointer to blocks, check whether the only // differences in the argument and result types are in Objective-C // pointer conversions. If so, we permit the conversion. const FunctionProtoType *FromFunctionType = FromPointeeType->getAs(); const FunctionProtoType *ToFunctionType = ToPointeeType->getAs(); if (!FromFunctionType || !ToFunctionType) return false; if (Context.hasSameType(FromPointeeType, ToPointeeType)) return true; // Perform the quick checks that will tell us whether these // function types are obviously different. if (FromFunctionType->getNumParams() != ToFunctionType->getNumParams() || FromFunctionType->isVariadic() != ToFunctionType->isVariadic()) return false; FunctionType::ExtInfo FromEInfo = FromFunctionType->getExtInfo(); FunctionType::ExtInfo ToEInfo = ToFunctionType->getExtInfo(); if (FromEInfo != ToEInfo) return false; bool IncompatibleObjC = false; if (Context.hasSameType(FromFunctionType->getReturnType(), ToFunctionType->getReturnType())) { // Okay, the types match exactly. Nothing to do. } else { QualType RHS = FromFunctionType->getReturnType(); QualType LHS = ToFunctionType->getReturnType(); if ((!getLangOpts().CPlusPlus || !RHS->isRecordType()) && !RHS.hasQualifiers() && LHS.hasQualifiers()) LHS = LHS.getUnqualifiedType(); if (Context.hasSameType(RHS,LHS)) { // OK exact match. } else if (isObjCPointerConversion(RHS, LHS, ConvertedType, IncompatibleObjC)) { if (IncompatibleObjC) return false; // Okay, we have an Objective-C pointer conversion. } else return false; } // Check argument types. for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumParams(); ArgIdx != NumArgs; ++ArgIdx) { IncompatibleObjC = false; QualType FromArgType = FromFunctionType->getParamType(ArgIdx); QualType ToArgType = ToFunctionType->getParamType(ArgIdx); if (Context.hasSameType(FromArgType, ToArgType)) { // Okay, the types match exactly. Nothing to do. } else if (isObjCPointerConversion(ToArgType, FromArgType, ConvertedType, IncompatibleObjC)) { if (IncompatibleObjC) return false; // Okay, we have an Objective-C pointer conversion. } else // Argument types are too different. Abort. return false; } SmallVector NewParamInfos; bool CanUseToFPT, CanUseFromFPT; if (!Context.mergeExtParameterInfo(ToFunctionType, FromFunctionType, CanUseToFPT, CanUseFromFPT, NewParamInfos)) return false; ConvertedType = ToType; return true; } enum { ft_default, ft_different_class, ft_parameter_arity, ft_parameter_mismatch, ft_return_type, ft_qualifer_mismatch, ft_noexcept }; /// Attempts to get the FunctionProtoType from a Type. Handles /// MemberFunctionPointers properly. static const FunctionProtoType *tryGetFunctionProtoType(QualType FromType) { if (auto *FPT = FromType->getAs()) return FPT; if (auto *MPT = FromType->getAs()) return MPT->getPointeeType()->getAs(); return nullptr; } /// HandleFunctionTypeMismatch - Gives diagnostic information for differeing /// function types. Catches different number of parameter, mismatch in /// parameter types, and different return types. void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, QualType FromType, QualType ToType) { // If either type is not valid, include no extra info. if (FromType.isNull() || ToType.isNull()) { PDiag << ft_default; return; } // Get the function type from the pointers. if (FromType->isMemberPointerType() && ToType->isMemberPointerType()) { const auto *FromMember = FromType->castAs(), *ToMember = ToType->castAs(); if (!Context.hasSameType(FromMember->getClass(), ToMember->getClass())) { PDiag << ft_different_class << QualType(ToMember->getClass(), 0) << QualType(FromMember->getClass(), 0); return; } FromType = FromMember->getPointeeType(); ToType = ToMember->getPointeeType(); } if (FromType->isPointerType()) FromType = FromType->getPointeeType(); if (ToType->isPointerType()) ToType = ToType->getPointeeType(); // Remove references. FromType = FromType.getNonReferenceType(); ToType = ToType.getNonReferenceType(); // Don't print extra info for non-specialized template functions. if (FromType->isInstantiationDependentType() && !FromType->getAs()) { PDiag << ft_default; return; } // No extra info for same types. if (Context.hasSameType(FromType, ToType)) { PDiag << ft_default; return; } const FunctionProtoType *FromFunction = tryGetFunctionProtoType(FromType), *ToFunction = tryGetFunctionProtoType(ToType); // Both types need to be function types. if (!FromFunction || !ToFunction) { PDiag << ft_default; return; } if (FromFunction->getNumParams() != ToFunction->getNumParams()) { PDiag << ft_parameter_arity << ToFunction->getNumParams() << FromFunction->getNumParams(); return; } // Handle different parameter types. unsigned ArgPos; if (!FunctionParamTypesAreEqual(FromFunction, ToFunction, &ArgPos)) { PDiag << ft_parameter_mismatch << ArgPos + 1 << ToFunction->getParamType(ArgPos) << FromFunction->getParamType(ArgPos); return; } // Handle different return type. if (!Context.hasSameType(FromFunction->getReturnType(), ToFunction->getReturnType())) { PDiag << ft_return_type << ToFunction->getReturnType() << FromFunction->getReturnType(); return; } if (FromFunction->getMethodQuals() != ToFunction->getMethodQuals()) { PDiag << ft_qualifer_mismatch << ToFunction->getMethodQuals() << FromFunction->getMethodQuals(); return; } // Handle exception specification differences on canonical type (in C++17 // onwards). if (cast(FromFunction->getCanonicalTypeUnqualified()) ->isNothrow() != cast(ToFunction->getCanonicalTypeUnqualified()) ->isNothrow()) { PDiag << ft_noexcept; return; } // Unable to find a difference, so add no extra info. PDiag << ft_default; } /// FunctionParamTypesAreEqual - This routine checks two function proto types /// for equality of their argument types. Caller has already checked that /// they have same number of arguments. If the parameters are different, /// ArgPos will have the parameter index of the first different parameter. bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType, const FunctionProtoType *NewType, unsigned *ArgPos) { for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(), N = NewType->param_type_begin(), E = OldType->param_type_end(); O && (O != E); ++O, ++N) { // Ignore address spaces in pointee type. This is to disallow overloading // on __ptr32/__ptr64 address spaces. QualType Old = Context.removePtrSizeAddrSpace(O->getUnqualifiedType()); QualType New = Context.removePtrSizeAddrSpace(N->getUnqualifiedType()); if (!Context.hasSameType(Old, New)) { if (ArgPos) *ArgPos = O - OldType->param_type_begin(); return false; } } return true; } /// CheckPointerConversion - Check the pointer conversion from the /// expression From to the type ToType. This routine checks for /// ambiguous or inaccessible derived-to-base pointer /// conversions for which IsPointerConversion has already returned /// true. It returns true and produces a diagnostic if there was an /// error, or returns false otherwise. bool Sema::CheckPointerConversion(Expr *From, QualType ToType, CastKind &Kind, CXXCastPath& BasePath, bool IgnoreBaseAccess, bool Diagnose) { QualType FromType = From->getType(); bool IsCStyleOrFunctionalCast = IgnoreBaseAccess; Kind = CK_BitCast; if (Diagnose && !IsCStyleOrFunctionalCast && !FromType->isAnyPointerType() && From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) == Expr::NPCK_ZeroExpression) { if (Context.hasSameUnqualifiedType(From->getType(), Context.BoolTy)) DiagRuntimeBehavior(From->getExprLoc(), From, PDiag(diag::warn_impcast_bool_to_null_pointer) << ToType << From->getSourceRange()); else if (!isUnevaluatedContext()) Diag(From->getExprLoc(), diag::warn_non_literal_null_pointer) << ToType << From->getSourceRange(); } if (const PointerType *ToPtrType = ToType->getAs()) { if (const PointerType *FromPtrType = FromType->getAs()) { QualType FromPointeeType = FromPtrType->getPointeeType(), ToPointeeType = ToPtrType->getPointeeType(); if (FromPointeeType->isRecordType() && ToPointeeType->isRecordType() && !Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) { // We must have a derived-to-base conversion. Check an // ambiguous or inaccessible conversion. unsigned InaccessibleID = 0; unsigned AmbigiousID = 0; if (Diagnose) { InaccessibleID = diag::err_upcast_to_inaccessible_base; AmbigiousID = diag::err_ambiguous_derived_to_base_conv; } if (CheckDerivedToBaseConversion( FromPointeeType, ToPointeeType, InaccessibleID, AmbigiousID, From->getExprLoc(), From->getSourceRange(), DeclarationName(), &BasePath, IgnoreBaseAccess)) return true; // The conversion was successful. Kind = CK_DerivedToBase; } if (Diagnose && !IsCStyleOrFunctionalCast && FromPointeeType->isFunctionType() && ToPointeeType->isVoidType()) { assert(getLangOpts().MSVCCompat && "this should only be possible with MSVCCompat!"); Diag(From->getExprLoc(), diag::ext_ms_impcast_fn_obj) << From->getSourceRange(); } } } else if (const ObjCObjectPointerType *ToPtrType = ToType->getAs()) { if (const ObjCObjectPointerType *FromPtrType = FromType->getAs()) { // Objective-C++ conversions are always okay. // FIXME: We should have a different class of conversions for the // Objective-C++ implicit conversions. if (FromPtrType->isObjCBuiltinType() || ToPtrType->isObjCBuiltinType()) return false; } else if (FromType->isBlockPointerType()) { Kind = CK_BlockPointerToObjCPointerCast; } else { Kind = CK_CPointerToObjCPointerCast; } } else if (ToType->isBlockPointerType()) { if (!FromType->isBlockPointerType()) Kind = CK_AnyPointerToBlockPointerCast; } // We shouldn't fall into this case unless it's valid for other // reasons. if (From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) Kind = CK_NullToPointer; return false; } /// IsMemberPointerConversion - Determines whether the conversion of the /// expression From, which has the (possibly adjusted) type FromType, can be /// converted to the type ToType via a member pointer conversion (C++ 4.11). /// If so, returns true and places the converted type (that might differ from /// ToType in its cv-qualifiers at some level) into ConvertedType. bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType, bool InOverloadResolution, QualType &ConvertedType) { const MemberPointerType *ToTypePtr = ToType->getAs(); if (!ToTypePtr) return false; // A null pointer constant can be converted to a member pointer (C++ 4.11p1) if (From->isNullPointerConstant(Context, InOverloadResolution? Expr::NPC_ValueDependentIsNotNull : Expr::NPC_ValueDependentIsNull)) { ConvertedType = ToType; return true; } // Otherwise, both types have to be member pointers. const MemberPointerType *FromTypePtr = FromType->getAs(); if (!FromTypePtr) return false; // A pointer to member of B can be converted to a pointer to member of D, // where D is derived from B (C++ 4.11p2). QualType FromClass(FromTypePtr->getClass(), 0); QualType ToClass(ToTypePtr->getClass(), 0); if (!Context.hasSameUnqualifiedType(FromClass, ToClass) && IsDerivedFrom(From->getBeginLoc(), ToClass, FromClass)) { ConvertedType = Context.getMemberPointerType(FromTypePtr->getPointeeType(), ToClass.getTypePtr()); return true; } return false; } /// CheckMemberPointerConversion - Check the member pointer conversion from the /// expression From to the type ToType. This routine checks for ambiguous or /// virtual or inaccessible base-to-derived member pointer conversions /// for which IsMemberPointerConversion has already returned true. It returns /// true and produces a diagnostic if there was an error, or returns false /// otherwise. bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType, CastKind &Kind, CXXCastPath &BasePath, bool IgnoreBaseAccess) { QualType FromType = From->getType(); const MemberPointerType *FromPtrType = FromType->getAs(); if (!FromPtrType) { // This must be a null pointer to member pointer conversion assert(From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull) && "Expr must be null pointer constant!"); Kind = CK_NullToMemberPointer; return false; } const MemberPointerType *ToPtrType = ToType->getAs(); assert(ToPtrType && "No member pointer cast has a target type " "that is not a member pointer."); QualType FromClass = QualType(FromPtrType->getClass(), 0); QualType ToClass = QualType(ToPtrType->getClass(), 0); // FIXME: What about dependent types? assert(FromClass->isRecordType() && "Pointer into non-class."); assert(ToClass->isRecordType() && "Pointer into non-class."); CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/true); bool DerivationOkay = IsDerivedFrom(From->getBeginLoc(), ToClass, FromClass, Paths); assert(DerivationOkay && "Should not have been called if derivation isn't OK."); (void)DerivationOkay; if (Paths.isAmbiguous(Context.getCanonicalType(FromClass). getUnqualifiedType())) { std::string PathDisplayStr = getAmbiguousPathsDisplayString(Paths); Diag(From->getExprLoc(), diag::err_ambiguous_memptr_conv) << 0 << FromClass << ToClass << PathDisplayStr << From->getSourceRange(); return true; } if (const RecordType *VBase = Paths.getDetectedVirtual()) { Diag(From->getExprLoc(), diag::err_memptr_conv_via_virtual) << FromClass << ToClass << QualType(VBase, 0) << From->getSourceRange(); return true; } if (!IgnoreBaseAccess) CheckBaseClassAccess(From->getExprLoc(), FromClass, ToClass, Paths.front(), diag::err_downcast_from_inaccessible_base); // Must be a base to derived member conversion. BuildBasePathArray(Paths, BasePath); Kind = CK_BaseToDerivedMemberPointer; return false; } /// Determine whether the lifetime conversion between the two given /// qualifiers sets is nontrivial. static bool isNonTrivialObjCLifetimeConversion(Qualifiers FromQuals, Qualifiers ToQuals) { // Converting anything to const __unsafe_unretained is trivial. if (ToQuals.hasConst() && ToQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone) return false; return true; } /// Perform a single iteration of the loop for checking if a qualification /// conversion is valid. /// /// Specifically, check whether any change between the qualifiers of \p /// FromType and \p ToType is permissible, given knowledge about whether every /// outer layer is const-qualified. static bool isQualificationConversionStep(QualType FromType, QualType ToType, bool CStyle, bool IsTopLevel, bool &PreviousToQualsIncludeConst, bool &ObjCLifetimeConversion) { Qualifiers FromQuals = FromType.getQualifiers(); Qualifiers ToQuals = ToType.getQualifiers(); // Ignore __unaligned qualifier if this type is void. if (ToType.getUnqualifiedType()->isVoidType()) FromQuals.removeUnaligned(); // Objective-C ARC: // Check Objective-C lifetime conversions. if (FromQuals.getObjCLifetime() != ToQuals.getObjCLifetime()) { if (ToQuals.compatiblyIncludesObjCLifetime(FromQuals)) { if (isNonTrivialObjCLifetimeConversion(FromQuals, ToQuals)) ObjCLifetimeConversion = true; FromQuals.removeObjCLifetime(); ToQuals.removeObjCLifetime(); } else { // Qualification conversions cannot cast between different // Objective-C lifetime qualifiers. return false; } } // Allow addition/removal of GC attributes but not changing GC attributes. if (FromQuals.getObjCGCAttr() != ToQuals.getObjCGCAttr() && (!FromQuals.hasObjCGCAttr() || !ToQuals.hasObjCGCAttr())) { FromQuals.removeObjCGCAttr(); ToQuals.removeObjCGCAttr(); } // -- for every j > 0, if const is in cv 1,j then const is in cv // 2,j, and similarly for volatile. if (!CStyle && !ToQuals.compatiblyIncludes(FromQuals)) return false; // If address spaces mismatch: // - in top level it is only valid to convert to addr space that is a // superset in all cases apart from C-style casts where we allow // conversions between overlapping address spaces. // - in non-top levels it is not a valid conversion. if (ToQuals.getAddressSpace() != FromQuals.getAddressSpace() && (!IsTopLevel || !(ToQuals.isAddressSpaceSupersetOf(FromQuals) || (CStyle && FromQuals.isAddressSpaceSupersetOf(ToQuals))))) return false; // -- if the cv 1,j and cv 2,j are different, then const is in // every cv for 0 < k < j. if (!CStyle && FromQuals.getCVRQualifiers() != ToQuals.getCVRQualifiers() && !PreviousToQualsIncludeConst) return false; // Keep track of whether all prior cv-qualifiers in the "to" type // include const. PreviousToQualsIncludeConst = PreviousToQualsIncludeConst && ToQuals.hasConst(); return true; } /// IsQualificationConversion - Determines whether the conversion from /// an rvalue of type FromType to ToType is a qualification conversion /// (C++ 4.4). /// /// \param ObjCLifetimeConversion Output parameter that will be set to indicate /// when the qualification conversion involves a change in the Objective-C /// object lifetime. bool Sema::IsQualificationConversion(QualType FromType, QualType ToType, bool CStyle, bool &ObjCLifetimeConversion) { FromType = Context.getCanonicalType(FromType); ToType = Context.getCanonicalType(ToType); ObjCLifetimeConversion = false; // If FromType and ToType are the same type, this is not a // qualification conversion. if (FromType.getUnqualifiedType() == ToType.getUnqualifiedType()) return false; // (C++ 4.4p4): // A conversion can add cv-qualifiers at levels other than the first // in multi-level pointers, subject to the following rules: [...] bool PreviousToQualsIncludeConst = true; bool UnwrappedAnyPointer = false; while (Context.UnwrapSimilarTypes(FromType, ToType)) { if (!isQualificationConversionStep( FromType, ToType, CStyle, !UnwrappedAnyPointer, PreviousToQualsIncludeConst, ObjCLifetimeConversion)) return false; UnwrappedAnyPointer = true; } // We are left with FromType and ToType being the pointee types // after unwrapping the original FromType and ToType the same number // of times. If we unwrapped any pointers, and if FromType and // ToType have the same unqualified type (since we checked // qualifiers above), then this is a qualification conversion. return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType); } /// - Determine whether this is a conversion from a scalar type to an /// atomic type. /// /// If successful, updates \c SCS's second and third steps in the conversion /// sequence to finish the conversion. static bool tryAtomicConversion(Sema &S, Expr *From, QualType ToType, bool InOverloadResolution, StandardConversionSequence &SCS, bool CStyle) { const AtomicType *ToAtomic = ToType->getAs(); if (!ToAtomic) return false; StandardConversionSequence InnerSCS; if (!IsStandardConversion(S, From, ToAtomic->getValueType(), InOverloadResolution, InnerSCS, CStyle, /*AllowObjCWritebackConversion=*/false)) return false; SCS.Second = InnerSCS.Second; SCS.setToType(1, InnerSCS.getToType(1)); SCS.Third = InnerSCS.Third; SCS.QualificationIncludesObjCLifetime = InnerSCS.QualificationIncludesObjCLifetime; SCS.setToType(2, InnerSCS.getToType(2)); return true; } static bool isFirstArgumentCompatibleWithType(ASTContext &Context, CXXConstructorDecl *Constructor, QualType Type) { const auto *CtorType = Constructor->getType()->castAs(); if (CtorType->getNumParams() > 0) { QualType FirstArg = CtorType->getParamType(0); if (Context.hasSameUnqualifiedType(Type, FirstArg.getNonReferenceType())) return true; } return false; } static OverloadingResult IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType, CXXRecordDecl *To, UserDefinedConversionSequence &User, OverloadCandidateSet &CandidateSet, bool AllowExplicit) { CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion); for (auto *D : S.LookupConstructors(To)) { auto Info = getConstructorInfo(D); if (!Info) continue; bool Usable = !Info.Constructor->isInvalidDecl() && S.isInitListConstructor(Info.Constructor); if (Usable) { // If the first argument is (a reference to) the target type, // suppress conversions. bool SuppressUserConversions = isFirstArgumentCompatibleWithType( S.Context, Info.Constructor, ToType); if (Info.ConstructorTmpl) S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl, /*ExplicitArgs*/ nullptr, From, CandidateSet, SuppressUserConversions, /*PartialOverloading*/ false, AllowExplicit); else S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, From, CandidateSet, SuppressUserConversions, /*PartialOverloading*/ false, AllowExplicit); } } bool HadMultipleCandidates = (CandidateSet.size() > 1); OverloadCandidateSet::iterator Best; switch (auto Result = CandidateSet.BestViableFunction(S, From->getBeginLoc(), Best)) { case OR_Deleted: case OR_Success: { // Record the standard conversion we used and the conversion function. CXXConstructorDecl *Constructor = cast(Best->Function); QualType ThisType = Constructor->getThisType(); // Initializer lists don't have conversions as such. User.Before.setAsIdentityConversion(); User.HadMultipleCandidates = HadMultipleCandidates; User.ConversionFunction = Constructor; User.FoundConversionFunction = Best->FoundDecl; User.After.setAsIdentityConversion(); User.After.setFromType(ThisType->castAs()->getPointeeType()); User.After.setAllToTypes(ToType); return Result; } case OR_No_Viable_Function: return OR_No_Viable_Function; case OR_Ambiguous: return OR_Ambiguous; } llvm_unreachable("Invalid OverloadResult!"); } /// Determines whether there is a user-defined conversion sequence /// (C++ [over.ics.user]) that converts expression From to the type /// ToType. If such a conversion exists, User will contain the /// user-defined conversion sequence that performs such a conversion /// and this routine will return true. Otherwise, this routine returns /// false and User is unspecified. /// /// \param AllowExplicit true if the conversion should consider C++0x /// "explicit" conversion functions as well as non-explicit conversion /// functions (C++0x [class.conv.fct]p2). /// /// \param AllowObjCConversionOnExplicit true if the conversion should /// allow an extra Objective-C pointer conversion on uses of explicit /// constructors. Requires \c AllowExplicit to also be set. static OverloadingResult IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, UserDefinedConversionSequence &User, OverloadCandidateSet &CandidateSet, bool AllowExplicit, bool AllowObjCConversionOnExplicit) { assert(AllowExplicit || !AllowObjCConversionOnExplicit); CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion); // Whether we will only visit constructors. bool ConstructorsOnly = false; // If the type we are conversion to is a class type, enumerate its // constructors. if (const RecordType *ToRecordType = ToType->getAs()) { // C++ [over.match.ctor]p1: // When objects of class type are direct-initialized (8.5), or // copy-initialized from an expression of the same or a // derived class type (8.5), overload resolution selects the // constructor. [...] For copy-initialization, the candidate // functions are all the converting constructors (12.3.1) of // that class. The argument list is the expression-list within // the parentheses of the initializer. if (S.Context.hasSameUnqualifiedType(ToType, From->getType()) || (From->getType()->getAs() && S.IsDerivedFrom(From->getBeginLoc(), From->getType(), ToType))) ConstructorsOnly = true; if (!S.isCompleteType(From->getExprLoc(), ToType)) { // We're not going to find any constructors. } else if (CXXRecordDecl *ToRecordDecl = dyn_cast(ToRecordType->getDecl())) { Expr **Args = &From; unsigned NumArgs = 1; bool ListInitializing = false; if (InitListExpr *InitList = dyn_cast(From)) { // But first, see if there is an init-list-constructor that will work. OverloadingResult Result = IsInitializerListConstructorConversion( S, From, ToType, ToRecordDecl, User, CandidateSet, AllowExplicit); if (Result != OR_No_Viable_Function) return Result; // Never mind. CandidateSet.clear( OverloadCandidateSet::CSK_InitByUserDefinedConversion); // If we're list-initializing, we pass the individual elements as // arguments, not the entire list. Args = InitList->getInits(); NumArgs = InitList->getNumInits(); ListInitializing = true; } for (auto *D : S.LookupConstructors(ToRecordDecl)) { auto Info = getConstructorInfo(D); if (!Info) continue; bool Usable = !Info.Constructor->isInvalidDecl(); if (!ListInitializing) Usable = Usable && Info.Constructor->isConvertingConstructor( /*AllowExplicit*/ true); if (Usable) { bool SuppressUserConversions = !ConstructorsOnly; if (SuppressUserConversions && ListInitializing) { SuppressUserConversions = false; if (NumArgs == 1) { // If the first argument is (a reference to) the target type, // suppress conversions. SuppressUserConversions = isFirstArgumentCompatibleWithType( S.Context, Info.Constructor, ToType); } } if (Info.ConstructorTmpl) S.AddTemplateOverloadCandidate( Info.ConstructorTmpl, Info.FoundDecl, /*ExplicitArgs*/ nullptr, llvm::makeArrayRef(Args, NumArgs), CandidateSet, SuppressUserConversions, /*PartialOverloading*/ false, AllowExplicit); else // Allow one user-defined conversion when user specifies a // From->ToType conversion via an static cast (c-style, etc). S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, llvm::makeArrayRef(Args, NumArgs), CandidateSet, SuppressUserConversions, /*PartialOverloading*/ false, AllowExplicit); } } } } // Enumerate conversion functions, if we're allowed to. if (ConstructorsOnly || isa(From)) { } else if (!S.isCompleteType(From->getBeginLoc(), From->getType())) { // No conversion functions from incomplete types. } else if (const RecordType *FromRecordType = From->getType()->getAs()) { if (CXXRecordDecl *FromRecordDecl = dyn_cast(FromRecordType->getDecl())) { // Add all of the conversion functions as candidates. const auto &Conversions = FromRecordDecl->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { DeclAccessPair FoundDecl = I.getPair(); NamedDecl *D = FoundDecl.getDecl(); CXXRecordDecl *ActingContext = cast(D->getDeclContext()); if (isa(D)) D = cast(D)->getTargetDecl(); CXXConversionDecl *Conv; FunctionTemplateDecl *ConvTemplate; if ((ConvTemplate = dyn_cast(D))) Conv = cast(ConvTemplate->getTemplatedDecl()); else Conv = cast(D); if (ConvTemplate) S.AddTemplateConversionCandidate( ConvTemplate, FoundDecl, ActingContext, From, ToType, CandidateSet, AllowObjCConversionOnExplicit, AllowExplicit); else S.AddConversionCandidate( Conv, FoundDecl, ActingContext, From, ToType, CandidateSet, AllowObjCConversionOnExplicit, AllowExplicit); } } } bool HadMultipleCandidates = (CandidateSet.size() > 1); OverloadCandidateSet::iterator Best; switch (auto Result = CandidateSet.BestViableFunction(S, From->getBeginLoc(), Best)) { case OR_Success: case OR_Deleted: // Record the standard conversion we used and the conversion function. if (CXXConstructorDecl *Constructor = dyn_cast(Best->Function)) { // C++ [over.ics.user]p1: // If the user-defined conversion is specified by a // constructor (12.3.1), the initial standard conversion // sequence converts the source type to the type required by // the argument of the constructor. // QualType ThisType = Constructor->getThisType(); if (isa(From)) { // Initializer lists don't have conversions as such. User.Before.setAsIdentityConversion(); } else { if (Best->Conversions[0].isEllipsis()) User.EllipsisConversion = true; else { User.Before = Best->Conversions[0].Standard; User.EllipsisConversion = false; } } User.HadMultipleCandidates = HadMultipleCandidates; User.ConversionFunction = Constructor; User.FoundConversionFunction = Best->FoundDecl; User.After.setAsIdentityConversion(); User.After.setFromType(ThisType->castAs()->getPointeeType()); User.After.setAllToTypes(ToType); return Result; } if (CXXConversionDecl *Conversion = dyn_cast(Best->Function)) { // C++ [over.ics.user]p1: // // [...] If the user-defined conversion is specified by a // conversion function (12.3.2), the initial standard // conversion sequence converts the source type to the // implicit object parameter of the conversion function. User.Before = Best->Conversions[0].Standard; User.HadMultipleCandidates = HadMultipleCandidates; User.ConversionFunction = Conversion; User.FoundConversionFunction = Best->FoundDecl; User.EllipsisConversion = false; // C++ [over.ics.user]p2: // The second standard conversion sequence converts the // result of the user-defined conversion to the target type // for the sequence. Since an implicit conversion sequence // is an initialization, the special rules for // initialization by user-defined conversion apply when // selecting the best user-defined conversion for a // user-defined conversion sequence (see 13.3.3 and // 13.3.3.1). User.After = Best->FinalConversion; return Result; } llvm_unreachable("Not a constructor or conversion function?"); case OR_No_Viable_Function: return OR_No_Viable_Function; case OR_Ambiguous: return OR_Ambiguous; } llvm_unreachable("Invalid OverloadResult!"); } bool Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) { ImplicitConversionSequence ICS; OverloadCandidateSet CandidateSet(From->getExprLoc(), OverloadCandidateSet::CSK_Normal); OverloadingResult OvResult = IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined, CandidateSet, false, false); if (!(OvResult == OR_Ambiguous || (OvResult == OR_No_Viable_Function && !CandidateSet.empty()))) return false; auto Cands = CandidateSet.CompleteCandidates( *this, OvResult == OR_Ambiguous ? OCD_AmbiguousCandidates : OCD_AllCandidates, From); if (OvResult == OR_Ambiguous) Diag(From->getBeginLoc(), diag::err_typecheck_ambiguous_condition) << From->getType() << ToType << From->getSourceRange(); else { // OR_No_Viable_Function && !CandidateSet.empty() if (!RequireCompleteType(From->getBeginLoc(), ToType, diag::err_typecheck_nonviable_condition_incomplete, From->getType(), From->getSourceRange())) Diag(From->getBeginLoc(), diag::err_typecheck_nonviable_condition) << false << From->getType() << From->getSourceRange() << ToType; } CandidateSet.NoteCandidates( *this, From, Cands); return true; } /// Compare the user-defined conversion functions or constructors /// of two user-defined conversion sequences to determine whether any ordering /// is possible. static ImplicitConversionSequence::CompareKind compareConversionFunctions(Sema &S, FunctionDecl *Function1, FunctionDecl *Function2) { if (!S.getLangOpts().ObjC || !S.getLangOpts().CPlusPlus11) return ImplicitConversionSequence::Indistinguishable; // Objective-C++: // If both conversion functions are implicitly-declared conversions from // a lambda closure type to a function pointer and a block pointer, // respectively, always prefer the conversion to a function pointer, // because the function pointer is more lightweight and is more likely // to keep code working. CXXConversionDecl *Conv1 = dyn_cast_or_null(Function1); if (!Conv1) return ImplicitConversionSequence::Indistinguishable; CXXConversionDecl *Conv2 = dyn_cast(Function2); if (!Conv2) return ImplicitConversionSequence::Indistinguishable; if (Conv1->getParent()->isLambda() && Conv2->getParent()->isLambda()) { bool Block1 = Conv1->getConversionType()->isBlockPointerType(); bool Block2 = Conv2->getConversionType()->isBlockPointerType(); if (Block1 != Block2) return Block1 ? ImplicitConversionSequence::Worse : ImplicitConversionSequence::Better; } return ImplicitConversionSequence::Indistinguishable; } static bool hasDeprecatedStringLiteralToCharPtrConversion( const ImplicitConversionSequence &ICS) { return (ICS.isStandard() && ICS.Standard.DeprecatedStringLiteralToCharPtr) || (ICS.isUserDefined() && ICS.UserDefined.Before.DeprecatedStringLiteralToCharPtr); } /// CompareImplicitConversionSequences - Compare two implicit /// conversion sequences to determine whether one is better than the /// other or if they are indistinguishable (C++ 13.3.3.2). static ImplicitConversionSequence::CompareKind CompareImplicitConversionSequences(Sema &S, SourceLocation Loc, const ImplicitConversionSequence& ICS1, const ImplicitConversionSequence& ICS2) { // (C++ 13.3.3.2p2): When comparing the basic forms of implicit // conversion sequences (as defined in 13.3.3.1) // -- a standard conversion sequence (13.3.3.1.1) is a better // conversion sequence than a user-defined conversion sequence or // an ellipsis conversion sequence, and // -- a user-defined conversion sequence (13.3.3.1.2) is a better // conversion sequence than an ellipsis conversion sequence // (13.3.3.1.3). // // C++0x [over.best.ics]p10: // For the purpose of ranking implicit conversion sequences as // described in 13.3.3.2, the ambiguous conversion sequence is // treated as a user-defined sequence that is indistinguishable // from any other user-defined conversion sequence. // String literal to 'char *' conversion has been deprecated in C++03. It has // been removed from C++11. We still accept this conversion, if it happens at // the best viable function. Otherwise, this conversion is considered worse // than ellipsis conversion. Consider this as an extension; this is not in the // standard. For example: // // int &f(...); // #1 // void f(char*); // #2 // void g() { int &r = f("foo"); } // // In C++03, we pick #2 as the best viable function. // In C++11, we pick #1 as the best viable function, because ellipsis // conversion is better than string-literal to char* conversion (since there // is no such conversion in C++11). If there was no #1 at all or #1 couldn't // convert arguments, #2 would be the best viable function in C++11. // If the best viable function has this conversion, a warning will be issued // in C++03, or an ExtWarn (+SFINAE failure) will be issued in C++11. if (S.getLangOpts().CPlusPlus11 && !S.getLangOpts().WritableStrings && hasDeprecatedStringLiteralToCharPtrConversion(ICS1) != hasDeprecatedStringLiteralToCharPtrConversion(ICS2)) return hasDeprecatedStringLiteralToCharPtrConversion(ICS1) ? ImplicitConversionSequence::Worse : ImplicitConversionSequence::Better; if (ICS1.getKindRank() < ICS2.getKindRank()) return ImplicitConversionSequence::Better; if (ICS2.getKindRank() < ICS1.getKindRank()) return ImplicitConversionSequence::Worse; // The following checks require both conversion sequences to be of // the same kind. if (ICS1.getKind() != ICS2.getKind()) return ImplicitConversionSequence::Indistinguishable; ImplicitConversionSequence::CompareKind Result = ImplicitConversionSequence::Indistinguishable; // Two implicit conversion sequences of the same form are // indistinguishable conversion sequences unless one of the // following rules apply: (C++ 13.3.3.2p3): // List-initialization sequence L1 is a better conversion sequence than // list-initialization sequence L2 if: // - L1 converts to std::initializer_list for some X and L2 does not, or, // if not that, // - L1 converts to type "array of N1 T", L2 converts to type "array of N2 T", // and N1 is smaller than N2., // even if one of the other rules in this paragraph would otherwise apply. if (!ICS1.isBad()) { if (ICS1.isStdInitializerListElement() && !ICS2.isStdInitializerListElement()) return ImplicitConversionSequence::Better; if (!ICS1.isStdInitializerListElement() && ICS2.isStdInitializerListElement()) return ImplicitConversionSequence::Worse; } if (ICS1.isStandard()) // Standard conversion sequence S1 is a better conversion sequence than // standard conversion sequence S2 if [...] Result = CompareStandardConversionSequences(S, Loc, ICS1.Standard, ICS2.Standard); else if (ICS1.isUserDefined()) { // User-defined conversion sequence U1 is a better conversion // sequence than another user-defined conversion sequence U2 if // they contain the same user-defined conversion function or // constructor and if the second standard conversion sequence of // U1 is better than the second standard conversion sequence of // U2 (C++ 13.3.3.2p3). if (ICS1.UserDefined.ConversionFunction == ICS2.UserDefined.ConversionFunction) Result = CompareStandardConversionSequences(S, Loc, ICS1.UserDefined.After, ICS2.UserDefined.After); else Result = compareConversionFunctions(S, ICS1.UserDefined.ConversionFunction, ICS2.UserDefined.ConversionFunction); } return Result; } // Per 13.3.3.2p3, compare the given standard conversion sequences to // determine if one is a proper subset of the other. static ImplicitConversionSequence::CompareKind compareStandardConversionSubsets(ASTContext &Context, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { ImplicitConversionSequence::CompareKind Result = ImplicitConversionSequence::Indistinguishable; // the identity conversion sequence is considered to be a subsequence of // any non-identity conversion sequence if (SCS1.isIdentityConversion() && !SCS2.isIdentityConversion()) return ImplicitConversionSequence::Better; else if (!SCS1.isIdentityConversion() && SCS2.isIdentityConversion()) return ImplicitConversionSequence::Worse; if (SCS1.Second != SCS2.Second) { if (SCS1.Second == ICK_Identity) Result = ImplicitConversionSequence::Better; else if (SCS2.Second == ICK_Identity) Result = ImplicitConversionSequence::Worse; else return ImplicitConversionSequence::Indistinguishable; } else if (!Context.hasSimilarType(SCS1.getToType(1), SCS2.getToType(1))) return ImplicitConversionSequence::Indistinguishable; if (SCS1.Third == SCS2.Third) { return Context.hasSameType(SCS1.getToType(2), SCS2.getToType(2))? Result : ImplicitConversionSequence::Indistinguishable; } if (SCS1.Third == ICK_Identity) return Result == ImplicitConversionSequence::Worse ? ImplicitConversionSequence::Indistinguishable : ImplicitConversionSequence::Better; if (SCS2.Third == ICK_Identity) return Result == ImplicitConversionSequence::Better ? ImplicitConversionSequence::Indistinguishable : ImplicitConversionSequence::Worse; return ImplicitConversionSequence::Indistinguishable; } /// Determine whether one of the given reference bindings is better /// than the other based on what kind of bindings they are. static bool isBetterReferenceBindingKind(const StandardConversionSequence &SCS1, const StandardConversionSequence &SCS2) { // C++0x [over.ics.rank]p3b4: // -- S1 and S2 are reference bindings (8.5.3) and neither refers to an // implicit object parameter of a non-static member function declared // without a ref-qualifier, and *either* S1 binds an rvalue reference // to an rvalue and S2 binds an lvalue reference *or S1 binds an // lvalue reference to a function lvalue and S2 binds an rvalue // reference*. // // FIXME: Rvalue references. We're going rogue with the above edits, // because the semantics in the current C++0x working paper (N3225 at the // time of this writing) break the standard definition of std::forward // and std::reference_wrapper when dealing with references to functions. // Proposed wording changes submitted to CWG for consideration. if (SCS1.BindsImplicitObjectArgumentWithoutRefQualifier || SCS2.BindsImplicitObjectArgumentWithoutRefQualifier) return false; return (!SCS1.IsLvalueReference && SCS1.BindsToRvalue && SCS2.IsLvalueReference) || (SCS1.IsLvalueReference && SCS1.BindsToFunctionLvalue && !SCS2.IsLvalueReference && SCS2.BindsToFunctionLvalue); } enum class FixedEnumPromotion { None, ToUnderlyingType, ToPromotedUnderlyingType }; /// Returns kind of fixed enum promotion the \a SCS uses. static FixedEnumPromotion getFixedEnumPromtion(Sema &S, const StandardConversionSequence &SCS) { if (SCS.Second != ICK_Integral_Promotion) return FixedEnumPromotion::None; QualType FromType = SCS.getFromType(); if (!FromType->isEnumeralType()) return FixedEnumPromotion::None; EnumDecl *Enum = FromType->getAs()->getDecl(); if (!Enum->isFixed()) return FixedEnumPromotion::None; QualType UnderlyingType = Enum->getIntegerType(); if (S.Context.hasSameType(SCS.getToType(1), UnderlyingType)) return FixedEnumPromotion::ToUnderlyingType; return FixedEnumPromotion::ToPromotedUnderlyingType; } /// CompareStandardConversionSequences - Compare two standard /// conversion sequences to determine whether one is better than the /// other or if they are indistinguishable (C++ 13.3.3.2p3). static ImplicitConversionSequence::CompareKind CompareStandardConversionSequences(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { // Standard conversion sequence S1 is a better conversion sequence // than standard conversion sequence S2 if (C++ 13.3.3.2p3): // -- S1 is a proper subsequence of S2 (comparing the conversion // sequences in the canonical form defined by 13.3.3.1.1, // excluding any Lvalue Transformation; the identity conversion // sequence is considered to be a subsequence of any // non-identity conversion sequence) or, if not that, if (ImplicitConversionSequence::CompareKind CK = compareStandardConversionSubsets(S.Context, SCS1, SCS2)) return CK; // -- the rank of S1 is better than the rank of S2 (by the rules // defined below), or, if not that, ImplicitConversionRank Rank1 = SCS1.getRank(); ImplicitConversionRank Rank2 = SCS2.getRank(); if (Rank1 < Rank2) return ImplicitConversionSequence::Better; else if (Rank2 < Rank1) return ImplicitConversionSequence::Worse; // (C++ 13.3.3.2p4): Two conversion sequences with the same rank // are indistinguishable unless one of the following rules // applies: // A conversion that is not a conversion of a pointer, or // pointer to member, to bool is better than another conversion // that is such a conversion. if (SCS1.isPointerConversionToBool() != SCS2.isPointerConversionToBool()) return SCS2.isPointerConversionToBool() ? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; // C++14 [over.ics.rank]p4b2: // This is retroactively applied to C++11 by CWG 1601. // // A conversion that promotes an enumeration whose underlying type is fixed // to its underlying type is better than one that promotes to the promoted // underlying type, if the two are different. FixedEnumPromotion FEP1 = getFixedEnumPromtion(S, SCS1); FixedEnumPromotion FEP2 = getFixedEnumPromtion(S, SCS2); if (FEP1 != FixedEnumPromotion::None && FEP2 != FixedEnumPromotion::None && FEP1 != FEP2) return FEP1 == FixedEnumPromotion::ToUnderlyingType ? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; // C++ [over.ics.rank]p4b2: // // If class B is derived directly or indirectly from class A, // conversion of B* to A* is better than conversion of B* to // void*, and conversion of A* to void* is better than conversion // of B* to void*. bool SCS1ConvertsToVoid = SCS1.isPointerConversionToVoidPointer(S.Context); bool SCS2ConvertsToVoid = SCS2.isPointerConversionToVoidPointer(S.Context); if (SCS1ConvertsToVoid != SCS2ConvertsToVoid) { // Exactly one of the conversion sequences is a conversion to // a void pointer; it's the worse conversion. return SCS2ConvertsToVoid ? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; } else if (!SCS1ConvertsToVoid && !SCS2ConvertsToVoid) { // Neither conversion sequence converts to a void pointer; compare // their derived-to-base conversions. if (ImplicitConversionSequence::CompareKind DerivedCK = CompareDerivedToBaseConversions(S, Loc, SCS1, SCS2)) return DerivedCK; } else if (SCS1ConvertsToVoid && SCS2ConvertsToVoid && !S.Context.hasSameType(SCS1.getFromType(), SCS2.getFromType())) { // Both conversion sequences are conversions to void // pointers. Compare the source types to determine if there's an // inheritance relationship in their sources. QualType FromType1 = SCS1.getFromType(); QualType FromType2 = SCS2.getFromType(); // Adjust the types we're converting from via the array-to-pointer // conversion, if we need to. if (SCS1.First == ICK_Array_To_Pointer) FromType1 = S.Context.getArrayDecayedType(FromType1); if (SCS2.First == ICK_Array_To_Pointer) FromType2 = S.Context.getArrayDecayedType(FromType2); QualType FromPointee1 = FromType1->getPointeeType().getUnqualifiedType(); QualType FromPointee2 = FromType2->getPointeeType().getUnqualifiedType(); if (S.IsDerivedFrom(Loc, FromPointee2, FromPointee1)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, FromPointee1, FromPointee2)) return ImplicitConversionSequence::Worse; // Objective-C++: If one interface is more specific than the // other, it is the better one. const ObjCObjectPointerType* FromObjCPtr1 = FromType1->getAs(); const ObjCObjectPointerType* FromObjCPtr2 = FromType2->getAs(); if (FromObjCPtr1 && FromObjCPtr2) { bool AssignLeft = S.Context.canAssignObjCInterfaces(FromObjCPtr1, FromObjCPtr2); bool AssignRight = S.Context.canAssignObjCInterfaces(FromObjCPtr2, FromObjCPtr1); if (AssignLeft != AssignRight) { return AssignLeft? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; } } } if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) { // Check for a better reference binding based on the kind of bindings. if (isBetterReferenceBindingKind(SCS1, SCS2)) return ImplicitConversionSequence::Better; else if (isBetterReferenceBindingKind(SCS2, SCS1)) return ImplicitConversionSequence::Worse; } // Compare based on qualification conversions (C++ 13.3.3.2p3, // bullet 3). if (ImplicitConversionSequence::CompareKind QualCK = CompareQualificationConversions(S, SCS1, SCS2)) return QualCK; if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) { // C++ [over.ics.rank]p3b4: // -- S1 and S2 are reference bindings (8.5.3), and the types to // which the references refer are the same type except for // top-level cv-qualifiers, and the type to which the reference // initialized by S2 refers is more cv-qualified than the type // to which the reference initialized by S1 refers. QualType T1 = SCS1.getToType(2); QualType T2 = SCS2.getToType(2); T1 = S.Context.getCanonicalType(T1); T2 = S.Context.getCanonicalType(T2); Qualifiers T1Quals, T2Quals; QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals); QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals); if (UnqualT1 == UnqualT2) { // Objective-C++ ARC: If the references refer to objects with different // lifetimes, prefer bindings that don't change lifetime. if (SCS1.ObjCLifetimeConversionBinding != SCS2.ObjCLifetimeConversionBinding) { return SCS1.ObjCLifetimeConversionBinding ? ImplicitConversionSequence::Worse : ImplicitConversionSequence::Better; } // If the type is an array type, promote the element qualifiers to the // type for comparison. if (isa(T1) && T1Quals) T1 = S.Context.getQualifiedType(UnqualT1, T1Quals); if (isa(T2) && T2Quals) T2 = S.Context.getQualifiedType(UnqualT2, T2Quals); if (T2.isMoreQualifiedThan(T1)) return ImplicitConversionSequence::Better; if (T1.isMoreQualifiedThan(T2)) return ImplicitConversionSequence::Worse; } } // In Microsoft mode, prefer an integral conversion to a // floating-to-integral conversion if the integral conversion // is between types of the same size. // For example: // void f(float); // void f(int); // int main { // long a; // f(a); // } // Here, MSVC will call f(int) instead of generating a compile error // as clang will do in standard mode. if (S.getLangOpts().MSVCCompat && SCS1.Second == ICK_Integral_Conversion && SCS2.Second == ICK_Floating_Integral && S.Context.getTypeSize(SCS1.getFromType()) == S.Context.getTypeSize(SCS1.getToType(2))) return ImplicitConversionSequence::Better; // Prefer a compatible vector conversion over a lax vector conversion // For example: // // typedef float __v4sf __attribute__((__vector_size__(16))); // void f(vector float); // void f(vector signed int); // int main() { // __v4sf a; // f(a); // } // Here, we'd like to choose f(vector float) and not // report an ambiguous call error if (SCS1.Second == ICK_Vector_Conversion && SCS2.Second == ICK_Vector_Conversion) { bool SCS1IsCompatibleVectorConversion = S.Context.areCompatibleVectorTypes( SCS1.getFromType(), SCS1.getToType(2)); bool SCS2IsCompatibleVectorConversion = S.Context.areCompatibleVectorTypes( SCS2.getFromType(), SCS2.getToType(2)); if (SCS1IsCompatibleVectorConversion != SCS2IsCompatibleVectorConversion) return SCS1IsCompatibleVectorConversion ? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; } return ImplicitConversionSequence::Indistinguishable; } /// CompareQualificationConversions - Compares two standard conversion /// sequences to determine whether they can be ranked based on their /// qualification conversions (C++ 13.3.3.2p3 bullet 3). static ImplicitConversionSequence::CompareKind CompareQualificationConversions(Sema &S, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { // C++ 13.3.3.2p3: // -- S1 and S2 differ only in their qualification conversion and // yield similar types T1 and T2 (C++ 4.4), respectively, and the // cv-qualification signature of type T1 is a proper subset of // the cv-qualification signature of type T2, and S1 is not the // deprecated string literal array-to-pointer conversion (4.2). if (SCS1.First != SCS2.First || SCS1.Second != SCS2.Second || SCS1.Third != SCS2.Third || SCS1.Third != ICK_Qualification) return ImplicitConversionSequence::Indistinguishable; // FIXME: the example in the standard doesn't use a qualification // conversion (!) QualType T1 = SCS1.getToType(2); QualType T2 = SCS2.getToType(2); T1 = S.Context.getCanonicalType(T1); T2 = S.Context.getCanonicalType(T2); assert(!T1->isReferenceType() && !T2->isReferenceType()); Qualifiers T1Quals, T2Quals; QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals); QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals); // If the types are the same, we won't learn anything by unwrapping // them. if (UnqualT1 == UnqualT2) return ImplicitConversionSequence::Indistinguishable; ImplicitConversionSequence::CompareKind Result = ImplicitConversionSequence::Indistinguishable; // Objective-C++ ARC: // Prefer qualification conversions not involving a change in lifetime // to qualification conversions that do not change lifetime. if (SCS1.QualificationIncludesObjCLifetime != SCS2.QualificationIncludesObjCLifetime) { Result = SCS1.QualificationIncludesObjCLifetime ? ImplicitConversionSequence::Worse : ImplicitConversionSequence::Better; } while (S.Context.UnwrapSimilarTypes(T1, T2)) { // Within each iteration of the loop, we check the qualifiers to // determine if this still looks like a qualification // conversion. Then, if all is well, we unwrap one more level of // pointers or pointers-to-members and do it all again // until there are no more pointers or pointers-to-members left // to unwrap. This essentially mimics what // IsQualificationConversion does, but here we're checking for a // strict subset of qualifiers. if (T1.getQualifiers().withoutObjCLifetime() == T2.getQualifiers().withoutObjCLifetime()) // The qualifiers are the same, so this doesn't tell us anything // about how the sequences rank. // ObjC ownership quals are omitted above as they interfere with // the ARC overload rule. ; else if (T2.isMoreQualifiedThan(T1)) { // T1 has fewer qualifiers, so it could be the better sequence. if (Result == ImplicitConversionSequence::Worse) // Neither has qualifiers that are a subset of the other's // qualifiers. return ImplicitConversionSequence::Indistinguishable; Result = ImplicitConversionSequence::Better; } else if (T1.isMoreQualifiedThan(T2)) { // T2 has fewer qualifiers, so it could be the better sequence. if (Result == ImplicitConversionSequence::Better) // Neither has qualifiers that are a subset of the other's // qualifiers. return ImplicitConversionSequence::Indistinguishable; Result = ImplicitConversionSequence::Worse; } else { // Qualifiers are disjoint. return ImplicitConversionSequence::Indistinguishable; } // If the types after this point are equivalent, we're done. if (S.Context.hasSameUnqualifiedType(T1, T2)) break; } // Check that the winning standard conversion sequence isn't using // the deprecated string literal array to pointer conversion. switch (Result) { case ImplicitConversionSequence::Better: if (SCS1.DeprecatedStringLiteralToCharPtr) Result = ImplicitConversionSequence::Indistinguishable; break; case ImplicitConversionSequence::Indistinguishable: break; case ImplicitConversionSequence::Worse: if (SCS2.DeprecatedStringLiteralToCharPtr) Result = ImplicitConversionSequence::Indistinguishable; break; } return Result; } /// CompareDerivedToBaseConversions - Compares two standard conversion /// sequences to determine whether they can be ranked based on their /// various kinds of derived-to-base conversions (C++ /// [over.ics.rank]p4b3). As part of these checks, we also look at /// conversions between Objective-C interface types. static ImplicitConversionSequence::CompareKind CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { QualType FromType1 = SCS1.getFromType(); QualType ToType1 = SCS1.getToType(1); QualType FromType2 = SCS2.getFromType(); QualType ToType2 = SCS2.getToType(1); // Adjust the types we're converting from via the array-to-pointer // conversion, if we need to. if (SCS1.First == ICK_Array_To_Pointer) FromType1 = S.Context.getArrayDecayedType(FromType1); if (SCS2.First == ICK_Array_To_Pointer) FromType2 = S.Context.getArrayDecayedType(FromType2); // Canonicalize all of the types. FromType1 = S.Context.getCanonicalType(FromType1); ToType1 = S.Context.getCanonicalType(ToType1); FromType2 = S.Context.getCanonicalType(FromType2); ToType2 = S.Context.getCanonicalType(ToType2); // C++ [over.ics.rank]p4b3: // // If class B is derived directly or indirectly from class A and // class C is derived directly or indirectly from B, // // Compare based on pointer conversions. if (SCS1.Second == ICK_Pointer_Conversion && SCS2.Second == ICK_Pointer_Conversion && /*FIXME: Remove if Objective-C id conversions get their own rank*/ FromType1->isPointerType() && FromType2->isPointerType() && ToType1->isPointerType() && ToType2->isPointerType()) { QualType FromPointee1 = FromType1->castAs()->getPointeeType().getUnqualifiedType(); QualType ToPointee1 = ToType1->castAs()->getPointeeType().getUnqualifiedType(); QualType FromPointee2 = FromType2->castAs()->getPointeeType().getUnqualifiedType(); QualType ToPointee2 = ToType2->castAs()->getPointeeType().getUnqualifiedType(); // -- conversion of C* to B* is better than conversion of C* to A*, if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) { if (S.IsDerivedFrom(Loc, ToPointee1, ToPointee2)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, ToPointee2, ToPointee1)) return ImplicitConversionSequence::Worse; } // -- conversion of B* to A* is better than conversion of C* to A*, if (FromPointee1 != FromPointee2 && ToPointee1 == ToPointee2) { if (S.IsDerivedFrom(Loc, FromPointee2, FromPointee1)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, FromPointee1, FromPointee2)) return ImplicitConversionSequence::Worse; } } else if (SCS1.Second == ICK_Pointer_Conversion && SCS2.Second == ICK_Pointer_Conversion) { const ObjCObjectPointerType *FromPtr1 = FromType1->getAs(); const ObjCObjectPointerType *FromPtr2 = FromType2->getAs(); const ObjCObjectPointerType *ToPtr1 = ToType1->getAs(); const ObjCObjectPointerType *ToPtr2 = ToType2->getAs(); if (FromPtr1 && FromPtr2 && ToPtr1 && ToPtr2) { // Apply the same conversion ranking rules for Objective-C pointer types // that we do for C++ pointers to class types. However, we employ the // Objective-C pseudo-subtyping relationship used for assignment of // Objective-C pointer types. bool FromAssignLeft = S.Context.canAssignObjCInterfaces(FromPtr1, FromPtr2); bool FromAssignRight = S.Context.canAssignObjCInterfaces(FromPtr2, FromPtr1); bool ToAssignLeft = S.Context.canAssignObjCInterfaces(ToPtr1, ToPtr2); bool ToAssignRight = S.Context.canAssignObjCInterfaces(ToPtr2, ToPtr1); // A conversion to an a non-id object pointer type or qualified 'id' // type is better than a conversion to 'id'. if (ToPtr1->isObjCIdType() && (ToPtr2->isObjCQualifiedIdType() || ToPtr2->getInterfaceDecl())) return ImplicitConversionSequence::Worse; if (ToPtr2->isObjCIdType() && (ToPtr1->isObjCQualifiedIdType() || ToPtr1->getInterfaceDecl())) return ImplicitConversionSequence::Better; // A conversion to a non-id object pointer type is better than a // conversion to a qualified 'id' type if (ToPtr1->isObjCQualifiedIdType() && ToPtr2->getInterfaceDecl()) return ImplicitConversionSequence::Worse; if (ToPtr2->isObjCQualifiedIdType() && ToPtr1->getInterfaceDecl()) return ImplicitConversionSequence::Better; // A conversion to an a non-Class object pointer type or qualified 'Class' // type is better than a conversion to 'Class'. if (ToPtr1->isObjCClassType() && (ToPtr2->isObjCQualifiedClassType() || ToPtr2->getInterfaceDecl())) return ImplicitConversionSequence::Worse; if (ToPtr2->isObjCClassType() && (ToPtr1->isObjCQualifiedClassType() || ToPtr1->getInterfaceDecl())) return ImplicitConversionSequence::Better; // A conversion to a non-Class object pointer type is better than a // conversion to a qualified 'Class' type. if (ToPtr1->isObjCQualifiedClassType() && ToPtr2->getInterfaceDecl()) return ImplicitConversionSequence::Worse; if (ToPtr2->isObjCQualifiedClassType() && ToPtr1->getInterfaceDecl()) return ImplicitConversionSequence::Better; // -- "conversion of C* to B* is better than conversion of C* to A*," if (S.Context.hasSameType(FromType1, FromType2) && !FromPtr1->isObjCIdType() && !FromPtr1->isObjCClassType() && (ToAssignLeft != ToAssignRight)) { if (FromPtr1->isSpecialized()) { // "conversion of B * to B * is better than conversion of B * to // C *. bool IsFirstSame = FromPtr1->getInterfaceDecl() == ToPtr1->getInterfaceDecl(); bool IsSecondSame = FromPtr1->getInterfaceDecl() == ToPtr2->getInterfaceDecl(); if (IsFirstSame) { if (!IsSecondSame) return ImplicitConversionSequence::Better; } else if (IsSecondSame) return ImplicitConversionSequence::Worse; } return ToAssignLeft? ImplicitConversionSequence::Worse : ImplicitConversionSequence::Better; } // -- "conversion of B* to A* is better than conversion of C* to A*," if (S.Context.hasSameUnqualifiedType(ToType1, ToType2) && (FromAssignLeft != FromAssignRight)) return FromAssignLeft? ImplicitConversionSequence::Better : ImplicitConversionSequence::Worse; } } // Ranking of member-pointer types. if (SCS1.Second == ICK_Pointer_Member && SCS2.Second == ICK_Pointer_Member && FromType1->isMemberPointerType() && FromType2->isMemberPointerType() && ToType1->isMemberPointerType() && ToType2->isMemberPointerType()) { const auto *FromMemPointer1 = FromType1->castAs(); const auto *ToMemPointer1 = ToType1->castAs(); const auto *FromMemPointer2 = FromType2->castAs(); const auto *ToMemPointer2 = ToType2->castAs(); const Type *FromPointeeType1 = FromMemPointer1->getClass(); const Type *ToPointeeType1 = ToMemPointer1->getClass(); const Type *FromPointeeType2 = FromMemPointer2->getClass(); const Type *ToPointeeType2 = ToMemPointer2->getClass(); QualType FromPointee1 = QualType(FromPointeeType1, 0).getUnqualifiedType(); QualType ToPointee1 = QualType(ToPointeeType1, 0).getUnqualifiedType(); QualType FromPointee2 = QualType(FromPointeeType2, 0).getUnqualifiedType(); QualType ToPointee2 = QualType(ToPointeeType2, 0).getUnqualifiedType(); // conversion of A::* to B::* is better than conversion of A::* to C::*, if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) { if (S.IsDerivedFrom(Loc, ToPointee1, ToPointee2)) return ImplicitConversionSequence::Worse; else if (S.IsDerivedFrom(Loc, ToPointee2, ToPointee1)) return ImplicitConversionSequence::Better; } // conversion of B::* to C::* is better than conversion of A::* to C::* if (ToPointee1 == ToPointee2 && FromPointee1 != FromPointee2) { if (S.IsDerivedFrom(Loc, FromPointee1, FromPointee2)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, FromPointee2, FromPointee1)) return ImplicitConversionSequence::Worse; } } if (SCS1.Second == ICK_Derived_To_Base) { // -- conversion of C to B is better than conversion of C to A, // -- binding of an expression of type C to a reference of type // B& is better than binding an expression of type C to a // reference of type A&, if (S.Context.hasSameUnqualifiedType(FromType1, FromType2) && !S.Context.hasSameUnqualifiedType(ToType1, ToType2)) { if (S.IsDerivedFrom(Loc, ToType1, ToType2)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, ToType2, ToType1)) return ImplicitConversionSequence::Worse; } // -- conversion of B to A is better than conversion of C to A. // -- binding of an expression of type B to a reference of type // A& is better than binding an expression of type C to a // reference of type A&, if (!S.Context.hasSameUnqualifiedType(FromType1, FromType2) && S.Context.hasSameUnqualifiedType(ToType1, ToType2)) { if (S.IsDerivedFrom(Loc, FromType2, FromType1)) return ImplicitConversionSequence::Better; else if (S.IsDerivedFrom(Loc, FromType1, FromType2)) return ImplicitConversionSequence::Worse; } } return ImplicitConversionSequence::Indistinguishable; } /// Determine whether the given type is valid, e.g., it is not an invalid /// C++ class. static bool isTypeValid(QualType T) { if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) return !Record->isInvalidDecl(); return true; } static QualType withoutUnaligned(ASTContext &Ctx, QualType T) { if (!T.getQualifiers().hasUnaligned()) return T; Qualifiers Q; T = Ctx.getUnqualifiedArrayType(T, Q); Q.removeUnaligned(); return Ctx.getQualifiedType(T, Q); } /// CompareReferenceRelationship - Compare the two types T1 and T2 to /// determine whether they are reference-compatible, /// reference-related, or incompatible, for use in C++ initialization by /// reference (C++ [dcl.ref.init]p4). Neither type can be a reference /// type, and the first type (T1) is the pointee type of the reference /// type being initialized. Sema::ReferenceCompareResult Sema::CompareReferenceRelationship(SourceLocation Loc, QualType OrigT1, QualType OrigT2, ReferenceConversions *ConvOut) { assert(!OrigT1->isReferenceType() && "T1 must be the pointee type of the reference type"); assert(!OrigT2->isReferenceType() && "T2 cannot be a reference type"); QualType T1 = Context.getCanonicalType(OrigT1); QualType T2 = Context.getCanonicalType(OrigT2); Qualifiers T1Quals, T2Quals; QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals); QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals); ReferenceConversions ConvTmp; ReferenceConversions &Conv = ConvOut ? *ConvOut : ConvTmp; Conv = ReferenceConversions(); // C++2a [dcl.init.ref]p4: // Given types "cv1 T1" and "cv2 T2," "cv1 T1" is // reference-related to "cv2 T2" if T1 is similar to T2, or // T1 is a base class of T2. // "cv1 T1" is reference-compatible with "cv2 T2" if // a prvalue of type "pointer to cv2 T2" can be converted to the type // "pointer to cv1 T1" via a standard conversion sequence. // Check for standard conversions we can apply to pointers: derived-to-base // conversions, ObjC pointer conversions, and function pointer conversions. // (Qualification conversions are checked last.) QualType ConvertedT2; if (UnqualT1 == UnqualT2) { // Nothing to do. } else if (isCompleteType(Loc, OrigT2) && isTypeValid(UnqualT1) && isTypeValid(UnqualT2) && IsDerivedFrom(Loc, UnqualT2, UnqualT1)) Conv |= ReferenceConversions::DerivedToBase; else if (UnqualT1->isObjCObjectOrInterfaceType() && UnqualT2->isObjCObjectOrInterfaceType() && Context.canBindObjCObjectType(UnqualT1, UnqualT2)) Conv |= ReferenceConversions::ObjC; else if (UnqualT2->isFunctionType() && IsFunctionConversion(UnqualT2, UnqualT1, ConvertedT2)) { Conv |= ReferenceConversions::Function; // No need to check qualifiers; function types don't have them. return Ref_Compatible; } bool ConvertedReferent = Conv != 0; // We can have a qualification conversion. Compute whether the types are // similar at the same time. bool PreviousToQualsIncludeConst = true; bool TopLevel = true; do { if (T1 == T2) break; // We will need a qualification conversion. Conv |= ReferenceConversions::Qualification; // Track whether we performed a qualification conversion anywhere other // than the top level. This matters for ranking reference bindings in // overload resolution. if (!TopLevel) Conv |= ReferenceConversions::NestedQualification; // MS compiler ignores __unaligned qualifier for references; do the same. T1 = withoutUnaligned(Context, T1); T2 = withoutUnaligned(Context, T2); // If we find a qualifier mismatch, the types are not reference-compatible, // but are still be reference-related if they're similar. bool ObjCLifetimeConversion = false; if (!isQualificationConversionStep(T2, T1, /*CStyle=*/false, TopLevel, PreviousToQualsIncludeConst, ObjCLifetimeConversion)) return (ConvertedReferent || Context.hasSimilarType(T1, T2)) ? Ref_Related : Ref_Incompatible; // FIXME: Should we track this for any level other than the first? if (ObjCLifetimeConversion) Conv |= ReferenceConversions::ObjCLifetime; TopLevel = false; } while (Context.UnwrapSimilarTypes(T1, T2)); // At this point, if the types are reference-related, we must either have the // same inner type (ignoring qualifiers), or must have already worked out how // to convert the referent. return (ConvertedReferent || Context.hasSameUnqualifiedType(T1, T2)) ? Ref_Compatible : Ref_Incompatible; } /// Look for a user-defined conversion to a value reference-compatible /// with DeclType. Return true if something definite is found. static bool FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS, QualType DeclType, SourceLocation DeclLoc, Expr *Init, QualType T2, bool AllowRvalues, bool AllowExplicit) { assert(T2->isRecordType() && "Can only find conversions of record types."); auto *T2RecordDecl = cast(T2->castAs()->getDecl()); OverloadCandidateSet CandidateSet( DeclLoc, OverloadCandidateSet::CSK_InitByUserDefinedConversion); const auto &Conversions = T2RecordDecl->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { NamedDecl *D = *I; CXXRecordDecl *ActingDC = cast(D->getDeclContext()); if (isa(D)) D = cast(D)->getTargetDecl(); FunctionTemplateDecl *ConvTemplate = dyn_cast(D); CXXConversionDecl *Conv; if (ConvTemplate) Conv = cast(ConvTemplate->getTemplatedDecl()); else Conv = cast(D); if (AllowRvalues) { // If we are initializing an rvalue reference, don't permit conversion // functions that return lvalues. if (!ConvTemplate && DeclType->isRValueReferenceType()) { const ReferenceType *RefType = Conv->getConversionType()->getAs(); if (RefType && !RefType->getPointeeType()->isFunctionType()) continue; } if (!ConvTemplate && S.CompareReferenceRelationship( DeclLoc, Conv->getConversionType() .getNonReferenceType() .getUnqualifiedType(), DeclType.getNonReferenceType().getUnqualifiedType()) == Sema::Ref_Incompatible) continue; } else { // If the conversion function doesn't return a reference type, // it can't be considered for this conversion. An rvalue reference // is only acceptable if its referencee is a function type. const ReferenceType *RefType = Conv->getConversionType()->getAs(); if (!RefType || (!RefType->isLValueReferenceType() && !RefType->getPointeeType()->isFunctionType())) continue; } if (ConvTemplate) S.AddTemplateConversionCandidate( ConvTemplate, I.getPair(), ActingDC, Init, DeclType, CandidateSet, /*AllowObjCConversionOnExplicit=*/false, AllowExplicit); else S.AddConversionCandidate( Conv, I.getPair(), ActingDC, Init, DeclType, CandidateSet, /*AllowObjCConversionOnExplicit=*/false, AllowExplicit); } bool HadMultipleCandidates = (CandidateSet.size() > 1); OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(S, DeclLoc, Best)) { case OR_Success: // C++ [over.ics.ref]p1: // // [...] If the parameter binds directly to the result of // applying a conversion function to the argument // expression, the implicit conversion sequence is a // user-defined conversion sequence (13.3.3.1.2), with the // second standard conversion sequence either an identity // conversion or, if the conversion function returns an // entity of a type that is a derived class of the parameter // type, a derived-to-base Conversion. if (!Best->FinalConversion.DirectBinding) return false; ICS.setUserDefined(); ICS.UserDefined.Before = Best->Conversions[0].Standard; ICS.UserDefined.After = Best->FinalConversion; ICS.UserDefined.HadMultipleCandidates = HadMultipleCandidates; ICS.UserDefined.ConversionFunction = Best->Function; ICS.UserDefined.FoundConversionFunction = Best->FoundDecl; ICS.UserDefined.EllipsisConversion = false; assert(ICS.UserDefined.After.ReferenceBinding && ICS.UserDefined.After.DirectBinding && "Expected a direct reference binding!"); return true; case OR_Ambiguous: ICS.setAmbiguous(); for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(); Cand != CandidateSet.end(); ++Cand) if (Cand->Best) ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function); return true; case OR_No_Viable_Function: case OR_Deleted: // There was no suitable conversion, or we found a deleted // conversion; continue with other checks. return false; } llvm_unreachable("Invalid OverloadResult!"); } /// Compute an implicit conversion sequence for reference /// initialization. static ImplicitConversionSequence TryReferenceInit(Sema &S, Expr *Init, QualType DeclType, SourceLocation DeclLoc, bool SuppressUserConversions, bool AllowExplicit) { assert(DeclType->isReferenceType() && "Reference init needs a reference"); // Most paths end in a failed conversion. ImplicitConversionSequence ICS; ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType); QualType T1 = DeclType->castAs()->getPointeeType(); QualType T2 = Init->getType(); // If the initializer is the address of an overloaded function, try // to resolve the overloaded function. If all goes well, T2 is the // type of the resulting function. if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) { DeclAccessPair Found; if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Init, DeclType, false, Found)) T2 = Fn->getType(); } // Compute some basic properties of the types and the initializer. bool isRValRef = DeclType->isRValueReferenceType(); Expr::Classification InitCategory = Init->Classify(S.Context); Sema::ReferenceConversions RefConv; Sema::ReferenceCompareResult RefRelationship = S.CompareReferenceRelationship(DeclLoc, T1, T2, &RefConv); auto SetAsReferenceBinding = [&](bool BindsDirectly) { ICS.setStandard(); ICS.Standard.First = ICK_Identity; // FIXME: A reference binding can be a function conversion too. We should // consider that when ordering reference-to-function bindings. ICS.Standard.Second = (RefConv & Sema::ReferenceConversions::DerivedToBase) ? ICK_Derived_To_Base : (RefConv & Sema::ReferenceConversions::ObjC) ? ICK_Compatible_Conversion : ICK_Identity; // FIXME: As a speculative fix to a defect introduced by CWG2352, we rank // a reference binding that performs a non-top-level qualification // conversion as a qualification conversion, not as an identity conversion. ICS.Standard.Third = (RefConv & Sema::ReferenceConversions::NestedQualification) ? ICK_Qualification : ICK_Identity; - ICS.Standard.FromTypePtr = T2.getAsOpaquePtr(); + ICS.Standard.setFromType(T2); ICS.Standard.setToType(0, T2); ICS.Standard.setToType(1, T1); ICS.Standard.setToType(2, T1); ICS.Standard.ReferenceBinding = true; ICS.Standard.DirectBinding = BindsDirectly; ICS.Standard.IsLvalueReference = !isRValRef; ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType(); ICS.Standard.BindsToRvalue = InitCategory.isRValue(); ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false; ICS.Standard.ObjCLifetimeConversionBinding = (RefConv & Sema::ReferenceConversions::ObjCLifetime) != 0; ICS.Standard.CopyConstructor = nullptr; ICS.Standard.DeprecatedStringLiteralToCharPtr = false; }; // C++0x [dcl.init.ref]p5: // A reference to type "cv1 T1" is initialized by an expression // of type "cv2 T2" as follows: // -- If reference is an lvalue reference and the initializer expression if (!isRValRef) { // -- is an lvalue (but is not a bit-field), and "cv1 T1" is // reference-compatible with "cv2 T2," or // // Per C++ [over.ics.ref]p4, we don't check the bit-field property here. if (InitCategory.isLValue() && RefRelationship == Sema::Ref_Compatible) { // C++ [over.ics.ref]p1: // When a parameter of reference type binds directly (8.5.3) // to an argument expression, the implicit conversion sequence // is the identity conversion, unless the argument expression // has a type that is a derived class of the parameter type, // in which case the implicit conversion sequence is a // derived-to-base Conversion (13.3.3.1). SetAsReferenceBinding(/*BindsDirectly=*/true); // Nothing more to do: the inaccessibility/ambiguity check for // derived-to-base conversions is suppressed when we're // computing the implicit conversion sequence (C++ // [over.best.ics]p2). return ICS; } // -- has a class type (i.e., T2 is a class type), where T1 is // not reference-related to T2, and can be implicitly // converted to an lvalue of type "cv3 T3," where "cv1 T1" // is reference-compatible with "cv3 T3" 92) (this // conversion is selected by enumerating the applicable // conversion functions (13.3.1.6) and choosing the best // one through overload resolution (13.3)), if (!SuppressUserConversions && T2->isRecordType() && S.isCompleteType(DeclLoc, T2) && RefRelationship == Sema::Ref_Incompatible) { if (FindConversionForRefInit(S, ICS, DeclType, DeclLoc, Init, T2, /*AllowRvalues=*/false, AllowExplicit)) return ICS; } } // -- Otherwise, the reference shall be an lvalue reference to a // non-volatile const type (i.e., cv1 shall be const), or the reference // shall be an rvalue reference. if (!isRValRef && (!T1.isConstQualified() || T1.isVolatileQualified())) return ICS; // -- If the initializer expression // // -- is an xvalue, class prvalue, array prvalue or function // lvalue and "cv1 T1" is reference-compatible with "cv2 T2", or if (RefRelationship == Sema::Ref_Compatible && (InitCategory.isXValue() || (InitCategory.isPRValue() && (T2->isRecordType() || T2->isArrayType())) || (InitCategory.isLValue() && T2->isFunctionType()))) { // In C++11, this is always a direct binding. In C++98/03, it's a direct // binding unless we're binding to a class prvalue. // Note: Although xvalues wouldn't normally show up in C++98/03 code, we // allow the use of rvalue references in C++98/03 for the benefit of // standard library implementors; therefore, we need the xvalue check here. SetAsReferenceBinding(/*BindsDirectly=*/S.getLangOpts().CPlusPlus11 || !(InitCategory.isPRValue() || T2->isRecordType())); return ICS; } // -- has a class type (i.e., T2 is a class type), where T1 is not // reference-related to T2, and can be implicitly converted to // an xvalue, class prvalue, or function lvalue of type // "cv3 T3", where "cv1 T1" is reference-compatible with // "cv3 T3", // // then the reference is bound to the value of the initializer // expression in the first case and to the result of the conversion // in the second case (or, in either case, to an appropriate base // class subobject). if (!SuppressUserConversions && RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() && S.isCompleteType(DeclLoc, T2) && FindConversionForRefInit(S, ICS, DeclType, DeclLoc, Init, T2, /*AllowRvalues=*/true, AllowExplicit)) { // In the second case, if the reference is an rvalue reference // and the second standard conversion sequence of the // user-defined conversion sequence includes an lvalue-to-rvalue // conversion, the program is ill-formed. if (ICS.isUserDefined() && isRValRef && ICS.UserDefined.After.First == ICK_Lvalue_To_Rvalue) ICS.setBad(BadConversionSequence::no_conversion, Init, DeclType); return ICS; } // A temporary of function type cannot be created; don't even try. if (T1->isFunctionType()) return ICS; // -- Otherwise, a temporary of type "cv1 T1" is created and // initialized from the initializer expression using the // rules for a non-reference copy initialization (8.5). The // reference is then bound to the temporary. If T1 is // reference-related to T2, cv1 must be the same // cv-qualification as, or greater cv-qualification than, // cv2; otherwise, the program is ill-formed. if (RefRelationship == Sema::Ref_Related) { // If cv1 == cv2 or cv1 is a greater cv-qualified than cv2, then // we would be reference-compatible or reference-compatible with // added qualification. But that wasn't the case, so the reference // initialization fails. // // Note that we only want to check address spaces and cvr-qualifiers here. // ObjC GC, lifetime and unaligned qualifiers aren't important. Qualifiers T1Quals = T1.getQualifiers(); Qualifiers T2Quals = T2.getQualifiers(); T1Quals.removeObjCGCAttr(); T1Quals.removeObjCLifetime(); T2Quals.removeObjCGCAttr(); T2Quals.removeObjCLifetime(); // MS compiler ignores __unaligned qualifier for references; do the same. T1Quals.removeUnaligned(); T2Quals.removeUnaligned(); if (!T1Quals.compatiblyIncludes(T2Quals)) return ICS; } // If at least one of the types is a class type, the types are not // related, and we aren't allowed any user conversions, the // reference binding fails. This case is important for breaking // recursion, since TryImplicitConversion below will attempt to // create a temporary through the use of a copy constructor. if (SuppressUserConversions && RefRelationship == Sema::Ref_Incompatible && (T1->isRecordType() || T2->isRecordType())) return ICS; // If T1 is reference-related to T2 and the reference is an rvalue // reference, the initializer expression shall not be an lvalue. if (RefRelationship >= Sema::Ref_Related && isRValRef && Init->Classify(S.Context).isLValue()) return ICS; // C++ [over.ics.ref]p2: // When a parameter of reference type is not bound directly to // an argument expression, the conversion sequence is the one // required to convert the argument expression to the // underlying type of the reference according to // 13.3.3.1. Conceptually, this conversion sequence corresponds // to copy-initializing a temporary of the underlying type with // the argument expression. Any difference in top-level // cv-qualification is subsumed by the initialization itself // and does not constitute a conversion. ICS = TryImplicitConversion(S, Init, T1, SuppressUserConversions, /*AllowExplicit=*/false, /*InOverloadResolution=*/false, /*CStyle=*/false, /*AllowObjCWritebackConversion=*/false, /*AllowObjCConversionOnExplicit=*/false); // Of course, that's still a reference binding. if (ICS.isStandard()) { ICS.Standard.ReferenceBinding = true; ICS.Standard.IsLvalueReference = !isRValRef; ICS.Standard.BindsToFunctionLvalue = false; ICS.Standard.BindsToRvalue = true; ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false; ICS.Standard.ObjCLifetimeConversionBinding = false; } else if (ICS.isUserDefined()) { const ReferenceType *LValRefType = ICS.UserDefined.ConversionFunction->getReturnType() ->getAs(); // C++ [over.ics.ref]p3: // Except for an implicit object parameter, for which see 13.3.1, a // standard conversion sequence cannot be formed if it requires [...] // binding an rvalue reference to an lvalue other than a function // lvalue. // Note that the function case is not possible here. if (DeclType->isRValueReferenceType() && LValRefType) { // FIXME: This is the wrong BadConversionSequence. The problem is binding // an rvalue reference to a (non-function) lvalue, not binding an lvalue // reference to an rvalue! ICS.setBad(BadConversionSequence::lvalue_ref_to_rvalue, Init, DeclType); return ICS; } ICS.UserDefined.After.ReferenceBinding = true; ICS.UserDefined.After.IsLvalueReference = !isRValRef; ICS.UserDefined.After.BindsToFunctionLvalue = false; ICS.UserDefined.After.BindsToRvalue = !LValRefType; ICS.UserDefined.After.BindsImplicitObjectArgumentWithoutRefQualifier = false; ICS.UserDefined.After.ObjCLifetimeConversionBinding = false; } return ICS; } static ImplicitConversionSequence TryCopyInitialization(Sema &S, Expr *From, QualType ToType, bool SuppressUserConversions, bool InOverloadResolution, bool AllowObjCWritebackConversion, bool AllowExplicit = false); /// TryListConversion - Try to copy-initialize a value of type ToType from the /// initializer list From. static ImplicitConversionSequence TryListConversion(Sema &S, InitListExpr *From, QualType ToType, bool SuppressUserConversions, bool InOverloadResolution, bool AllowObjCWritebackConversion) { // C++11 [over.ics.list]p1: // When an argument is an initializer list, it is not an expression and // special rules apply for converting it to a parameter type. ImplicitConversionSequence Result; Result.setBad(BadConversionSequence::no_conversion, From, ToType); // We need a complete type for what follows. Incomplete types can never be // initialized from init lists. if (!S.isCompleteType(From->getBeginLoc(), ToType)) return Result; // Per DR1467: // If the parameter type is a class X and the initializer list has a single // element of type cv U, where U is X or a class derived from X, the // implicit conversion sequence is the one required to convert the element // to the parameter type. // // Otherwise, if the parameter type is a character array [... ] // and the initializer list has a single element that is an // appropriately-typed string literal (8.5.2 [dcl.init.string]), the // implicit conversion sequence is the identity conversion. if (From->getNumInits() == 1) { if (ToType->isRecordType()) { QualType InitType = From->getInit(0)->getType(); if (S.Context.hasSameUnqualifiedType(InitType, ToType) || S.IsDerivedFrom(From->getBeginLoc(), InitType, ToType)) return TryCopyInitialization(S, From->getInit(0), ToType, SuppressUserConversions, InOverloadResolution, AllowObjCWritebackConversion); } // FIXME: Check the other conditions here: array of character type, // initializer is a string literal. if (ToType->isArrayType()) { InitializedEntity Entity = InitializedEntity::InitializeParameter(S.Context, ToType, /*Consumed=*/false); if (S.CanPerformCopyInitialization(Entity, From)) { Result.setStandard(); Result.Standard.setAsIdentityConversion(); Result.Standard.setFromType(ToType); Result.Standard.setAllToTypes(ToType); return Result; } } } // C++14 [over.ics.list]p2: Otherwise, if the parameter type [...] (below). // C++11 [over.ics.list]p2: // If the parameter type is std::initializer_list or "array of X" and // all the elements can be implicitly converted to X, the implicit // conversion sequence is the worst conversion necessary to convert an // element of the list to X. // // C++14 [over.ics.list]p3: // Otherwise, if the parameter type is "array of N X", if the initializer // list has exactly N elements or if it has fewer than N elements and X is // default-constructible, and if all the elements of the initializer list // can be implicitly converted to X, the implicit conversion sequence is // the worst conversion necessary to convert an element of the list to X. // // FIXME: We're missing a lot of these checks. bool toStdInitializerList = false; QualType X; if (ToType->isArrayType()) X = S.Context.getAsArrayType(ToType)->getElementType(); else toStdInitializerList = S.isStdInitializerList(ToType, &X); if (!X.isNull()) { for (unsigned i = 0, e = From->getNumInits(); i < e; ++i) { Expr *Init = From->getInit(i); ImplicitConversionSequence ICS = TryCopyInitialization(S, Init, X, SuppressUserConversions, InOverloadResolution, AllowObjCWritebackConversion); // If a single element isn't convertible, fail. if (ICS.isBad()) { Result = ICS; break; } // Otherwise, look for the worst conversion. if (Result.isBad() || CompareImplicitConversionSequences( S, From->getBeginLoc(), ICS, Result) == ImplicitConversionSequence::Worse) Result = ICS; } // For an empty list, we won't have computed any conversion sequence. // Introduce the identity conversion sequence. if (From->getNumInits() == 0) { Result.setStandard(); Result.Standard.setAsIdentityConversion(); Result.Standard.setFromType(ToType); Result.Standard.setAllToTypes(ToType); } Result.setStdInitializerListElement(toStdInitializerList); return Result; } // C++14 [over.ics.list]p4: // C++11 [over.ics.list]p3: // Otherwise, if the parameter is a non-aggregate class X and overload // resolution chooses a single best constructor [...] the implicit // conversion sequence is a user-defined conversion sequence. If multiple // constructors are viable but none is better than the others, the // implicit conversion sequence is a user-defined conversion sequence. if (ToType->isRecordType() && !ToType->isAggregateType()) { // This function can deal with initializer lists. return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions, /*AllowExplicit=*/false, InOverloadResolution, /*CStyle=*/false, AllowObjCWritebackConversion, /*AllowObjCConversionOnExplicit=*/false); } // C++14 [over.ics.list]p5: // C++11 [over.ics.list]p4: // Otherwise, if the parameter has an aggregate type which can be // initialized from the initializer list [...] the implicit conversion // sequence is a user-defined conversion sequence. if (ToType->isAggregateType()) { // Type is an aggregate, argument is an init list. At this point it comes // down to checking whether the initialization works. // FIXME: Find out whether this parameter is consumed or not. InitializedEntity Entity = InitializedEntity::InitializeParameter(S.Context, ToType, /*Consumed=*/false); if (S.CanPerformAggregateInitializationForOverloadResolution(Entity, From)) { Result.setUserDefined(); Result.UserDefined.Before.setAsIdentityConversion(); // Initializer lists don't have a type. Result.UserDefined.Before.setFromType(QualType()); Result.UserDefined.Before.setAllToTypes(QualType()); Result.UserDefined.After.setAsIdentityConversion(); Result.UserDefined.After.setFromType(ToType); Result.UserDefined.After.setAllToTypes(ToType); Result.UserDefined.ConversionFunction = nullptr; } return Result; } // C++14 [over.ics.list]p6: // C++11 [over.ics.list]p5: // Otherwise, if the parameter is a reference, see 13.3.3.1.4. if (ToType->isReferenceType()) { // The standard is notoriously unclear here, since 13.3.3.1.4 doesn't // mention initializer lists in any way. So we go by what list- // initialization would do and try to extrapolate from that. QualType T1 = ToType->castAs()->getPointeeType(); // If the initializer list has a single element that is reference-related // to the parameter type, we initialize the reference from that. if (From->getNumInits() == 1) { Expr *Init = From->getInit(0); QualType T2 = Init->getType(); // If the initializer is the address of an overloaded function, try // to resolve the overloaded function. If all goes well, T2 is the // type of the resulting function. if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) { DeclAccessPair Found; if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction( Init, ToType, false, Found)) T2 = Fn->getType(); } // Compute some basic properties of the types and the initializer. Sema::ReferenceCompareResult RefRelationship = S.CompareReferenceRelationship(From->getBeginLoc(), T1, T2); if (RefRelationship >= Sema::Ref_Related) { return TryReferenceInit(S, Init, ToType, /*FIXME*/ From->getBeginLoc(), SuppressUserConversions, /*AllowExplicit=*/false); } } // Otherwise, we bind the reference to a temporary created from the // initializer list. Result = TryListConversion(S, From, T1, SuppressUserConversions, InOverloadResolution, AllowObjCWritebackConversion); if (Result.isFailure()) return Result; assert(!Result.isEllipsis() && "Sub-initialization cannot result in ellipsis conversion."); // Can we even bind to a temporary? if (ToType->isRValueReferenceType() || (T1.isConstQualified() && !T1.isVolatileQualified())) { StandardConversionSequence &SCS = Result.isStandard() ? Result.Standard : Result.UserDefined.After; SCS.ReferenceBinding = true; SCS.IsLvalueReference = ToType->isLValueReferenceType(); SCS.BindsToRvalue = true; SCS.BindsToFunctionLvalue = false; SCS.BindsImplicitObjectArgumentWithoutRefQualifier = false; SCS.ObjCLifetimeConversionBinding = false; } else Result.setBad(BadConversionSequence::lvalue_ref_to_rvalue, From, ToType); return Result; } // C++14 [over.ics.list]p7: // C++11 [over.ics.list]p6: // Otherwise, if the parameter type is not a class: if (!ToType->isRecordType()) { // - if the initializer list has one element that is not itself an // initializer list, the implicit conversion sequence is the one // required to convert the element to the parameter type. unsigned NumInits = From->getNumInits(); if (NumInits == 1 && !isa(From->getInit(0))) Result = TryCopyInitialization(S, From->getInit(0), ToType, SuppressUserConversions, InOverloadResolution, AllowObjCWritebackConversion); // - if the initializer list has no elements, the implicit conversion // sequence is the identity conversion. else if (NumInits == 0) { Result.setStandard(); Result.Standard.setAsIdentityConversion(); Result.Standard.setFromType(ToType); Result.Standard.setAllToTypes(ToType); } return Result; } // C++14 [over.ics.list]p8: // C++11 [over.ics.list]p7: // In all cases other than those enumerated above, no conversion is possible return Result; } /// TryCopyInitialization - Try to copy-initialize a value of type /// ToType from the expression From. Return the implicit conversion /// sequence required to pass this argument, which may be a bad /// conversion sequence (meaning that the argument cannot be passed to /// a parameter of this type). If @p SuppressUserConversions, then we /// do not permit any user-defined conversion sequences. static ImplicitConversionSequence TryCopyInitialization(Sema &S, Expr *From, QualType ToType, bool SuppressUserConversions, bool InOverloadResolution, bool AllowObjCWritebackConversion, bool AllowExplicit) { if (InitListExpr *FromInitList = dyn_cast(From)) return TryListConversion(S, FromInitList, ToType, SuppressUserConversions, InOverloadResolution,AllowObjCWritebackConversion); if (ToType->isReferenceType()) return TryReferenceInit(S, From, ToType, /*FIXME:*/ From->getBeginLoc(), SuppressUserConversions, AllowExplicit); return TryImplicitConversion(S, From, ToType, SuppressUserConversions, /*AllowExplicit=*/false, InOverloadResolution, /*CStyle=*/false, AllowObjCWritebackConversion, /*AllowObjCConversionOnExplicit=*/false); } static bool TryCopyInitialization(const CanQualType FromQTy, const CanQualType ToQTy, Sema &S, SourceLocation Loc, ExprValueKind FromVK) { OpaqueValueExpr TmpExpr(Loc, FromQTy, FromVK); ImplicitConversionSequence ICS = TryCopyInitialization(S, &TmpExpr, ToQTy, true, true, false); return !ICS.isBad(); } /// TryObjectArgumentInitialization - Try to initialize the object /// parameter of the given member function (@c Method) from the /// expression @p From. static ImplicitConversionSequence TryObjectArgumentInitialization(Sema &S, SourceLocation Loc, QualType FromType, Expr::Classification FromClassification, CXXMethodDecl *Method, CXXRecordDecl *ActingContext) { QualType ClassType = S.Context.getTypeDeclType(ActingContext); // [class.dtor]p2: A destructor can be invoked for a const, volatile or // const volatile object. Qualifiers Quals = Method->getMethodQualifiers(); if (isa(Method)) { Quals.addConst(); Quals.addVolatile(); } QualType ImplicitParamType = S.Context.getQualifiedType(ClassType, Quals); // Set up the conversion sequence as a "bad" conversion, to allow us // to exit early. ImplicitConversionSequence ICS; // We need to have an object of class type. if (const PointerType *PT = FromType->getAs()) { FromType = PT->getPointeeType(); // When we had a pointer, it's implicitly dereferenced, so we // better have an lvalue. assert(FromClassification.isLValue()); } assert(FromType->isRecordType()); // C++0x [over.match.funcs]p4: // For non-static member functions, the type of the implicit object // parameter is // // - "lvalue reference to cv X" for functions declared without a // ref-qualifier or with the & ref-qualifier // - "rvalue reference to cv X" for functions declared with the && // ref-qualifier // // where X is the class of which the function is a member and cv is the // cv-qualification on the member function declaration. // // However, when finding an implicit conversion sequence for the argument, we // are not allowed to perform user-defined conversions // (C++ [over.match.funcs]p5). We perform a simplified version of // reference binding here, that allows class rvalues to bind to // non-constant references. // First check the qualifiers. QualType FromTypeCanon = S.Context.getCanonicalType(FromType); if (ImplicitParamType.getCVRQualifiers() != FromTypeCanon.getLocalCVRQualifiers() && !ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon)) { ICS.setBad(BadConversionSequence::bad_qualifiers, FromType, ImplicitParamType); return ICS; } if (FromTypeCanon.hasAddressSpace()) { Qualifiers QualsImplicitParamType = ImplicitParamType.getQualifiers(); Qualifiers QualsFromType = FromTypeCanon.getQualifiers(); if (!QualsImplicitParamType.isAddressSpaceSupersetOf(QualsFromType)) { ICS.setBad(BadConversionSequence::bad_qualifiers, FromType, ImplicitParamType); return ICS; } } // Check that we have either the same type or a derived type. It // affects the conversion rank. QualType ClassTypeCanon = S.Context.getCanonicalType(ClassType); ImplicitConversionKind SecondKind; if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType()) { SecondKind = ICK_Identity; } else if (S.IsDerivedFrom(Loc, FromType, ClassType)) SecondKind = ICK_Derived_To_Base; else { ICS.setBad(BadConversionSequence::unrelated_class, FromType, ImplicitParamType); return ICS; } // Check the ref-qualifier. switch (Method->getRefQualifier()) { case RQ_None: // Do nothing; we don't care about lvalueness or rvalueness. break; case RQ_LValue: if (!FromClassification.isLValue() && !Quals.hasOnlyConst()) { // non-const lvalue reference cannot bind to an rvalue ICS.setBad(BadConversionSequence::lvalue_ref_to_rvalue, FromType, ImplicitParamType); return ICS; } break; case RQ_RValue: if (!FromClassification.isRValue()) { // rvalue reference cannot bind to an lvalue ICS.setBad(BadConversionSequence::rvalue_ref_to_lvalue, FromType, ImplicitParamType); return ICS; } break; } // Success. Mark this as a reference binding. ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); ICS.Standard.Second = SecondKind; ICS.Standard.setFromType(FromType); ICS.Standard.setAllToTypes(ImplicitParamType); ICS.Standard.ReferenceBinding = true; ICS.Standard.DirectBinding = true; ICS.Standard.IsLvalueReference = Method->getRefQualifier() != RQ_RValue; ICS.Standard.BindsToFunctionLvalue = false; ICS.Standard.BindsToRvalue = FromClassification.isRValue(); ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = (Method->getRefQualifier() == RQ_None); return ICS; } /// PerformObjectArgumentInitialization - Perform initialization of /// the implicit object parameter for the given Method with the given /// expression. ExprResult Sema::PerformObjectArgumentInitialization(Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl, CXXMethodDecl *Method) { QualType FromRecordType, DestType; QualType ImplicitParamRecordType = Method->getThisType()->castAs()->getPointeeType(); Expr::Classification FromClassification; if (const PointerType *PT = From->getType()->getAs()) { FromRecordType = PT->getPointeeType(); DestType = Method->getThisType(); FromClassification = Expr::Classification::makeSimpleLValue(); } else { FromRecordType = From->getType(); DestType = ImplicitParamRecordType; FromClassification = From->Classify(Context); // When performing member access on an rvalue, materialize a temporary. if (From->isRValue()) { From = CreateMaterializeTemporaryExpr(FromRecordType, From, Method->getRefQualifier() != RefQualifierKind::RQ_RValue); } } // Note that we always use the true parent context when performing // the actual argument initialization. ImplicitConversionSequence ICS = TryObjectArgumentInitialization( *this, From->getBeginLoc(), From->getType(), FromClassification, Method, Method->getParent()); if (ICS.isBad()) { switch (ICS.Bad.Kind) { case BadConversionSequence::bad_qualifiers: { Qualifiers FromQs = FromRecordType.getQualifiers(); Qualifiers ToQs = DestType.getQualifiers(); unsigned CVR = FromQs.getCVRQualifiers() & ~ToQs.getCVRQualifiers(); if (CVR) { Diag(From->getBeginLoc(), diag::err_member_function_call_bad_cvr) << Method->getDeclName() << FromRecordType << (CVR - 1) << From->getSourceRange(); Diag(Method->getLocation(), diag::note_previous_decl) << Method->getDeclName(); return ExprError(); } break; } case BadConversionSequence::lvalue_ref_to_rvalue: case BadConversionSequence::rvalue_ref_to_lvalue: { bool IsRValueQualified = Method->getRefQualifier() == RefQualifierKind::RQ_RValue; Diag(From->getBeginLoc(), diag::err_member_function_call_bad_ref) << Method->getDeclName() << FromClassification.isRValue() << IsRValueQualified; Diag(Method->getLocation(), diag::note_previous_decl) << Method->getDeclName(); return ExprError(); } case BadConversionSequence::no_conversion: case BadConversionSequence::unrelated_class: break; } return Diag(From->getBeginLoc(), diag::err_member_function_call_bad_type) << ImplicitParamRecordType << FromRecordType << From->getSourceRange(); } if (ICS.Standard.Second == ICK_Derived_To_Base) { ExprResult FromRes = PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method); if (FromRes.isInvalid()) return ExprError(); From = FromRes.get(); } if (!Context.hasSameType(From->getType(), DestType)) { CastKind CK; QualType PteeTy = DestType->getPointeeType(); LangAS DestAS = PteeTy.isNull() ? DestType.getAddressSpace() : PteeTy.getAddressSpace(); if (FromRecordType.getAddressSpace() != DestAS) CK = CK_AddressSpaceConversion; else CK = CK_NoOp; From = ImpCastExprToType(From, DestType, CK, From->getValueKind()).get(); } return From; } /// TryContextuallyConvertToBool - Attempt to contextually convert the /// expression From to bool (C++0x [conv]p3). static ImplicitConversionSequence TryContextuallyConvertToBool(Sema &S, Expr *From) { return TryImplicitConversion(S, From, S.Context.BoolTy, /*SuppressUserConversions=*/false, /*AllowExplicit=*/true, /*InOverloadResolution=*/false, /*CStyle=*/false, /*AllowObjCWritebackConversion=*/false, /*AllowObjCConversionOnExplicit=*/false); } /// PerformContextuallyConvertToBool - Perform a contextual conversion /// of the expression From to bool (C++0x [conv]p3). ExprResult Sema::PerformContextuallyConvertToBool(Expr *From) { if (checkPlaceholderForOverload(*this, From)) return ExprError(); ImplicitConversionSequence ICS = TryContextuallyConvertToBool(*this, From); if (!ICS.isBad()) return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting); if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy)) return Diag(From->getBeginLoc(), diag::err_typecheck_bool_condition) << From->getType() << From->getSourceRange(); return ExprError(); } /// Check that the specified conversion is permitted in a converted constant /// expression, according to C++11 [expr.const]p3. Return true if the conversion /// is acceptable. static bool CheckConvertedConstantConversions(Sema &S, StandardConversionSequence &SCS) { // Since we know that the target type is an integral or unscoped enumeration // type, most conversion kinds are impossible. All possible First and Third // conversions are fine. switch (SCS.Second) { case ICK_Identity: case ICK_Function_Conversion: case ICK_Integral_Promotion: case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere. case ICK_Zero_Queue_Conversion: return true; case ICK_Boolean_Conversion: // Conversion from an integral or unscoped enumeration type to bool is // classified as ICK_Boolean_Conversion, but it's also arguably an integral // conversion, so we allow it in a converted constant expression. // // FIXME: Per core issue 1407, we should not allow this, but that breaks // a lot of popular code. We should at least add a warning for this // (non-conforming) extension. return SCS.getFromType()->isIntegralOrUnscopedEnumerationType() && SCS.getToType(2)->isBooleanType(); case ICK_Pointer_Conversion: case ICK_Pointer_Member: // C++1z: null pointer conversions and null member pointer conversions are // only permitted if the source type is std::nullptr_t. return SCS.getFromType()->isNullPtrType(); case ICK_Floating_Promotion: case ICK_Complex_Promotion: case ICK_Floating_Conversion: case ICK_Complex_Conversion: case ICK_Floating_Integral: case ICK_Compatible_Conversion: case ICK_Derived_To_Base: case ICK_Vector_Conversion: case ICK_Vector_Splat: case ICK_Complex_Real: case ICK_Block_Pointer_Conversion: case ICK_TransparentUnionConversion: case ICK_Writeback_Conversion: case ICK_Zero_Event_Conversion: case ICK_C_Only_Conversion: case ICK_Incompatible_Pointer_Conversion: return false; case ICK_Lvalue_To_Rvalue: case ICK_Array_To_Pointer: case ICK_Function_To_Pointer: llvm_unreachable("found a first conversion kind in Second"); case ICK_Qualification: llvm_unreachable("found a third conversion kind in Second"); case ICK_Num_Conversion_Kinds: break; } llvm_unreachable("unknown conversion kind"); } /// CheckConvertedConstantExpression - Check that the expression From is a /// converted constant expression of type T, perform the conversion and produce /// the converted expression, per C++11 [expr.const]p3. static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, QualType T, APValue &Value, Sema::CCEKind CCE, bool RequireInt) { assert(S.getLangOpts().CPlusPlus11 && "converted constant expression outside C++11"); if (checkPlaceholderForOverload(S, From)) return ExprError(); // C++1z [expr.const]p3: // A converted constant expression of type T is an expression, // implicitly converted to type T, where the converted // expression is a constant expression and the implicit conversion // sequence contains only [... list of conversions ...]. // C++1z [stmt.if]p2: // If the if statement is of the form if constexpr, the value of the // condition shall be a contextually converted constant expression of type // bool. ImplicitConversionSequence ICS = CCE == Sema::CCEK_ConstexprIf || CCE == Sema::CCEK_ExplicitBool ? TryContextuallyConvertToBool(S, From) : TryCopyInitialization(S, From, T, /*SuppressUserConversions=*/false, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/false, /*AllowExplicit=*/false); StandardConversionSequence *SCS = nullptr; switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: SCS = &ICS.Standard; break; case ImplicitConversionSequence::UserDefinedConversion: // We are converting to a non-class type, so the Before sequence // must be trivial. SCS = &ICS.UserDefined.After; break; case ImplicitConversionSequence::AmbiguousConversion: case ImplicitConversionSequence::BadConversion: if (!S.DiagnoseMultipleUserDefinedConversion(From, T)) return S.Diag(From->getBeginLoc(), diag::err_typecheck_converted_constant_expression) << From->getType() << From->getSourceRange() << T; return ExprError(); case ImplicitConversionSequence::EllipsisConversion: llvm_unreachable("ellipsis conversion in converted constant expression"); } // Check that we would only use permitted conversions. if (!CheckConvertedConstantConversions(S, *SCS)) { return S.Diag(From->getBeginLoc(), diag::err_typecheck_converted_constant_expression_disallowed) << From->getType() << From->getSourceRange() << T; } // [...] and where the reference binding (if any) binds directly. if (SCS->ReferenceBinding && !SCS->DirectBinding) { return S.Diag(From->getBeginLoc(), diag::err_typecheck_converted_constant_expression_indirect) << From->getType() << From->getSourceRange() << T; } ExprResult Result = S.PerformImplicitConversion(From, T, ICS, Sema::AA_Converting); if (Result.isInvalid()) return Result; // C++2a [intro.execution]p5: // A full-expression is [...] a constant-expression [...] Result = S.ActOnFinishFullExpr(Result.get(), From->getExprLoc(), /*DiscardedValue=*/false, /*IsConstexpr=*/true); if (Result.isInvalid()) return Result; // Check for a narrowing implicit conversion. APValue PreNarrowingValue; QualType PreNarrowingType; switch (SCS->getNarrowingKind(S.Context, Result.get(), PreNarrowingValue, PreNarrowingType)) { case NK_Dependent_Narrowing: // Implicit conversion to a narrower type, but the expression is // value-dependent so we can't tell whether it's actually narrowing. case NK_Variable_Narrowing: // Implicit conversion to a narrower type, and the value is not a constant // expression. We'll diagnose this in a moment. case NK_Not_Narrowing: break; case NK_Constant_Narrowing: S.Diag(From->getBeginLoc(), diag::ext_cce_narrowing) << CCE << /*Constant*/ 1 << PreNarrowingValue.getAsString(S.Context, PreNarrowingType) << T; break; case NK_Type_Narrowing: S.Diag(From->getBeginLoc(), diag::ext_cce_narrowing) << CCE << /*Constant*/ 0 << From->getType() << T; break; } if (Result.get()->isValueDependent()) { Value = APValue(); return Result; } // Check the expression is a constant expression. SmallVector Notes; Expr::EvalResult Eval; Eval.Diag = &Notes; Expr::ConstExprUsage Usage = CCE == Sema::CCEK_TemplateArg ? Expr::EvaluateForMangling : Expr::EvaluateForCodeGen; if (!Result.get()->EvaluateAsConstantExpr(Eval, Usage, S.Context) || (RequireInt && !Eval.Val.isInt())) { // The expression can't be folded, so we can't keep it at this position in // the AST. Result = ExprError(); } else { Value = Eval.Val; if (Notes.empty()) { // It's a constant expression. return ConstantExpr::Create(S.Context, Result.get(), Value); } } // It's not a constant expression. Produce an appropriate diagnostic. if (Notes.size() == 1 && Notes[0].second.getDiagID() == diag::note_invalid_subexpr_in_const_expr) S.Diag(Notes[0].first, diag::err_expr_not_cce) << CCE; else { S.Diag(From->getBeginLoc(), diag::err_expr_not_cce) << CCE << From->getSourceRange(); for (unsigned I = 0; I < Notes.size(); ++I) S.Diag(Notes[I].first, Notes[I].second); } return ExprError(); } ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, APValue &Value, CCEKind CCE) { return ::CheckConvertedConstantExpression(*this, From, T, Value, CCE, false); } ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE) { assert(T->isIntegralOrEnumerationType() && "unexpected converted const type"); APValue V; auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true); if (!R.isInvalid() && !R.get()->isValueDependent()) Value = V.getInt(); return R; } /// dropPointerConversions - If the given standard conversion sequence /// involves any pointer conversions, remove them. This may change /// the result type of the conversion sequence. static void dropPointerConversion(StandardConversionSequence &SCS) { if (SCS.Second == ICK_Pointer_Conversion) { SCS.Second = ICK_Identity; SCS.Third = ICK_Identity; SCS.ToTypePtrs[2] = SCS.ToTypePtrs[1] = SCS.ToTypePtrs[0]; } } /// TryContextuallyConvertToObjCPointer - Attempt to contextually /// convert the expression From to an Objective-C pointer type. static ImplicitConversionSequence TryContextuallyConvertToObjCPointer(Sema &S, Expr *From) { // Do an implicit conversion to 'id'. QualType Ty = S.Context.getObjCIdType(); ImplicitConversionSequence ICS = TryImplicitConversion(S, From, Ty, // FIXME: Are these flags correct? /*SuppressUserConversions=*/false, /*AllowExplicit=*/true, /*InOverloadResolution=*/false, /*CStyle=*/false, /*AllowObjCWritebackConversion=*/false, /*AllowObjCConversionOnExplicit=*/true); // Strip off any final conversions to 'id'. switch (ICS.getKind()) { case ImplicitConversionSequence::BadConversion: case ImplicitConversionSequence::AmbiguousConversion: case ImplicitConversionSequence::EllipsisConversion: break; case ImplicitConversionSequence::UserDefinedConversion: dropPointerConversion(ICS.UserDefined.After); break; case ImplicitConversionSequence::StandardConversion: dropPointerConversion(ICS.Standard); break; } return ICS; } /// PerformContextuallyConvertToObjCPointer - Perform a contextual /// conversion of the expression From to an Objective-C pointer type. /// Returns a valid but null ExprResult if no conversion sequence exists. ExprResult Sema::PerformContextuallyConvertToObjCPointer(Expr *From) { if (checkPlaceholderForOverload(*this, From)) return ExprError(); QualType Ty = Context.getObjCIdType(); ImplicitConversionSequence ICS = TryContextuallyConvertToObjCPointer(*this, From); if (!ICS.isBad()) return PerformImplicitConversion(From, Ty, ICS, AA_Converting); return ExprResult(); } /// Determine whether the provided type is an integral type, or an enumeration /// type of a permitted flavor. bool Sema::ICEConvertDiagnoser::match(QualType T) { return AllowScopedEnumerations ? T->isIntegralOrEnumerationType() : T->isIntegralOrUnscopedEnumerationType(); } static ExprResult diagnoseAmbiguousConversion(Sema &SemaRef, SourceLocation Loc, Expr *From, Sema::ContextualImplicitConverter &Converter, QualType T, UnresolvedSetImpl &ViableConversions) { if (Converter.Suppress) return ExprError(); Converter.diagnoseAmbiguous(SemaRef, Loc, T) << From->getSourceRange(); for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) { CXXConversionDecl *Conv = cast(ViableConversions[I]->getUnderlyingDecl()); QualType ConvTy = Conv->getConversionType().getNonReferenceType(); Converter.noteAmbiguous(SemaRef, Conv, ConvTy); } return From; } static bool diagnoseNoViableConversion(Sema &SemaRef, SourceLocation Loc, Expr *&From, Sema::ContextualImplicitConverter &Converter, QualType T, bool HadMultipleCandidates, UnresolvedSetImpl &ExplicitConversions) { if (ExplicitConversions.size() == 1 && !Converter.Suppress) { DeclAccessPair Found = ExplicitConversions[0]; CXXConversionDecl *Conversion = cast(Found->getUnderlyingDecl()); // The user probably meant to invoke the given explicit // conversion; use it. QualType ConvTy = Conversion->getConversionType().getNonReferenceType(); std::string TypeStr; ConvTy.getAsStringInternal(TypeStr, SemaRef.getPrintingPolicy()); Converter.diagnoseExplicitConv(SemaRef, Loc, T, ConvTy) << FixItHint::CreateInsertion(From->getBeginLoc(), "static_cast<" + TypeStr + ">(") << FixItHint::CreateInsertion( SemaRef.getLocForEndOfToken(From->getEndLoc()), ")"); Converter.noteExplicitConv(SemaRef, Conversion, ConvTy); // If we aren't in a SFINAE context, build a call to the // explicit conversion function. if (SemaRef.isSFINAEContext()) return true; SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found); ExprResult Result = SemaRef.BuildCXXMemberCallExpr(From, Found, Conversion, HadMultipleCandidates); if (Result.isInvalid()) return true; // Record usage of conversion in an implicit cast. From = ImplicitCastExpr::Create(SemaRef.Context, Result.get()->getType(), CK_UserDefinedConversion, Result.get(), nullptr, Result.get()->getValueKind()); } return false; } static bool recordConversion(Sema &SemaRef, SourceLocation Loc, Expr *&From, Sema::ContextualImplicitConverter &Converter, QualType T, bool HadMultipleCandidates, DeclAccessPair &Found) { CXXConversionDecl *Conversion = cast(Found->getUnderlyingDecl()); SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found); QualType ToType = Conversion->getConversionType().getNonReferenceType(); if (!Converter.SuppressConversion) { if (SemaRef.isSFINAEContext()) return true; Converter.diagnoseConversion(SemaRef, Loc, T, ToType) << From->getSourceRange(); } ExprResult Result = SemaRef.BuildCXXMemberCallExpr(From, Found, Conversion, HadMultipleCandidates); if (Result.isInvalid()) return true; // Record usage of conversion in an implicit cast. From = ImplicitCastExpr::Create(SemaRef.Context, Result.get()->getType(), CK_UserDefinedConversion, Result.get(), nullptr, Result.get()->getValueKind()); return false; } static ExprResult finishContextualImplicitConversion( Sema &SemaRef, SourceLocation Loc, Expr *From, Sema::ContextualImplicitConverter &Converter) { if (!Converter.match(From->getType()) && !Converter.Suppress) Converter.diagnoseNoMatch(SemaRef, Loc, From->getType()) << From->getSourceRange(); return SemaRef.DefaultLvalueConversion(From); } static void collectViableConversionCandidates(Sema &SemaRef, Expr *From, QualType ToType, UnresolvedSetImpl &ViableConversions, OverloadCandidateSet &CandidateSet) { for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) { DeclAccessPair FoundDecl = ViableConversions[I]; NamedDecl *D = FoundDecl.getDecl(); CXXRecordDecl *ActingContext = cast(D->getDeclContext()); if (isa(D)) D = cast(D)->getTargetDecl(); CXXConversionDecl *Conv; FunctionTemplateDecl *ConvTemplate; if ((ConvTemplate = dyn_cast(D))) Conv = cast(ConvTemplate->getTemplatedDecl()); else Conv = cast(D); if (ConvTemplate) SemaRef.AddTemplateConversionCandidate( ConvTemplate, FoundDecl, ActingContext, From, ToType, CandidateSet, /*AllowObjCConversionOnExplicit=*/false, /*AllowExplicit*/ true); else SemaRef.AddConversionCandidate(Conv, FoundDecl, ActingContext, From, ToType, CandidateSet, /*AllowObjCConversionOnExplicit=*/false, /*AllowExplicit*/ true); } } /// Attempt to convert the given expression to a type which is accepted /// by the given converter. /// /// This routine will attempt to convert an expression of class type to a /// type accepted by the specified converter. In C++11 and before, the class /// must have a single non-explicit conversion function converting to a matching /// type. In C++1y, there can be multiple such conversion functions, but only /// one target type. /// /// \param Loc The source location of the construct that requires the /// conversion. /// /// \param From The expression we're converting from. /// /// \param Converter Used to control and diagnose the conversion process. /// /// \returns The expression, converted to an integral or enumeration type if /// successful. ExprResult Sema::PerformContextualImplicitConversion( SourceLocation Loc, Expr *From, ContextualImplicitConverter &Converter) { // We can't perform any more checking for type-dependent expressions. if (From->isTypeDependent()) return From; // Process placeholders immediately. if (From->hasPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(From); if (result.isInvalid()) return result; From = result.get(); } // If the expression already has a matching type, we're golden. QualType T = From->getType(); if (Converter.match(T)) return DefaultLvalueConversion(From); // FIXME: Check for missing '()' if T is a function type? // We can only perform contextual implicit conversions on objects of class // type. const RecordType *RecordTy = T->getAs(); if (!RecordTy || !getLangOpts().CPlusPlus) { if (!Converter.Suppress) Converter.diagnoseNoMatch(*this, Loc, T) << From->getSourceRange(); return From; } // We must have a complete class type. struct TypeDiagnoserPartialDiag : TypeDiagnoser { ContextualImplicitConverter &Converter; Expr *From; TypeDiagnoserPartialDiag(ContextualImplicitConverter &Converter, Expr *From) : Converter(Converter), From(From) {} void diagnose(Sema &S, SourceLocation Loc, QualType T) override { Converter.diagnoseIncomplete(S, Loc, T) << From->getSourceRange(); } } IncompleteDiagnoser(Converter, From); if (Converter.Suppress ? !isCompleteType(Loc, T) : RequireCompleteType(Loc, T, IncompleteDiagnoser)) return From; // Look for a conversion to an integral or enumeration type. UnresolvedSet<4> ViableConversions; // These are *potentially* viable in C++1y. UnresolvedSet<4> ExplicitConversions; const auto &Conversions = cast(RecordTy->getDecl())->getVisibleConversionFunctions(); bool HadMultipleCandidates = (std::distance(Conversions.begin(), Conversions.end()) > 1); // To check that there is only one target type, in C++1y: QualType ToType; bool HasUniqueTargetType = true; // Collect explicit or viable (potentially in C++1y) conversions. for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { NamedDecl *D = (*I)->getUnderlyingDecl(); CXXConversionDecl *Conversion; FunctionTemplateDecl *ConvTemplate = dyn_cast(D); if (ConvTemplate) { if (getLangOpts().CPlusPlus14) Conversion = cast(ConvTemplate->getTemplatedDecl()); else continue; // C++11 does not consider conversion operator templates(?). } else Conversion = cast(D); assert((!ConvTemplate || getLangOpts().CPlusPlus14) && "Conversion operator templates are considered potentially " "viable in C++1y"); QualType CurToType = Conversion->getConversionType().getNonReferenceType(); if (Converter.match(CurToType) || ConvTemplate) { if (Conversion->isExplicit()) { // FIXME: For C++1y, do we need this restriction? // cf. diagnoseNoViableConversion() if (!ConvTemplate) ExplicitConversions.addDecl(I.getDecl(), I.getAccess()); } else { if (!ConvTemplate && getLangOpts().CPlusPlus14) { if (ToType.isNull()) ToType = CurToType.getUnqualifiedType(); else if (HasUniqueTargetType && (CurToType.getUnqualifiedType() != ToType)) HasUniqueTargetType = false; } ViableConversions.addDecl(I.getDecl(), I.getAccess()); } } } if (getLangOpts().CPlusPlus14) { // C++1y [conv]p6: // ... An expression e of class type E appearing in such a context // is said to be contextually implicitly converted to a specified // type T and is well-formed if and only if e can be implicitly // converted to a type T that is determined as follows: E is searched // for conversion functions whose return type is cv T or reference to // cv T such that T is allowed by the context. There shall be // exactly one such T. // If no unique T is found: if (ToType.isNull()) { if (diagnoseNoViableConversion(*this, Loc, From, Converter, T, HadMultipleCandidates, ExplicitConversions)) return ExprError(); return finishContextualImplicitConversion(*this, Loc, From, Converter); } // If more than one unique Ts are found: if (!HasUniqueTargetType) return diagnoseAmbiguousConversion(*this, Loc, From, Converter, T, ViableConversions); // If one unique T is found: // First, build a candidate set from the previously recorded // potentially viable conversions. OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); collectViableConversionCandidates(*this, From, ToType, ViableConversions, CandidateSet); // Then, perform overload resolution over the candidate set. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, Loc, Best)) { case OR_Success: { // Apply this conversion. DeclAccessPair Found = DeclAccessPair::make(Best->Function, Best->FoundDecl.getAccess()); if (recordConversion(*this, Loc, From, Converter, T, HadMultipleCandidates, Found)) return ExprError(); break; } case OR_Ambiguous: return diagnoseAmbiguousConversion(*this, Loc, From, Converter, T, ViableConversions); case OR_No_Viable_Function: if (diagnoseNoViableConversion(*this, Loc, From, Converter, T, HadMultipleCandidates, ExplicitConversions)) return ExprError(); LLVM_FALLTHROUGH; case OR_Deleted: // We'll complain below about a non-integral condition type. break; } } else { switch (ViableConversions.size()) { case 0: { if (diagnoseNoViableConversion(*this, Loc, From, Converter, T, HadMultipleCandidates, ExplicitConversions)) return ExprError(); // We'll complain below about a non-integral condition type. break; } case 1: { // Apply this conversion. DeclAccessPair Found = ViableConversions[0]; if (recordConversion(*this, Loc, From, Converter, T, HadMultipleCandidates, Found)) return ExprError(); break; } default: return diagnoseAmbiguousConversion(*this, Loc, From, Converter, T, ViableConversions); } } return finishContextualImplicitConversion(*this, Loc, From, Converter); } /// IsAcceptableNonMemberOperatorCandidate - Determine whether Fn is /// an acceptable non-member overloaded operator for a call whose /// arguments have types T1 (and, if non-empty, T2). This routine /// implements the check in C++ [over.match.oper]p3b2 concerning /// enumeration types. static bool IsAcceptableNonMemberOperatorCandidate(ASTContext &Context, FunctionDecl *Fn, ArrayRef Args) { QualType T1 = Args[0]->getType(); QualType T2 = Args.size() > 1 ? Args[1]->getType() : QualType(); if (T1->isDependentType() || (!T2.isNull() && T2->isDependentType())) return true; if (T1->isRecordType() || (!T2.isNull() && T2->isRecordType())) return true; const auto *Proto = Fn->getType()->castAs(); if (Proto->getNumParams() < 1) return false; if (T1->isEnumeralType()) { QualType ArgType = Proto->getParamType(0).getNonReferenceType(); if (Context.hasSameUnqualifiedType(T1, ArgType)) return true; } if (Proto->getNumParams() < 2) return false; if (!T2.isNull() && T2->isEnumeralType()) { QualType ArgType = Proto->getParamType(1).getNonReferenceType(); if (Context.hasSameUnqualifiedType(T2, ArgType)) return true; } return false; } /// AddOverloadCandidate - Adds the given function to the set of /// candidate functions, using the given function call arguments. If /// @p SuppressUserConversions, then don't allow user-defined /// conversions via constructors or conversion operators. /// /// \param PartialOverloading true if we are performing "partial" overloading /// based on an incomplete set of function arguments. This feature is used by /// code completion. void Sema::AddOverloadCandidate( FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, bool AllowExplicit, bool AllowExplicitConversions, ADLCallKind IsADLCandidate, ConversionSequenceList EarlyConversions, OverloadCandidateParamOrder PO) { const FunctionProtoType *Proto = dyn_cast(Function->getType()->getAs()); assert(Proto && "Functions without a prototype cannot be overloaded"); assert(!Function->getDescribedFunctionTemplate() && "Use AddTemplateOverloadCandidate for function templates"); if (CXXMethodDecl *Method = dyn_cast(Function)) { if (!isa(Method)) { // If we get here, it's because we're calling a member function // that is named without a member access expression (e.g., // "this->f") that was either written explicitly or created // implicitly. This can happen with a qualified call to a member // function, e.g., X::f(). We use an empty type for the implied // object argument (C++ [over.call.func]p3), and the acting context // is irrelevant. AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(), Expr::Classification::makeSimpleLValue(), Args, CandidateSet, SuppressUserConversions, PartialOverloading, EarlyConversions, PO); return; } // We treat a constructor like a non-member function, since its object // argument doesn't participate in overload resolution. } if (!CandidateSet.isNewCandidate(Function, PO)) return; // C++11 [class.copy]p11: [DR1402] // A defaulted move constructor that is defined as deleted is ignored by // overload resolution. CXXConstructorDecl *Constructor = dyn_cast(Function); if (Constructor && Constructor->isDefaulted() && Constructor->isDeleted() && Constructor->isMoveConstructor()) return; // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); // C++ [over.match.oper]p3: // if no operand has a class type, only those non-member functions in the // lookup set that have a first parameter of type T1 or "reference to // (possibly cv-qualified) T1", when T1 is an enumeration type, or (if there // is a right operand) a second parameter of type T2 or "reference to // (possibly cv-qualified) T2", when T2 is an enumeration type, are // candidate functions. if (CandidateSet.getKind() == OverloadCandidateSet::CSK_Operator && !IsAcceptableNonMemberOperatorCandidate(Context, Function, Args)) return; // Add this candidate OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size(), EarlyConversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = Function; Candidate.Viable = true; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Function, PO); Candidate.IsSurrogate = false; Candidate.IsADLCandidate = IsADLCandidate; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = Args.size(); // Explicit functions are not actually candidates at all if we're not // allowing them in this context, but keep them around so we can point // to them in diagnostics. if (!AllowExplicit && ExplicitSpecifier::getFromDecl(Function).isExplicit()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_explicit; return; } if (Function->isMultiVersion() && Function->hasAttr() && !Function->getAttr()->isDefaultVersion()) { Candidate.Viable = false; Candidate.FailureKind = ovl_non_default_multiversion_function; return; } if (Constructor) { // C++ [class.copy]p3: // A member function template is never instantiated to perform the copy // of a class object to an object of its class type. QualType ClassType = Context.getTypeDeclType(Constructor->getParent()); if (Args.size() == 1 && Constructor->isSpecializationCopyingObject() && (Context.hasSameUnqualifiedType(ClassType, Args[0]->getType()) || IsDerivedFrom(Args[0]->getBeginLoc(), Args[0]->getType(), ClassType))) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_illegal_constructor; return; } // C++ [over.match.funcs]p8: (proposed DR resolution) // A constructor inherited from class type C that has a first parameter // of type "reference to P" (including such a constructor instantiated // from a template) is excluded from the set of candidate functions when // constructing an object of type cv D if the argument list has exactly // one argument and D is reference-related to P and P is reference-related // to C. auto *Shadow = dyn_cast(FoundDecl.getDecl()); if (Shadow && Args.size() == 1 && Constructor->getNumParams() >= 1 && Constructor->getParamDecl(0)->getType()->isReferenceType()) { QualType P = Constructor->getParamDecl(0)->getType()->getPointeeType(); QualType C = Context.getRecordType(Constructor->getParent()); QualType D = Context.getRecordType(Shadow->getParent()); SourceLocation Loc = Args.front()->getExprLoc(); if ((Context.hasSameUnqualifiedType(P, C) || IsDerivedFrom(Loc, P, C)) && (Context.hasSameUnqualifiedType(D, P) || IsDerivedFrom(Loc, D, P))) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_inhctor_slice; return; } } // Check that the constructor is capable of constructing an object in the // destination address space. if (!Qualifiers::isAddressSpaceSupersetOf( Constructor->getMethodQualifiers().getAddressSpace(), CandidateSet.getDestAS())) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_object_addrspace_mismatch; } } unsigned NumParams = Proto->getNumParams(); // (C++ 13.3.2p2): A candidate function having fewer than m // parameters is viable only if it has an ellipsis in its parameter // list (8.3.5). if (TooManyArguments(NumParams, Args.size(), PartialOverloading) && !Proto->isVariadic()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_many_arguments; return; } // (C++ 13.3.2p2): A candidate function having more than m parameters // is viable only if the (m+1)st parameter has a default argument // (8.3.6). For the purposes of overload resolution, the // parameter list is truncated on the right, so that there are // exactly m parameters. unsigned MinRequiredArgs = Function->getMinRequiredArguments(); if (Args.size() < MinRequiredArgs && !PartialOverloading) { // Not enough arguments. Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_few_arguments; return; } // (CUDA B.1): Check for invalid calls between targets. if (getLangOpts().CUDA) if (const FunctionDecl *Caller = dyn_cast(CurContext)) // Skip the check for callers that are implicit members, because in this // case we may not yet know what the member's target is; the target is // inferred for the member automatically, based on the bases and fields of // the class. if (!Caller->isImplicit() && !IsAllowedCUDACall(Caller, Function)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_target; return; } if (Function->getTrailingRequiresClause()) { ConstraintSatisfaction Satisfaction; if (CheckFunctionConstraints(Function, Satisfaction) || !Satisfaction.IsSatisfied) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_constraints_not_satisfied; return; } } // Determine the implicit conversion sequences for each of the // arguments. for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 1 - ArgIdx : ArgIdx; if (Candidate.Conversions[ConvIdx].isInitialized()) { // We already formed a conversion sequence for this parameter during // template argument deduction. } else if (ArgIdx < NumParams) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding // parameter of F. QualType ParamType = Proto->getParamType(ArgIdx); Candidate.Conversions[ConvIdx] = TryCopyInitialization( *this, Args[ArgIdx], ParamType, SuppressUserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, AllowExplicitConversions); if (Candidate.Conversions[ConvIdx].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; return; } } else { // (C++ 13.3.2p2): For the purposes of overload resolution, any // argument for which there is no corresponding parameter is // considered to ""match the ellipsis" (C+ 13.3.3.1.3). Candidate.Conversions[ConvIdx].setEllipsis(); } } if (EnableIfAttr *FailedAttr = CheckEnableIf(Function, Args)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; Candidate.DeductionFailure.Data = FailedAttr; return; } if (LangOpts.OpenCL && isOpenCLDisabledDecl(Function)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_ext_disabled; return; } } ObjCMethodDecl * Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance, SmallVectorImpl &Methods) { if (Methods.size() <= 1) return nullptr; for (unsigned b = 0, e = Methods.size(); b < e; b++) { bool Match = true; ObjCMethodDecl *Method = Methods[b]; unsigned NumNamedArgs = Sel.getNumArgs(); // Method might have more arguments than selector indicates. This is due // to addition of c-style arguments in method. if (Method->param_size() > NumNamedArgs) NumNamedArgs = Method->param_size(); if (Args.size() < NumNamedArgs) continue; for (unsigned i = 0; i < NumNamedArgs; i++) { // We can't do any type-checking on a type-dependent argument. if (Args[i]->isTypeDependent()) { Match = false; break; } ParmVarDecl *param = Method->parameters()[i]; Expr *argExpr = Args[i]; assert(argExpr && "SelectBestMethod(): missing expression"); // Strip the unbridged-cast placeholder expression off unless it's // a consumed argument. if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) && !param->hasAttr()) argExpr = stripARCUnbridgedCast(argExpr); // If the parameter is __unknown_anytype, move on to the next method. if (param->getType() == Context.UnknownAnyTy) { Match = false; break; } ImplicitConversionSequence ConversionState = TryCopyInitialization(*this, argExpr, param->getType(), /*SuppressUserConversions*/false, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, /*AllowExplicit*/false); // This function looks for a reasonably-exact match, so we consider // incompatible pointer conversions to be a failure here. if (ConversionState.isBad() || (ConversionState.isStandard() && ConversionState.Standard.Second == ICK_Incompatible_Pointer_Conversion)) { Match = false; break; } } // Promote additional arguments to variadic methods. if (Match && Method->isVariadic()) { for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) { if (Args[i]->isTypeDependent()) { Match = false; break; } ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, nullptr); if (Arg.isInvalid()) { Match = false; break; } } } else { // Check for extra arguments to non-variadic methods. if (Args.size() != NumNamedArgs) Match = false; else if (Match && NumNamedArgs == 0 && Methods.size() > 1) { // Special case when selectors have no argument. In this case, select // one with the most general result type of 'id'. for (unsigned b = 0, e = Methods.size(); b < e; b++) { QualType ReturnT = Methods[b]->getReturnType(); if (ReturnT->isObjCIdType()) return Methods[b]; } } } if (Match) return Method; } return nullptr; } static bool convertArgsForAvailabilityChecks(Sema &S, FunctionDecl *Function, Expr *ThisArg, ArrayRef Args, Sema::SFINAETrap &Trap, bool MissingImplicitThis, Expr *&ConvertedThis, SmallVectorImpl &ConvertedArgs) { if (ThisArg) { CXXMethodDecl *Method = cast(Function); assert(!isa(Method) && "Shouldn't have `this` for ctors!"); assert(!Method->isStatic() && "Shouldn't have `this` for static methods!"); ExprResult R = S.PerformObjectArgumentInitialization( ThisArg, /*Qualifier=*/nullptr, Method, Method); if (R.isInvalid()) return false; ConvertedThis = R.get(); } else { if (auto *MD = dyn_cast(Function)) { (void)MD; assert((MissingImplicitThis || MD->isStatic() || isa(MD)) && "Expected `this` for non-ctor instance methods"); } ConvertedThis = nullptr; } // Ignore any variadic arguments. Converting them is pointless, since the // user can't refer to them in the function condition. unsigned ArgSizeNoVarargs = std::min(Function->param_size(), Args.size()); // Convert the arguments. for (unsigned I = 0; I != ArgSizeNoVarargs; ++I) { ExprResult R; R = S.PerformCopyInitialization(InitializedEntity::InitializeParameter( S.Context, Function->getParamDecl(I)), SourceLocation(), Args[I]); if (R.isInvalid()) return false; ConvertedArgs.push_back(R.get()); } if (Trap.hasErrorOccurred()) return false; // Push default arguments if needed. if (!Function->isVariadic() && Args.size() < Function->getNumParams()) { for (unsigned i = Args.size(), e = Function->getNumParams(); i != e; ++i) { ParmVarDecl *P = Function->getParamDecl(i); Expr *DefArg = P->hasUninstantiatedDefaultArg() ? P->getUninstantiatedDefaultArg() : P->getDefaultArg(); // This can only happen in code completion, i.e. when PartialOverloading // is true. if (!DefArg) return false; ExprResult R = S.PerformCopyInitialization(InitializedEntity::InitializeParameter( S.Context, Function->getParamDecl(i)), SourceLocation(), DefArg); if (R.isInvalid()) return false; ConvertedArgs.push_back(R.get()); } if (Trap.hasErrorOccurred()) return false; } return true; } EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef Args, bool MissingImplicitThis) { auto EnableIfAttrs = Function->specific_attrs(); if (EnableIfAttrs.begin() == EnableIfAttrs.end()) return nullptr; SFINAETrap Trap(*this); SmallVector ConvertedArgs; // FIXME: We should look into making enable_if late-parsed. Expr *DiscardedThis; if (!convertArgsForAvailabilityChecks( *this, Function, /*ThisArg=*/nullptr, Args, Trap, /*MissingImplicitThis=*/true, DiscardedThis, ConvertedArgs)) return *EnableIfAttrs.begin(); for (auto *EIA : EnableIfAttrs) { APValue Result; // FIXME: This doesn't consider value-dependent cases, because doing so is // very difficult. Ideally, we should handle them more gracefully. if (EIA->getCond()->isValueDependent() || !EIA->getCond()->EvaluateWithSubstitution( Result, Context, Function, llvm::makeArrayRef(ConvertedArgs))) return EIA; if (!Result.isInt() || !Result.getInt().getBoolValue()) return EIA; } return nullptr; } template static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const NamedDecl *ND, bool ArgDependent, SourceLocation Loc, CheckFn &&IsSuccessful) { SmallVector Attrs; for (const auto *DIA : ND->specific_attrs()) { if (ArgDependent == DIA->getArgDependent()) Attrs.push_back(DIA); } // Common case: No diagnose_if attributes, so we can quit early. if (Attrs.empty()) return false; auto WarningBegin = std::stable_partition( Attrs.begin(), Attrs.end(), [](const DiagnoseIfAttr *DIA) { return DIA->isError(); }); // Note that diagnose_if attributes are late-parsed, so they appear in the // correct order (unlike enable_if attributes). auto ErrAttr = llvm::find_if(llvm::make_range(Attrs.begin(), WarningBegin), IsSuccessful); if (ErrAttr != WarningBegin) { const DiagnoseIfAttr *DIA = *ErrAttr; S.Diag(Loc, diag::err_diagnose_if_succeeded) << DIA->getMessage(); S.Diag(DIA->getLocation(), diag::note_from_diagnose_if) << DIA->getParent() << DIA->getCond()->getSourceRange(); return true; } for (const auto *DIA : llvm::make_range(WarningBegin, Attrs.end())) if (IsSuccessful(DIA)) { S.Diag(Loc, diag::warn_diagnose_if_succeeded) << DIA->getMessage(); S.Diag(DIA->getLocation(), diag::note_from_diagnose_if) << DIA->getParent() << DIA->getCond()->getSourceRange(); } return false; } bool Sema::diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef Args, SourceLocation Loc) { return diagnoseDiagnoseIfAttrsWith( *this, Function, /*ArgDependent=*/true, Loc, [&](const DiagnoseIfAttr *DIA) { APValue Result; // It's sane to use the same Args for any redecl of this function, since // EvaluateWithSubstitution only cares about the position of each // argument in the arg list, not the ParmVarDecl* it maps to. if (!DIA->getCond()->EvaluateWithSubstitution( Result, Context, cast(DIA->getParent()), Args, ThisArg)) return false; return Result.isInt() && Result.getInt().getBoolValue(); }); } bool Sema::diagnoseArgIndependentDiagnoseIfAttrs(const NamedDecl *ND, SourceLocation Loc) { return diagnoseDiagnoseIfAttrsWith( *this, ND, /*ArgDependent=*/false, Loc, [&](const DiagnoseIfAttr *DIA) { bool Result; return DIA->getCond()->EvaluateAsBooleanCondition(Result, Context) && Result; }); } /// Add all of the function declarations in the given function set to /// the overload candidate set. void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, ArrayRef Args, OverloadCandidateSet &CandidateSet, TemplateArgumentListInfo *ExplicitTemplateArgs, bool SuppressUserConversions, bool PartialOverloading, bool FirstArgumentIsBase) { for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { NamedDecl *D = F.getDecl()->getUnderlyingDecl(); ArrayRef FunctionArgs = Args; FunctionTemplateDecl *FunTmpl = dyn_cast(D); FunctionDecl *FD = FunTmpl ? FunTmpl->getTemplatedDecl() : cast(D); if (isa(FD) && !cast(FD)->isStatic()) { QualType ObjectType; Expr::Classification ObjectClassification; if (Args.size() > 0) { if (Expr *E = Args[0]) { // Use the explicit base to restrict the lookup: ObjectType = E->getType(); // Pointers in the object arguments are implicitly dereferenced, so we // always classify them as l-values. if (!ObjectType.isNull() && ObjectType->isPointerType()) ObjectClassification = Expr::Classification::makeSimpleLValue(); else ObjectClassification = E->Classify(Context); } // .. else there is an implicit base. FunctionArgs = Args.slice(1); } if (FunTmpl) { AddMethodTemplateCandidate( FunTmpl, F.getPair(), cast(FunTmpl->getDeclContext()), ExplicitTemplateArgs, ObjectType, ObjectClassification, FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } else { AddMethodCandidate(cast(FD), F.getPair(), cast(FD)->getParent(), ObjectType, ObjectClassification, FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } } else { // This branch handles both standalone functions and static methods. // Slice the first argument (which is the base) when we access // static method as non-static. if (Args.size() > 0 && (!Args[0] || (FirstArgumentIsBase && isa(FD) && !isa(FD)))) { assert(cast(FD)->isStatic()); FunctionArgs = Args.slice(1); } if (FunTmpl) { AddTemplateOverloadCandidate(FunTmpl, F.getPair(), ExplicitTemplateArgs, FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } else { AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } } } } /// AddMethodCandidate - Adds a named decl (which is some kind of /// method) as a method candidate to the given overload set. void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, OverloadCandidateParamOrder PO) { NamedDecl *Decl = FoundDecl.getDecl(); CXXRecordDecl *ActingContext = cast(Decl->getDeclContext()); if (isa(Decl)) Decl = cast(Decl)->getTargetDecl(); if (FunctionTemplateDecl *TD = dyn_cast(Decl)) { assert(isa(TD->getTemplatedDecl()) && "Expected a member function template"); AddMethodTemplateCandidate(TD, FoundDecl, ActingContext, /*ExplicitArgs*/ nullptr, ObjectType, ObjectClassification, Args, CandidateSet, SuppressUserConversions, false, PO); } else { AddMethodCandidate(cast(Decl), FoundDecl, ActingContext, ObjectType, ObjectClassification, Args, CandidateSet, SuppressUserConversions, false, None, PO); } } /// AddMethodCandidate - Adds the given C++ member function to the set /// of candidate functions, using the given function call arguments /// and the object argument (@c Object). For example, in a call /// @c o.f(a1,a2), @c Object will contain @c o and @c Args will contain /// both @c a1 and @c a2. If @p SuppressUserConversions, then don't /// allow user-defined conversions via constructors or conversion /// operators. void Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, ConversionSequenceList EarlyConversions, OverloadCandidateParamOrder PO) { const FunctionProtoType *Proto = dyn_cast(Method->getType()->getAs()); assert(Proto && "Methods without a prototype cannot be overloaded"); assert(!isa(Method) && "Use AddOverloadCandidate for constructors"); if (!CandidateSet.isNewCandidate(Method, PO)) return; // C++11 [class.copy]p23: [DR1402] // A defaulted move assignment operator that is defined as deleted is // ignored by overload resolution. if (Method->isDefaulted() && Method->isDeleted() && Method->isMoveAssignmentOperator()) return; // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); // Add this candidate OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1, EarlyConversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = Method; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Method, PO); Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = Args.size(); unsigned NumParams = Proto->getNumParams(); // (C++ 13.3.2p2): A candidate function having fewer than m // parameters is viable only if it has an ellipsis in its parameter // list (8.3.5). if (TooManyArguments(NumParams, Args.size(), PartialOverloading) && !Proto->isVariadic()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_many_arguments; return; } // (C++ 13.3.2p2): A candidate function having more than m parameters // is viable only if the (m+1)st parameter has a default argument // (8.3.6). For the purposes of overload resolution, the // parameter list is truncated on the right, so that there are // exactly m parameters. unsigned MinRequiredArgs = Method->getMinRequiredArguments(); if (Args.size() < MinRequiredArgs && !PartialOverloading) { // Not enough arguments. Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_few_arguments; return; } Candidate.Viable = true; if (Method->isStatic() || ObjectType.isNull()) // The implicit object argument is ignored. Candidate.IgnoreObjectArgument = true; else { unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 1 : 0; // Determine the implicit conversion sequence for the object // parameter. Candidate.Conversions[ConvIdx] = TryObjectArgumentInitialization( *this, CandidateSet.getLocation(), ObjectType, ObjectClassification, Method, ActingContext); if (Candidate.Conversions[ConvIdx].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; return; } } // (CUDA B.1): Check for invalid calls between targets. if (getLangOpts().CUDA) if (const FunctionDecl *Caller = dyn_cast(CurContext)) if (!IsAllowedCUDACall(Caller, Method)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_target; return; } if (Method->getTrailingRequiresClause()) { ConstraintSatisfaction Satisfaction; if (CheckFunctionConstraints(Method, Satisfaction) || !Satisfaction.IsSatisfied) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_constraints_not_satisfied; return; } } // Determine the implicit conversion sequences for each of the // arguments. for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 0 : (ArgIdx + 1); if (Candidate.Conversions[ConvIdx].isInitialized()) { // We already formed a conversion sequence for this parameter during // template argument deduction. } else if (ArgIdx < NumParams) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding // parameter of F. QualType ParamType = Proto->getParamType(ArgIdx); Candidate.Conversions[ConvIdx] = TryCopyInitialization(*this, Args[ArgIdx], ParamType, SuppressUserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount); if (Candidate.Conversions[ConvIdx].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; return; } } else { // (C++ 13.3.2p2): For the purposes of overload resolution, any // argument for which there is no corresponding parameter is // considered to "match the ellipsis" (C+ 13.3.3.1.3). Candidate.Conversions[ConvIdx].setEllipsis(); } } if (EnableIfAttr *FailedAttr = CheckEnableIf(Method, Args, true)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; Candidate.DeductionFailure.Data = FailedAttr; return; } if (Method->isMultiVersion() && Method->hasAttr() && !Method->getAttr()->isDefaultVersion()) { Candidate.Viable = false; Candidate.FailureKind = ovl_non_default_multiversion_function; } } /// Add a C++ member function template as a candidate to the candidate /// set, using template argument deduction to produce an appropriate member /// function template specialization. void Sema::AddMethodTemplateCandidate( FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, OverloadCandidateParamOrder PO) { if (!CandidateSet.isNewCandidate(MethodTmpl, PO)) return; // C++ [over.match.funcs]p7: // In each case where a candidate is a function template, candidate // function template specializations are generated using template argument // deduction (14.8.3, 14.8.2). Those candidates are then handled as // candidate functions in the usual way.113) A given name can refer to one // or more function templates and also to a set of overloaded non-template // functions. In such a case, the candidate functions generated from each // function template are combined with the set of non-template candidate // functions. TemplateDeductionInfo Info(CandidateSet.getLocation()); FunctionDecl *Specialization = nullptr; ConversionSequenceList Conversions; if (TemplateDeductionResult Result = DeduceTemplateArguments( MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info, PartialOverloading, [&](ArrayRef ParamTypes) { return CheckNonDependentConversions( MethodTmpl, ParamTypes, Args, CandidateSet, Conversions, SuppressUserConversions, ActingContext, ObjectType, ObjectClassification, PO); })) { OverloadCandidate &Candidate = CandidateSet.addCandidate(Conversions.size(), Conversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = MethodTmpl->getTemplatedDecl(); Candidate.Viable = false; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Candidate.Function, PO); Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = cast(Candidate.Function)->isStatic() || ObjectType.isNull(); Candidate.ExplicitCallArguments = Args.size(); if (Result == TDK_NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; else { Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, Info); } return; } // Add the function template specialization produced by template argument // deduction as a candidate. assert(Specialization && "Missing member function template specialization?"); assert(isa(Specialization) && "Specialization is not a member function?"); AddMethodCandidate(cast(Specialization), FoundDecl, ActingContext, ObjectType, ObjectClassification, Args, CandidateSet, SuppressUserConversions, PartialOverloading, Conversions, PO); } /// Determine whether a given function template has a simple explicit specifier /// or a non-value-dependent explicit-specification that evaluates to true. static bool isNonDependentlyExplicit(FunctionTemplateDecl *FTD) { return ExplicitSpecifier::getFromDecl(FTD->getTemplatedDecl()).isExplicit(); } /// Add a C++ function template specialization as a candidate /// in the candidate set, using template argument deduction to produce /// an appropriate function template specialization. void Sema::AddTemplateOverloadCandidate( FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, bool AllowExplicit, ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO) { if (!CandidateSet.isNewCandidate(FunctionTemplate, PO)) return; // If the function template has a non-dependent explicit specification, // exclude it now if appropriate; we are not permitted to perform deduction // and substitution in this case. if (!AllowExplicit && isNonDependentlyExplicit(FunctionTemplate)) { OverloadCandidate &Candidate = CandidateSet.addCandidate(); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.FailureKind = ovl_fail_explicit; return; } // C++ [over.match.funcs]p7: // In each case where a candidate is a function template, candidate // function template specializations are generated using template argument // deduction (14.8.3, 14.8.2). Those candidates are then handled as // candidate functions in the usual way.113) A given name can refer to one // or more function templates and also to a set of overloaded non-template // functions. In such a case, the candidate functions generated from each // function template are combined with the set of non-template candidate // functions. TemplateDeductionInfo Info(CandidateSet.getLocation()); FunctionDecl *Specialization = nullptr; ConversionSequenceList Conversions; if (TemplateDeductionResult Result = DeduceTemplateArguments( FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info, PartialOverloading, [&](ArrayRef ParamTypes) { return CheckNonDependentConversions( FunctionTemplate, ParamTypes, Args, CandidateSet, Conversions, SuppressUserConversions, nullptr, QualType(), {}, PO); })) { OverloadCandidate &Candidate = CandidateSet.addCandidate(Conversions.size(), Conversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Candidate.Function, PO); Candidate.IsSurrogate = false; Candidate.IsADLCandidate = IsADLCandidate; // Ignore the object argument if there is one, since we don't have an object // type. Candidate.IgnoreObjectArgument = isa(Candidate.Function) && !isa(Candidate.Function); Candidate.ExplicitCallArguments = Args.size(); if (Result == TDK_NonDependentConversionFailure) Candidate.FailureKind = ovl_fail_bad_conversion; else { Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, Info); } return; } // Add the function template specialization produced by template argument // deduction as a candidate. assert(Specialization && "Missing function template specialization?"); AddOverloadCandidate( Specialization, FoundDecl, Args, CandidateSet, SuppressUserConversions, PartialOverloading, AllowExplicit, /*AllowExplicitConversions*/ false, IsADLCandidate, Conversions, PO); } /// Check that implicit conversion sequences can be formed for each argument /// whose corresponding parameter has a non-dependent type, per DR1391's /// [temp.deduct.call]p10. bool Sema::CheckNonDependentConversions( FunctionTemplateDecl *FunctionTemplate, ArrayRef ParamTypes, ArrayRef Args, OverloadCandidateSet &CandidateSet, ConversionSequenceList &Conversions, bool SuppressUserConversions, CXXRecordDecl *ActingContext, QualType ObjectType, Expr::Classification ObjectClassification, OverloadCandidateParamOrder PO) { // FIXME: The cases in which we allow explicit conversions for constructor // arguments never consider calling a constructor template. It's not clear // that is correct. const bool AllowExplicit = false; auto *FD = FunctionTemplate->getTemplatedDecl(); auto *Method = dyn_cast(FD); bool HasThisConversion = Method && !isa(Method); unsigned ThisConversions = HasThisConversion ? 1 : 0; Conversions = CandidateSet.allocateConversionSequences(ThisConversions + Args.size()); // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); // For a method call, check the 'this' conversion here too. DR1391 doesn't // require that, but this check should never result in a hard error, and // overload resolution is permitted to sidestep instantiations. if (HasThisConversion && !cast(FD)->isStatic() && !ObjectType.isNull()) { unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 1 : 0; Conversions[ConvIdx] = TryObjectArgumentInitialization( *this, CandidateSet.getLocation(), ObjectType, ObjectClassification, Method, ActingContext); if (Conversions[ConvIdx].isBad()) return true; } for (unsigned I = 0, N = std::min(ParamTypes.size(), Args.size()); I != N; ++I) { QualType ParamType = ParamTypes[I]; if (!ParamType->isDependentType()) { unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed ? 0 : (ThisConversions + I); Conversions[ConvIdx] = TryCopyInitialization(*this, Args[I], ParamType, SuppressUserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, AllowExplicit); if (Conversions[ConvIdx].isBad()) return true; } } return false; } /// Determine whether this is an allowable conversion from the result /// of an explicit conversion operator to the expected type, per C++ /// [over.match.conv]p1 and [over.match.ref]p1. /// /// \param ConvType The return type of the conversion function. /// /// \param ToType The type we are converting to. /// /// \param AllowObjCPointerConversion Allow a conversion from one /// Objective-C pointer to another. /// /// \returns true if the conversion is allowable, false otherwise. static bool isAllowableExplicitConversion(Sema &S, QualType ConvType, QualType ToType, bool AllowObjCPointerConversion) { QualType ToNonRefType = ToType.getNonReferenceType(); // Easy case: the types are the same. if (S.Context.hasSameUnqualifiedType(ConvType, ToNonRefType)) return true; // Allow qualification conversions. bool ObjCLifetimeConversion; if (S.IsQualificationConversion(ConvType, ToNonRefType, /*CStyle*/false, ObjCLifetimeConversion)) return true; // If we're not allowed to consider Objective-C pointer conversions, // we're done. if (!AllowObjCPointerConversion) return false; // Is this an Objective-C pointer conversion? bool IncompatibleObjC = false; QualType ConvertedType; return S.isObjCPointerConversion(ConvType, ToNonRefType, ConvertedType, IncompatibleObjC); } /// AddConversionCandidate - Add a C++ conversion function as a /// candidate in the candidate set (C++ [over.match.conv], /// C++ [over.match.copy]). From is the expression we're converting from, /// and ToType is the type that we're eventually trying to convert to /// (which may or may not be the same type as the type that the /// conversion function produces). void Sema::AddConversionCandidate( CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, Expr *From, QualType ToType, OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, bool AllowExplicit, bool AllowResultConversion) { assert(!Conversion->getDescribedFunctionTemplate() && "Conversion function templates use AddTemplateConversionCandidate"); QualType ConvType = Conversion->getConversionType().getNonReferenceType(); if (!CandidateSet.isNewCandidate(Conversion)) return; // If the conversion function has an undeduced return type, trigger its // deduction now. if (getLangOpts().CPlusPlus14 && ConvType->isUndeducedType()) { if (DeduceReturnType(Conversion, From->getExprLoc())) return; ConvType = Conversion->getConversionType().getNonReferenceType(); } // If we don't allow any conversion of the result type, ignore conversion // functions that don't convert to exactly (possibly cv-qualified) T. if (!AllowResultConversion && !Context.hasSameUnqualifiedType(Conversion->getConversionType(), ToType)) return; // Per C++ [over.match.conv]p1, [over.match.ref]p1, an explicit conversion // operator is only a candidate if its return type is the target type or // can be converted to the target type with a qualification conversion. // // FIXME: Include such functions in the candidate list and explain why we // can't select them. if (Conversion->isExplicit() && !isAllowableExplicitConversion(*this, ConvType, ToType, AllowObjCConversionOnExplicit)) return; // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); // Add this candidate OverloadCandidate &Candidate = CandidateSet.addCandidate(1); Candidate.FoundDecl = FoundDecl; Candidate.Function = Conversion; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.FinalConversion.setAsIdentityConversion(); Candidate.FinalConversion.setFromType(ConvType); Candidate.FinalConversion.setAllToTypes(ToType); Candidate.Viable = true; Candidate.ExplicitCallArguments = 1; // Explicit functions are not actually candidates at all if we're not // allowing them in this context, but keep them around so we can point // to them in diagnostics. if (!AllowExplicit && Conversion->isExplicit()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_explicit; return; } // C++ [over.match.funcs]p4: // For conversion functions, the function is considered to be a member of // the class of the implicit implied object argument for the purpose of // defining the type of the implicit object parameter. // // Determine the implicit conversion sequence for the implicit // object parameter. QualType ImplicitParamType = From->getType(); if (const PointerType *FromPtrType = ImplicitParamType->getAs()) ImplicitParamType = FromPtrType->getPointeeType(); CXXRecordDecl *ConversionContext = cast(ImplicitParamType->castAs()->getDecl()); Candidate.Conversions[0] = TryObjectArgumentInitialization( *this, CandidateSet.getLocation(), From->getType(), From->Classify(Context), Conversion, ConversionContext); if (Candidate.Conversions[0].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; return; } if (Conversion->getTrailingRequiresClause()) { ConstraintSatisfaction Satisfaction; if (CheckFunctionConstraints(Conversion, Satisfaction) || !Satisfaction.IsSatisfied) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_constraints_not_satisfied; return; } } // We won't go through a user-defined type conversion function to convert a // derived to base as such conversions are given Conversion Rank. They only // go through a copy constructor. 13.3.3.1.2-p4 [over.ics.user] QualType FromCanon = Context.getCanonicalType(From->getType().getUnqualifiedType()); QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType(); if (FromCanon == ToCanon || IsDerivedFrom(CandidateSet.getLocation(), FromCanon, ToCanon)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_trivial_conversion; return; } // To determine what the conversion from the result of calling the // conversion function to the type we're eventually trying to // convert to (ToType), we need to synthesize a call to the // conversion function and attempt copy initialization from it. This // makes sure that we get the right semantics with respect to // lvalues/rvalues and the type. Fortunately, we can allocate this // call on the stack and we don't need its arguments to be // well-formed. DeclRefExpr ConversionRef(Context, Conversion, false, Conversion->getType(), VK_LValue, From->getBeginLoc()); ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack, Context.getPointerType(Conversion->getType()), CK_FunctionToPointerDecay, &ConversionRef, VK_RValue); QualType ConversionType = Conversion->getConversionType(); if (!isCompleteType(From->getBeginLoc(), ConversionType)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_final_conversion; return; } ExprValueKind VK = Expr::getValueKindForType(ConversionType); // Note that it is safe to allocate CallExpr on the stack here because // there are 0 arguments (i.e., nothing is allocated using ASTContext's // allocator). QualType CallResultType = ConversionType.getNonLValueExprType(Context); alignas(CallExpr) char Buffer[sizeof(CallExpr) + sizeof(Stmt *)]; CallExpr *TheTemporaryCall = CallExpr::CreateTemporary( Buffer, &ConversionFn, CallResultType, VK, From->getBeginLoc()); ImplicitConversionSequence ICS = TryCopyInitialization(*this, TheTemporaryCall, ToType, /*SuppressUserConversions=*/true, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/false); switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: Candidate.FinalConversion = ICS.Standard; // C++ [over.ics.user]p3: // If the user-defined conversion is specified by a specialization of a // conversion function template, the second standard conversion sequence // shall have exact match rank. if (Conversion->getPrimaryTemplate() && GetConversionRank(ICS.Standard.Second) != ICR_Exact_Match) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_final_conversion_not_exact; return; } // C++0x [dcl.init.ref]p5: // In the second case, if the reference is an rvalue reference and // the second standard conversion sequence of the user-defined // conversion sequence includes an lvalue-to-rvalue conversion, the // program is ill-formed. if (ToType->isRValueReferenceType() && ICS.Standard.First == ICK_Lvalue_To_Rvalue) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_final_conversion; return; } break; case ImplicitConversionSequence::BadConversion: Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_final_conversion; return; default: llvm_unreachable( "Can only end up with a standard conversion sequence or failure"); } if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, None)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; Candidate.DeductionFailure.Data = FailedAttr; return; } if (Conversion->isMultiVersion() && Conversion->hasAttr() && !Conversion->getAttr()->isDefaultVersion()) { Candidate.Viable = false; Candidate.FailureKind = ovl_non_default_multiversion_function; } } /// Adds a conversion function template specialization /// candidate to the overload set, using template argument deduction /// to deduce the template arguments of the conversion function /// template from the type that we are converting to (C++ /// [temp.deduct.conv]). void Sema::AddTemplateConversionCandidate( FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, CXXRecordDecl *ActingDC, Expr *From, QualType ToType, OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, bool AllowExplicit, bool AllowResultConversion) { assert(isa(FunctionTemplate->getTemplatedDecl()) && "Only conversion function templates permitted here"); if (!CandidateSet.isNewCandidate(FunctionTemplate)) return; // If the function template has a non-dependent explicit specification, // exclude it now if appropriate; we are not permitted to perform deduction // and substitution in this case. if (!AllowExplicit && isNonDependentlyExplicit(FunctionTemplate)) { OverloadCandidate &Candidate = CandidateSet.addCandidate(); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.FailureKind = ovl_fail_explicit; return; } TemplateDeductionInfo Info(CandidateSet.getLocation()); CXXConversionDecl *Specialization = nullptr; if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, ToType, Specialization, Info)) { OverloadCandidate &Candidate = CandidateSet.addCandidate(); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = 1; Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, Info); return; } // Add the conversion function template specialization produced by // template argument deduction as a candidate. assert(Specialization && "Missing function template specialization?"); AddConversionCandidate(Specialization, FoundDecl, ActingDC, From, ToType, CandidateSet, AllowObjCConversionOnExplicit, AllowExplicit, AllowResultConversion); } /// AddSurrogateCandidate - Adds a "surrogate" candidate function that /// converts the given @c Object to a function pointer via the /// conversion function @c Conversion, and then attempts to call it /// with the given arguments (C++ [over.call.object]p2-4). Proto is /// the type of function that we'll eventually be calling. void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, const FunctionProtoType *Proto, Expr *Object, ArrayRef Args, OverloadCandidateSet& CandidateSet) { if (!CandidateSet.isNewCandidate(Conversion)) return; // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1); Candidate.FoundDecl = FoundDecl; Candidate.Function = nullptr; Candidate.Surrogate = Conversion; Candidate.Viable = true; Candidate.IsSurrogate = true; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = Args.size(); // Determine the implicit conversion sequence for the implicit // object parameter. ImplicitConversionSequence ObjectInit = TryObjectArgumentInitialization( *this, CandidateSet.getLocation(), Object->getType(), Object->Classify(Context), Conversion, ActingContext); if (ObjectInit.isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; Candidate.Conversions[0] = ObjectInit; return; } // The first conversion is actually a user-defined conversion whose // first conversion is ObjectInit's standard conversion (which is // effectively a reference binding). Record it as such. Candidate.Conversions[0].setUserDefined(); Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard; Candidate.Conversions[0].UserDefined.EllipsisConversion = false; Candidate.Conversions[0].UserDefined.HadMultipleCandidates = false; Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion; Candidate.Conversions[0].UserDefined.FoundConversionFunction = FoundDecl; Candidate.Conversions[0].UserDefined.After = Candidate.Conversions[0].UserDefined.Before; Candidate.Conversions[0].UserDefined.After.setAsIdentityConversion(); // Find the unsigned NumParams = Proto->getNumParams(); // (C++ 13.3.2p2): A candidate function having fewer than m // parameters is viable only if it has an ellipsis in its parameter // list (8.3.5). if (Args.size() > NumParams && !Proto->isVariadic()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_many_arguments; return; } // Function types don't have any default arguments, so just check if // we have enough arguments. if (Args.size() < NumParams) { // Not enough arguments. Candidate.Viable = false; Candidate.FailureKind = ovl_fail_too_few_arguments; return; } // Determine the implicit conversion sequences for each of the // arguments. for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { if (ArgIdx < NumParams) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding // parameter of F. QualType ParamType = Proto->getParamType(ArgIdx); Candidate.Conversions[ArgIdx + 1] = TryCopyInitialization(*this, Args[ArgIdx], ParamType, /*SuppressUserConversions=*/false, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount); if (Candidate.Conversions[ArgIdx + 1].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; return; } } else { // (C++ 13.3.2p2): For the purposes of overload resolution, any // argument for which there is no corresponding parameter is // considered to ""match the ellipsis" (C+ 13.3.3.1.3). Candidate.Conversions[ArgIdx + 1].setEllipsis(); } } if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, None)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; Candidate.DeductionFailure.Data = FailedAttr; return; } } /// Add all of the non-member operator function declarations in the given /// function set to the overload candidate set. void Sema::AddNonMemberOperatorCandidates( const UnresolvedSetImpl &Fns, ArrayRef Args, OverloadCandidateSet &CandidateSet, TemplateArgumentListInfo *ExplicitTemplateArgs) { for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { NamedDecl *D = F.getDecl()->getUnderlyingDecl(); ArrayRef FunctionArgs = Args; FunctionTemplateDecl *FunTmpl = dyn_cast(D); FunctionDecl *FD = FunTmpl ? FunTmpl->getTemplatedDecl() : cast(D); // Don't consider rewritten functions if we're not rewriting. if (!CandidateSet.getRewriteInfo().isAcceptableCandidate(FD)) continue; assert(!isa(FD) && "unqualified operator lookup found a member function"); if (FunTmpl) { AddTemplateOverloadCandidate(FunTmpl, F.getPair(), ExplicitTemplateArgs, FunctionArgs, CandidateSet); if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) AddTemplateOverloadCandidate( FunTmpl, F.getPair(), ExplicitTemplateArgs, {FunctionArgs[1], FunctionArgs[0]}, CandidateSet, false, false, true, ADLCallKind::NotADL, OverloadCandidateParamOrder::Reversed); } else { if (ExplicitTemplateArgs) continue; AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet); if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) AddOverloadCandidate(FD, F.getPair(), {FunctionArgs[1], FunctionArgs[0]}, CandidateSet, false, false, true, false, ADLCallKind::NotADL, None, OverloadCandidateParamOrder::Reversed); } } } /// Add overload candidates for overloaded operators that are /// member functions. /// /// Add the overloaded operator candidates that are member functions /// for the operator Op that was used in an operator expression such /// as "x Op y". , Args/NumArgs provides the operator arguments, and /// CandidateSet will store the added overload candidates. (C++ /// [over.match.oper]). void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, SourceLocation OpLoc, ArrayRef Args, OverloadCandidateSet &CandidateSet, OverloadCandidateParamOrder PO) { DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); // C++ [over.match.oper]p3: // For a unary operator @ with an operand of a type whose // cv-unqualified version is T1, and for a binary operator @ with // a left operand of a type whose cv-unqualified version is T1 and // a right operand of a type whose cv-unqualified version is T2, // three sets of candidate functions, designated member // candidates, non-member candidates and built-in candidates, are // constructed as follows: QualType T1 = Args[0]->getType(); // -- If T1 is a complete class type or a class currently being // defined, the set of member candidates is the result of the // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, // the set of member candidates is empty. if (const RecordType *T1Rec = T1->getAs()) { // Complete the type if it can be completed. if (!isCompleteType(OpLoc, T1) && !T1Rec->isBeingDefined()) return; // If the type is neither complete nor being defined, bail out now. if (!T1Rec->getDecl()->getDefinition()) return; LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName); LookupQualifiedName(Operators, T1Rec->getDecl()); Operators.suppressDiagnostics(); for (LookupResult::iterator Oper = Operators.begin(), OperEnd = Operators.end(); Oper != OperEnd; ++Oper) AddMethodCandidate(Oper.getPair(), Args[0]->getType(), Args[0]->Classify(Context), Args.slice(1), CandidateSet, /*SuppressUserConversion=*/false, PO); } } /// AddBuiltinCandidate - Add a candidate for a built-in /// operator. ResultTy and ParamTys are the result and parameter types /// of the built-in candidate, respectively. Args and NumArgs are the /// arguments being passed to the candidate. IsAssignmentOperator /// should be true when this built-in candidate is an assignment /// operator. NumContextualBoolArguments is the number of arguments /// (at the beginning of the argument list) that will be contextually /// converted to bool. void Sema::AddBuiltinCandidate(QualType *ParamTys, ArrayRef Args, OverloadCandidateSet& CandidateSet, bool IsAssignmentOperator, unsigned NumContextualBoolArguments) { // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated( *this, Sema::ExpressionEvaluationContext::Unevaluated); // Add this candidate OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); Candidate.FoundDecl = DeclAccessPair::make(nullptr, AS_none); Candidate.Function = nullptr; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; std::copy(ParamTys, ParamTys + Args.size(), Candidate.BuiltinParamTypes); // Determine the implicit conversion sequences for each of the // arguments. Candidate.Viable = true; Candidate.ExplicitCallArguments = Args.size(); for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { // C++ [over.match.oper]p4: // For the built-in assignment operators, conversions of the // left operand are restricted as follows: // -- no temporaries are introduced to hold the left operand, and // -- no user-defined conversions are applied to the left // operand to achieve a type match with the left-most // parameter of a built-in candidate. // // We block these conversions by turning off user-defined // conversions, since that is the only way that initialization of // a reference to a non-class type can occur from something that // is not of the same type. if (ArgIdx < NumContextualBoolArguments) { assert(ParamTys[ArgIdx] == Context.BoolTy && "Contextual conversion to bool requires bool type"); Candidate.Conversions[ArgIdx] = TryContextuallyConvertToBool(*this, Args[ArgIdx]); } else { Candidate.Conversions[ArgIdx] = TryCopyInitialization(*this, Args[ArgIdx], ParamTys[ArgIdx], ArgIdx == 0 && IsAssignmentOperator, /*InOverloadResolution=*/false, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount); } if (Candidate.Conversions[ArgIdx].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; break; } } } namespace { /// BuiltinCandidateTypeSet - A set of types that will be used for the /// candidate operator functions for built-in operators (C++ /// [over.built]). The types are separated into pointer types and /// enumeration types. class BuiltinCandidateTypeSet { /// TypeSet - A set of types. typedef llvm::SetVector, llvm::SmallPtrSet> TypeSet; /// PointerTypes - The set of pointer types that will be used in the /// built-in candidates. TypeSet PointerTypes; /// MemberPointerTypes - The set of member pointer types that will be /// used in the built-in candidates. TypeSet MemberPointerTypes; /// EnumerationTypes - The set of enumeration types that will be /// used in the built-in candidates. TypeSet EnumerationTypes; /// The set of vector types that will be used in the built-in /// candidates. TypeSet VectorTypes; /// A flag indicating non-record types are viable candidates bool HasNonRecordTypes; /// A flag indicating whether either arithmetic or enumeration types /// were present in the candidate set. bool HasArithmeticOrEnumeralTypes; /// A flag indicating whether the nullptr type was present in the /// candidate set. bool HasNullPtrType; /// Sema - The semantic analysis instance where we are building the /// candidate type set. Sema &SemaRef; /// Context - The AST context in which we will build the type sets. ASTContext &Context; bool AddPointerWithMoreQualifiedTypeVariants(QualType Ty, const Qualifiers &VisibleQuals); bool AddMemberPointerWithMoreQualifiedTypeVariants(QualType Ty); public: /// iterator - Iterates through the types that are part of the set. typedef TypeSet::iterator iterator; BuiltinCandidateTypeSet(Sema &SemaRef) : HasNonRecordTypes(false), HasArithmeticOrEnumeralTypes(false), HasNullPtrType(false), SemaRef(SemaRef), Context(SemaRef.Context) { } void AddTypesConvertedFrom(QualType Ty, SourceLocation Loc, bool AllowUserConversions, bool AllowExplicitConversions, const Qualifiers &VisibleTypeConversionsQuals); /// pointer_begin - First pointer type found; iterator pointer_begin() { return PointerTypes.begin(); } /// pointer_end - Past the last pointer type found; iterator pointer_end() { return PointerTypes.end(); } /// member_pointer_begin - First member pointer type found; iterator member_pointer_begin() { return MemberPointerTypes.begin(); } /// member_pointer_end - Past the last member pointer type found; iterator member_pointer_end() { return MemberPointerTypes.end(); } /// enumeration_begin - First enumeration type found; iterator enumeration_begin() { return EnumerationTypes.begin(); } /// enumeration_end - Past the last enumeration type found; iterator enumeration_end() { return EnumerationTypes.end(); } iterator vector_begin() { return VectorTypes.begin(); } iterator vector_end() { return VectorTypes.end(); } bool hasNonRecordTypes() { return HasNonRecordTypes; } bool hasArithmeticOrEnumeralTypes() { return HasArithmeticOrEnumeralTypes; } bool hasNullPtrType() const { return HasNullPtrType; } }; } // end anonymous namespace /// AddPointerWithMoreQualifiedTypeVariants - Add the pointer type @p Ty to /// the set of pointer types along with any more-qualified variants of /// that type. For example, if @p Ty is "int const *", this routine /// will add "int const *", "int const volatile *", "int const /// restrict *", and "int const volatile restrict *" to the set of /// pointer types. Returns true if the add of @p Ty itself succeeded, /// false otherwise. /// /// FIXME: what to do about extended qualifiers? bool BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty, const Qualifiers &VisibleQuals) { // Insert this type. if (!PointerTypes.insert(Ty)) return false; QualType PointeeTy; const PointerType *PointerTy = Ty->getAs(); bool buildObjCPtr = false; if (!PointerTy) { const ObjCObjectPointerType *PTy = Ty->castAs(); PointeeTy = PTy->getPointeeType(); buildObjCPtr = true; } else { PointeeTy = PointerTy->getPointeeType(); } // Don't add qualified variants of arrays. For one, they're not allowed // (the qualifier would sink to the element type), and for another, the // only overload situation where it matters is subscript or pointer +- int, // and those shouldn't have qualifier variants anyway. if (PointeeTy->isArrayType()) return true; unsigned BaseCVR = PointeeTy.getCVRQualifiers(); bool hasVolatile = VisibleQuals.hasVolatile(); bool hasRestrict = VisibleQuals.hasRestrict(); // Iterate through all strict supersets of BaseCVR. for (unsigned CVR = BaseCVR+1; CVR <= Qualifiers::CVRMask; ++CVR) { if ((CVR | BaseCVR) != CVR) continue; // Skip over volatile if no volatile found anywhere in the types. if ((CVR & Qualifiers::Volatile) && !hasVolatile) continue; // Skip over restrict if no restrict found anywhere in the types, or if // the type cannot be restrict-qualified. if ((CVR & Qualifiers::Restrict) && (!hasRestrict || (!(PointeeTy->isAnyPointerType() || PointeeTy->isReferenceType())))) continue; // Build qualified pointee type. QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR); // Build qualified pointer type. QualType QPointerTy; if (!buildObjCPtr) QPointerTy = Context.getPointerType(QPointeeTy); else QPointerTy = Context.getObjCObjectPointerType(QPointeeTy); // Insert qualified pointer type. PointerTypes.insert(QPointerTy); } return true; } /// AddMemberPointerWithMoreQualifiedTypeVariants - Add the pointer type @p Ty /// to the set of pointer types along with any more-qualified variants of /// that type. For example, if @p Ty is "int const *", this routine /// will add "int const *", "int const volatile *", "int const /// restrict *", and "int const volatile restrict *" to the set of /// pointer types. Returns true if the add of @p Ty itself succeeded, /// false otherwise. /// /// FIXME: what to do about extended qualifiers? bool BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants( QualType Ty) { // Insert this type. if (!MemberPointerTypes.insert(Ty)) return false; const MemberPointerType *PointerTy = Ty->getAs(); assert(PointerTy && "type was not a member pointer type!"); QualType PointeeTy = PointerTy->getPointeeType(); // Don't add qualified variants of arrays. For one, they're not allowed // (the qualifier would sink to the element type), and for another, the // only overload situation where it matters is subscript or pointer +- int, // and those shouldn't have qualifier variants anyway. if (PointeeTy->isArrayType()) return true; const Type *ClassTy = PointerTy->getClass(); // Iterate through all strict supersets of the pointee type's CVR // qualifiers. unsigned BaseCVR = PointeeTy.getCVRQualifiers(); for (unsigned CVR = BaseCVR+1; CVR <= Qualifiers::CVRMask; ++CVR) { if ((CVR | BaseCVR) != CVR) continue; QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR); MemberPointerTypes.insert( Context.getMemberPointerType(QPointeeTy, ClassTy)); } return true; } /// AddTypesConvertedFrom - Add each of the types to which the type @p /// Ty can be implicit converted to the given set of @p Types. We're /// primarily interested in pointer types and enumeration types. We also /// take member pointer types, for the conditional operator. /// AllowUserConversions is true if we should look at the conversion /// functions of a class type, and AllowExplicitConversions if we /// should also include the explicit conversion functions of a class /// type. void BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty, SourceLocation Loc, bool AllowUserConversions, bool AllowExplicitConversions, const Qualifiers &VisibleQuals) { // Only deal with canonical types. Ty = Context.getCanonicalType(Ty); // Look through reference types; they aren't part of the type of an // expression for the purposes of conversions. if (const ReferenceType *RefTy = Ty->getAs()) Ty = RefTy->getPointeeType(); // If we're dealing with an array type, decay to the pointer. if (Ty->isArrayType()) Ty = SemaRef.Context.getArrayDecayedType(Ty); // Otherwise, we don't care about qualifiers on the type. Ty = Ty.getLocalUnqualifiedType(); // Flag if we ever add a non-record type. const RecordType *TyRec = Ty->getAs(); HasNonRecordTypes = HasNonRecordTypes || !TyRec; // Flag if we encounter an arithmetic type. HasArithmeticOrEnumeralTypes = HasArithmeticOrEnumeralTypes || Ty->isArithmeticType(); if (Ty->isObjCIdType() || Ty->isObjCClassType()) PointerTypes.insert(Ty); else if (Ty->getAs() || Ty->getAs()) { // Insert our type, and its more-qualified variants, into the set // of types. if (!AddPointerWithMoreQualifiedTypeVariants(Ty, VisibleQuals)) return; } else if (Ty->isMemberPointerType()) { // Member pointers are far easier, since the pointee can't be converted. if (!AddMemberPointerWithMoreQualifiedTypeVariants(Ty)) return; } else if (Ty->isEnumeralType()) { HasArithmeticOrEnumeralTypes = true; EnumerationTypes.insert(Ty); } else if (Ty->isVectorType()) { // We treat vector types as arithmetic types in many contexts as an // extension. HasArithmeticOrEnumeralTypes = true; VectorTypes.insert(Ty); } else if (Ty->isNullPtrType()) { HasNullPtrType = true; } else if (AllowUserConversions && TyRec) { // No conversion functions in incomplete types. if (!SemaRef.isCompleteType(Loc, Ty)) return; CXXRecordDecl *ClassDecl = cast(TyRec->getDecl()); for (NamedDecl *D : ClassDecl->getVisibleConversionFunctions()) { if (isa(D)) D = cast(D)->getTargetDecl(); // Skip conversion function templates; they don't tell us anything // about which builtin types we can convert to. if (isa(D)) continue; CXXConversionDecl *Conv = cast(D); if (AllowExplicitConversions || !Conv->isExplicit()) { AddTypesConvertedFrom(Conv->getConversionType(), Loc, false, false, VisibleQuals); } } } } /// Helper function for adjusting address spaces for the pointer or reference /// operands of builtin operators depending on the argument. static QualType AdjustAddressSpaceForBuiltinOperandType(Sema &S, QualType T, Expr *Arg) { return S.Context.getAddrSpaceQualType(T, Arg->getType().getAddressSpace()); } /// Helper function for AddBuiltinOperatorCandidates() that adds /// the volatile- and non-volatile-qualified assignment operators for the /// given type to the candidate set. static void AddBuiltinAssignmentOperatorCandidates(Sema &S, QualType T, ArrayRef Args, OverloadCandidateSet &CandidateSet) { QualType ParamTypes[2]; // T& operator=(T&, T) ParamTypes[0] = S.Context.getLValueReferenceType( AdjustAddressSpaceForBuiltinOperandType(S, T, Args[0])); ParamTypes[1] = T; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); if (!S.Context.getCanonicalType(T).isVolatileQualified()) { // volatile T& operator=(volatile T&, T) ParamTypes[0] = S.Context.getLValueReferenceType( AdjustAddressSpaceForBuiltinOperandType(S, S.Context.getVolatileType(T), Args[0])); ParamTypes[1] = T; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); } } /// CollectVRQualifiers - This routine returns Volatile/Restrict qualifiers, /// if any, found in visible type conversion functions found in ArgExpr's type. static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) { Qualifiers VRQuals; const RecordType *TyRec; if (const MemberPointerType *RHSMPType = ArgExpr->getType()->getAs()) TyRec = RHSMPType->getClass()->getAs(); else TyRec = ArgExpr->getType()->getAs(); if (!TyRec) { // Just to be safe, assume the worst case. VRQuals.addVolatile(); VRQuals.addRestrict(); return VRQuals; } CXXRecordDecl *ClassDecl = cast(TyRec->getDecl()); if (!ClassDecl->hasDefinition()) return VRQuals; for (NamedDecl *D : ClassDecl->getVisibleConversionFunctions()) { if (isa(D)) D = cast(D)->getTargetDecl(); if (CXXConversionDecl *Conv = dyn_cast(D)) { QualType CanTy = Context.getCanonicalType(Conv->getConversionType()); if (const ReferenceType *ResTypeRef = CanTy->getAs()) CanTy = ResTypeRef->getPointeeType(); // Need to go down the pointer/mempointer chain and add qualifiers // as see them. bool done = false; while (!done) { if (CanTy.isRestrictQualified()) VRQuals.addRestrict(); if (const PointerType *ResTypePtr = CanTy->getAs()) CanTy = ResTypePtr->getPointeeType(); else if (const MemberPointerType *ResTypeMPtr = CanTy->getAs()) CanTy = ResTypeMPtr->getPointeeType(); else done = true; if (CanTy.isVolatileQualified()) VRQuals.addVolatile(); if (VRQuals.hasRestrict() && VRQuals.hasVolatile()) return VRQuals; } } } return VRQuals; } namespace { /// Helper class to manage the addition of builtin operator overload /// candidates. It provides shared state and utility methods used throughout /// the process, as well as a helper method to add each group of builtin /// operator overloads from the standard to a candidate set. class BuiltinOperatorOverloadBuilder { // Common instance state available to all overload candidate addition methods. Sema &S; ArrayRef Args; Qualifiers VisibleTypeConversionsQuals; bool HasArithmeticOrEnumeralCandidateType; SmallVectorImpl &CandidateTypes; OverloadCandidateSet &CandidateSet; static constexpr int ArithmeticTypesCap = 24; SmallVector ArithmeticTypes; // Define some indices used to iterate over the arithmetic types in // ArithmeticTypes. The "promoted arithmetic types" are the arithmetic // types are that preserved by promotion (C++ [over.built]p2). unsigned FirstIntegralType, LastIntegralType; unsigned FirstPromotedIntegralType, LastPromotedIntegralType; unsigned FirstPromotedArithmeticType, LastPromotedArithmeticType; unsigned NumArithmeticTypes; void InitArithmeticTypes() { // Start of promoted types. FirstPromotedArithmeticType = 0; ArithmeticTypes.push_back(S.Context.FloatTy); ArithmeticTypes.push_back(S.Context.DoubleTy); ArithmeticTypes.push_back(S.Context.LongDoubleTy); if (S.Context.getTargetInfo().hasFloat128Type()) ArithmeticTypes.push_back(S.Context.Float128Ty); // Start of integral types. FirstIntegralType = ArithmeticTypes.size(); FirstPromotedIntegralType = ArithmeticTypes.size(); ArithmeticTypes.push_back(S.Context.IntTy); ArithmeticTypes.push_back(S.Context.LongTy); ArithmeticTypes.push_back(S.Context.LongLongTy); if (S.Context.getTargetInfo().hasInt128Type()) ArithmeticTypes.push_back(S.Context.Int128Ty); ArithmeticTypes.push_back(S.Context.UnsignedIntTy); ArithmeticTypes.push_back(S.Context.UnsignedLongTy); ArithmeticTypes.push_back(S.Context.UnsignedLongLongTy); if (S.Context.getTargetInfo().hasInt128Type()) ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty); LastPromotedIntegralType = ArithmeticTypes.size(); LastPromotedArithmeticType = ArithmeticTypes.size(); // End of promoted types. ArithmeticTypes.push_back(S.Context.BoolTy); ArithmeticTypes.push_back(S.Context.CharTy); ArithmeticTypes.push_back(S.Context.WCharTy); if (S.Context.getLangOpts().Char8) ArithmeticTypes.push_back(S.Context.Char8Ty); ArithmeticTypes.push_back(S.Context.Char16Ty); ArithmeticTypes.push_back(S.Context.Char32Ty); ArithmeticTypes.push_back(S.Context.SignedCharTy); ArithmeticTypes.push_back(S.Context.ShortTy); ArithmeticTypes.push_back(S.Context.UnsignedCharTy); ArithmeticTypes.push_back(S.Context.UnsignedShortTy); LastIntegralType = ArithmeticTypes.size(); NumArithmeticTypes = ArithmeticTypes.size(); // End of integral types. // FIXME: What about complex? What about half? assert(ArithmeticTypes.size() <= ArithmeticTypesCap && "Enough inline storage for all arithmetic types."); } /// Helper method to factor out the common pattern of adding overloads /// for '++' and '--' builtin operators. void addPlusPlusMinusMinusStyleOverloads(QualType CandidateTy, bool HasVolatile, bool HasRestrict) { QualType ParamTypes[2] = { S.Context.getLValueReferenceType(CandidateTy), S.Context.IntTy }; // Non-volatile version. S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); // Use a heuristic to reduce number of builtin candidates in the set: // add volatile version only if there are conversions to a volatile type. if (HasVolatile) { ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getVolatileType(CandidateTy)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } // Add restrict version only if there are conversions to a restrict type // and our candidate type is a non-restrict-qualified pointer. if (HasRestrict && CandidateTy->isAnyPointerType() && !CandidateTy.isRestrictQualified()) { ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getCVRQualifiedType(CandidateTy, Qualifiers::Restrict)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); if (HasVolatile) { ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getCVRQualifiedType(CandidateTy, (Qualifiers::Volatile | Qualifiers::Restrict))); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } public: BuiltinOperatorOverloadBuilder( Sema &S, ArrayRef Args, Qualifiers VisibleTypeConversionsQuals, bool HasArithmeticOrEnumeralCandidateType, SmallVectorImpl &CandidateTypes, OverloadCandidateSet &CandidateSet) : S(S), Args(Args), VisibleTypeConversionsQuals(VisibleTypeConversionsQuals), HasArithmeticOrEnumeralCandidateType( HasArithmeticOrEnumeralCandidateType), CandidateTypes(CandidateTypes), CandidateSet(CandidateSet) { InitArithmeticTypes(); } // Increment is deprecated for bool since C++17. // // C++ [over.built]p3: // // For every pair (T, VQ), where T is an arithmetic type other // than bool, and VQ is either volatile or empty, there exist // candidate operator functions of the form // // VQ T& operator++(VQ T&); // T operator++(VQ T&, int); // // C++ [over.built]p4: // // For every pair (T, VQ), where T is an arithmetic type other // than bool, and VQ is either volatile or empty, there exist // candidate operator functions of the form // // VQ T& operator--(VQ T&); // T operator--(VQ T&, int); void addPlusPlusMinusMinusArithmeticOverloads(OverloadedOperatorKind Op) { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Arith = 0; Arith < NumArithmeticTypes; ++Arith) { const auto TypeOfT = ArithmeticTypes[Arith]; if (TypeOfT == S.Context.BoolTy) { if (Op == OO_MinusMinus) continue; if (Op == OO_PlusPlus && S.getLangOpts().CPlusPlus17) continue; } addPlusPlusMinusMinusStyleOverloads( TypeOfT, VisibleTypeConversionsQuals.hasVolatile(), VisibleTypeConversionsQuals.hasRestrict()); } } // C++ [over.built]p5: // // For every pair (T, VQ), where T is a cv-qualified or // cv-unqualified object type, and VQ is either volatile or // empty, there exist candidate operator functions of the form // // T*VQ& operator++(T*VQ&); // T*VQ& operator--(T*VQ&); // T* operator++(T*VQ&, int); // T* operator--(T*VQ&, int); void addPlusPlusMinusMinusPointerOverloads() { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { // Skip pointer types that aren't pointers to object types. if (!(*Ptr)->getPointeeType()->isObjectType()) continue; addPlusPlusMinusMinusStyleOverloads(*Ptr, (!(*Ptr).isVolatileQualified() && VisibleTypeConversionsQuals.hasVolatile()), (!(*Ptr).isRestrictQualified() && VisibleTypeConversionsQuals.hasRestrict())); } } // C++ [over.built]p6: // For every cv-qualified or cv-unqualified object type T, there // exist candidate operator functions of the form // // T& operator*(T*); // // C++ [over.built]p7: // For every function type T that does not have cv-qualifiers or a // ref-qualifier, there exist candidate operator functions of the form // T& operator*(T*); void addUnaryStarPointerOverloads() { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType ParamTy = *Ptr; QualType PointeeTy = ParamTy->getPointeeType(); if (!PointeeTy->isObjectType() && !PointeeTy->isFunctionType()) continue; if (const FunctionProtoType *Proto =PointeeTy->getAs()) if (Proto->getMethodQuals() || Proto->getRefQualifier()) continue; S.AddBuiltinCandidate(&ParamTy, Args, CandidateSet); } } // C++ [over.built]p9: // For every promoted arithmetic type T, there exist candidate // operator functions of the form // // T operator+(T); // T operator-(T); void addUnaryPlusOrMinusArithmeticOverloads() { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Arith = FirstPromotedArithmeticType; Arith < LastPromotedArithmeticType; ++Arith) { QualType ArithTy = ArithmeticTypes[Arith]; S.AddBuiltinCandidate(&ArithTy, Args, CandidateSet); } // Extension: We also add these operators for vector types. for (BuiltinCandidateTypeSet::iterator Vec = CandidateTypes[0].vector_begin(), VecEnd = CandidateTypes[0].vector_end(); Vec != VecEnd; ++Vec) { QualType VecTy = *Vec; S.AddBuiltinCandidate(&VecTy, Args, CandidateSet); } } // C++ [over.built]p8: // For every type T, there exist candidate operator functions of // the form // // T* operator+(T*); void addUnaryPlusPointerOverloads() { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType ParamTy = *Ptr; S.AddBuiltinCandidate(&ParamTy, Args, CandidateSet); } } // C++ [over.built]p10: // For every promoted integral type T, there exist candidate // operator functions of the form // // T operator~(T); void addUnaryTildePromotedIntegralOverloads() { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Int = FirstPromotedIntegralType; Int < LastPromotedIntegralType; ++Int) { QualType IntTy = ArithmeticTypes[Int]; S.AddBuiltinCandidate(&IntTy, Args, CandidateSet); } // Extension: We also add this operator for vector types. for (BuiltinCandidateTypeSet::iterator Vec = CandidateTypes[0].vector_begin(), VecEnd = CandidateTypes[0].vector_end(); Vec != VecEnd; ++Vec) { QualType VecTy = *Vec; S.AddBuiltinCandidate(&VecTy, Args, CandidateSet); } } // C++ [over.match.oper]p16: // For every pointer to member type T or type std::nullptr_t, there // exist candidate operator functions of the form // // bool operator==(T,T); // bool operator!=(T,T); void addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads() { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(), MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end(); MemPtr != MemPtrEnd; ++MemPtr) { // Don't add the same builtin candidate twice. if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)).second) continue; QualType ParamTypes[2] = { *MemPtr, *MemPtr }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } if (CandidateTypes[ArgIdx].hasNullPtrType()) { CanQualType NullPtrTy = S.Context.getCanonicalType(S.Context.NullPtrTy); if (AddedTypes.insert(NullPtrTy).second) { QualType ParamTypes[2] = { NullPtrTy, NullPtrTy }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } } // C++ [over.built]p15: // // For every T, where T is an enumeration type or a pointer type, // there exist candidate operator functions of the form // // bool operator<(T, T); // bool operator>(T, T); // bool operator<=(T, T); // bool operator>=(T, T); // bool operator==(T, T); // bool operator!=(T, T); // R operator<=>(T, T) void addGenericBinaryPointerOrEnumeralOverloads() { // C++ [over.match.oper]p3: // [...]the built-in candidates include all of the candidate operator // functions defined in 13.6 that, compared to the given operator, [...] // do not have the same parameter-type-list as any non-template non-member // candidate. // // Note that in practice, this only affects enumeration types because there // aren't any built-in candidates of record type, and a user-defined operator // must have an operand of record or enumeration type. Also, the only other // overloaded operator with enumeration arguments, operator=, // cannot be overloaded for enumeration types, so this is the only place // where we must suppress candidates like this. llvm::DenseSet > UserDefinedBinaryOperators; for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { if (CandidateTypes[ArgIdx].enumeration_begin() != CandidateTypes[ArgIdx].enumeration_end()) { for (OverloadCandidateSet::iterator C = CandidateSet.begin(), CEnd = CandidateSet.end(); C != CEnd; ++C) { if (!C->Viable || !C->Function || C->Function->getNumParams() != 2) continue; if (C->Function->isFunctionTemplateSpecialization()) continue; // We interpret "same parameter-type-list" as applying to the // "synthesized candidate, with the order of the two parameters // reversed", not to the original function. bool Reversed = C->RewriteKind & CRK_Reversed; QualType FirstParamType = C->Function->getParamDecl(Reversed ? 1 : 0) ->getType() .getUnqualifiedType(); QualType SecondParamType = C->Function->getParamDecl(Reversed ? 0 : 1) ->getType() .getUnqualifiedType(); // Skip if either parameter isn't of enumeral type. if (!FirstParamType->isEnumeralType() || !SecondParamType->isEnumeralType()) continue; // Add this operator to the set of known user-defined operators. UserDefinedBinaryOperators.insert( std::make_pair(S.Context.getCanonicalType(FirstParamType), S.Context.getCanonicalType(SecondParamType))); } } } /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[ArgIdx].pointer_begin(), PtrEnd = CandidateTypes[ArgIdx].pointer_end(); Ptr != PtrEnd; ++Ptr) { // Don't add the same builtin candidate twice. if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second) continue; QualType ParamTypes[2] = { *Ptr, *Ptr }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator Enum = CandidateTypes[ArgIdx].enumeration_begin(), EnumEnd = CandidateTypes[ArgIdx].enumeration_end(); Enum != EnumEnd; ++Enum) { CanQualType CanonType = S.Context.getCanonicalType(*Enum); // Don't add the same builtin candidate twice, or if a user defined // candidate exists. if (!AddedTypes.insert(CanonType).second || UserDefinedBinaryOperators.count(std::make_pair(CanonType, CanonType))) continue; QualType ParamTypes[2] = { *Enum, *Enum }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } // C++ [over.built]p13: // // For every cv-qualified or cv-unqualified object type T // there exist candidate operator functions of the form // // T* operator+(T*, ptrdiff_t); // T& operator[](T*, ptrdiff_t); [BELOW] // T* operator-(T*, ptrdiff_t); // T* operator+(ptrdiff_t, T*); // T& operator[](ptrdiff_t, T*); [BELOW] // // C++ [over.built]p14: // // For every T, where T is a pointer to object type, there // exist candidate operator functions of the form // // ptrdiff_t operator-(T, T); void addBinaryPlusOrMinusPointerOverloads(OverloadedOperatorKind Op) { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (int Arg = 0; Arg < 2; ++Arg) { QualType AsymmetricParamTypes[2] = { S.Context.getPointerDiffType(), S.Context.getPointerDiffType(), }; for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[Arg].pointer_begin(), PtrEnd = CandidateTypes[Arg].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType PointeeTy = (*Ptr)->getPointeeType(); if (!PointeeTy->isObjectType()) continue; AsymmetricParamTypes[Arg] = *Ptr; if (Arg == 0 || Op == OO_Plus) { // operator+(T*, ptrdiff_t) or operator-(T*, ptrdiff_t) // T* operator+(ptrdiff_t, T*); S.AddBuiltinCandidate(AsymmetricParamTypes, Args, CandidateSet); } if (Op == OO_Minus) { // ptrdiff_t operator-(T, T); if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second) continue; QualType ParamTypes[2] = { *Ptr, *Ptr }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } } // C++ [over.built]p12: // // For every pair of promoted arithmetic types L and R, there // exist candidate operator functions of the form // // LR operator*(L, R); // LR operator/(L, R); // LR operator+(L, R); // LR operator-(L, R); // bool operator<(L, R); // bool operator>(L, R); // bool operator<=(L, R); // bool operator>=(L, R); // bool operator==(L, R); // bool operator!=(L, R); // // where LR is the result of the usual arithmetic conversions // between types L and R. // // C++ [over.built]p24: // // For every pair of promoted arithmetic types L and R, there exist // candidate operator functions of the form // // LR operator?(bool, L, R); // // where LR is the result of the usual arithmetic conversions // between types L and R. // Our candidates ignore the first parameter. void addGenericBinaryArithmeticOverloads() { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Left = FirstPromotedArithmeticType; Left < LastPromotedArithmeticType; ++Left) { for (unsigned Right = FirstPromotedArithmeticType; Right < LastPromotedArithmeticType; ++Right) { QualType LandR[2] = { ArithmeticTypes[Left], ArithmeticTypes[Right] }; S.AddBuiltinCandidate(LandR, Args, CandidateSet); } } // Extension: Add the binary operators ==, !=, <, <=, >=, >, *, /, and the // conditional operator for vector types. for (BuiltinCandidateTypeSet::iterator Vec1 = CandidateTypes[0].vector_begin(), Vec1End = CandidateTypes[0].vector_end(); Vec1 != Vec1End; ++Vec1) { for (BuiltinCandidateTypeSet::iterator Vec2 = CandidateTypes[1].vector_begin(), Vec2End = CandidateTypes[1].vector_end(); Vec2 != Vec2End; ++Vec2) { QualType LandR[2] = { *Vec1, *Vec2 }; S.AddBuiltinCandidate(LandR, Args, CandidateSet); } } } // C++2a [over.built]p14: // // For every integral type T there exists a candidate operator function // of the form // // std::strong_ordering operator<=>(T, T) // // C++2a [over.built]p15: // // For every pair of floating-point types L and R, there exists a candidate // operator function of the form // // std::partial_ordering operator<=>(L, R); // // FIXME: The current specification for integral types doesn't play nice with // the direction of p0946r0, which allows mixed integral and unscoped-enum // comparisons. Under the current spec this can lead to ambiguity during // overload resolution. For example: // // enum A : int {a}; // auto x = (a <=> (long)42); // // error: call is ambiguous for arguments 'A' and 'long'. // note: candidate operator<=>(int, int) // note: candidate operator<=>(long, long) // // To avoid this error, this function deviates from the specification and adds // the mixed overloads `operator<=>(L, R)` where L and R are promoted // arithmetic types (the same as the generic relational overloads). // // For now this function acts as a placeholder. void addThreeWayArithmeticOverloads() { addGenericBinaryArithmeticOverloads(); } // C++ [over.built]p17: // // For every pair of promoted integral types L and R, there // exist candidate operator functions of the form // // LR operator%(L, R); // LR operator&(L, R); // LR operator^(L, R); // LR operator|(L, R); // L operator<<(L, R); // L operator>>(L, R); // // where LR is the result of the usual arithmetic conversions // between types L and R. void addBinaryBitwiseArithmeticOverloads(OverloadedOperatorKind Op) { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Left = FirstPromotedIntegralType; Left < LastPromotedIntegralType; ++Left) { for (unsigned Right = FirstPromotedIntegralType; Right < LastPromotedIntegralType; ++Right) { QualType LandR[2] = { ArithmeticTypes[Left], ArithmeticTypes[Right] }; S.AddBuiltinCandidate(LandR, Args, CandidateSet); } } } // C++ [over.built]p20: // // For every pair (T, VQ), where T is an enumeration or // pointer to member type and VQ is either volatile or // empty, there exist candidate operator functions of the form // // VQ T& operator=(VQ T&, T); void addAssignmentMemberPointerOrEnumeralOverloads() { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (unsigned ArgIdx = 0; ArgIdx < 2; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator Enum = CandidateTypes[ArgIdx].enumeration_begin(), EnumEnd = CandidateTypes[ArgIdx].enumeration_end(); Enum != EnumEnd; ++Enum) { if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum)).second) continue; AddBuiltinAssignmentOperatorCandidates(S, *Enum, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(), MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end(); MemPtr != MemPtrEnd; ++MemPtr) { if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)).second) continue; AddBuiltinAssignmentOperatorCandidates(S, *MemPtr, Args, CandidateSet); } } } // C++ [over.built]p19: // // For every pair (T, VQ), where T is any type and VQ is either // volatile or empty, there exist candidate operator functions // of the form // // T*VQ& operator=(T*VQ&, T*); // // C++ [over.built]p21: // // For every pair (T, VQ), where T is a cv-qualified or // cv-unqualified object type and VQ is either volatile or // empty, there exist candidate operator functions of the form // // T*VQ& operator+=(T*VQ&, ptrdiff_t); // T*VQ& operator-=(T*VQ&, ptrdiff_t); void addAssignmentPointerOverloads(bool isEqualOp) { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { // If this is operator=, keep track of the builtin candidates we added. if (isEqualOp) AddedTypes.insert(S.Context.getCanonicalType(*Ptr)); else if (!(*Ptr)->getPointeeType()->isObjectType()) continue; // non-volatile version QualType ParamTypes[2] = { S.Context.getLValueReferenceType(*Ptr), isEqualOp ? *Ptr : S.Context.getPointerDiffType(), }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/ isEqualOp); bool NeedVolatile = !(*Ptr).isVolatileQualified() && VisibleTypeConversionsQuals.hasVolatile(); if (NeedVolatile) { // volatile version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); } if (!(*Ptr).isRestrictQualified() && VisibleTypeConversionsQuals.hasRestrict()) { // restrict version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); if (NeedVolatile) { // volatile restrict version ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getCVRQualifiedType(*Ptr, (Qualifiers::Volatile | Qualifiers::Restrict))); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); } } } if (isEqualOp) { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[1].pointer_begin(), PtrEnd = CandidateTypes[1].pointer_end(); Ptr != PtrEnd; ++Ptr) { // Make sure we don't add the same candidate twice. if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second) continue; QualType ParamTypes[2] = { S.Context.getLValueReferenceType(*Ptr), *Ptr, }; // non-volatile version S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); bool NeedVolatile = !(*Ptr).isVolatileQualified() && VisibleTypeConversionsQuals.hasVolatile(); if (NeedVolatile) { // volatile version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); } if (!(*Ptr).isRestrictQualified() && VisibleTypeConversionsQuals.hasRestrict()) { // restrict version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr)); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); if (NeedVolatile) { // volatile restrict version ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getCVRQualifiedType(*Ptr, (Qualifiers::Volatile | Qualifiers::Restrict))); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); } } } } } // C++ [over.built]p18: // // For every triple (L, VQ, R), where L is an arithmetic type, // VQ is either volatile or empty, and R is a promoted // arithmetic type, there exist candidate operator functions of // the form // // VQ L& operator=(VQ L&, R); // VQ L& operator*=(VQ L&, R); // VQ L& operator/=(VQ L&, R); // VQ L& operator+=(VQ L&, R); // VQ L& operator-=(VQ L&, R); void addAssignmentArithmeticOverloads(bool isEqualOp) { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Left = 0; Left < NumArithmeticTypes; ++Left) { for (unsigned Right = FirstPromotedArithmeticType; Right < LastPromotedArithmeticType; ++Right) { QualType ParamTypes[2]; ParamTypes[1] = ArithmeticTypes[Right]; auto LeftBaseTy = AdjustAddressSpaceForBuiltinOperandType( S, ArithmeticTypes[Left], Args[0]); // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(LeftBaseTy); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { ParamTypes[0] = S.Context.getVolatileType(LeftBaseTy); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); } } } // Extension: Add the binary operators =, +=, -=, *=, /= for vector types. for (BuiltinCandidateTypeSet::iterator Vec1 = CandidateTypes[0].vector_begin(), Vec1End = CandidateTypes[0].vector_end(); Vec1 != Vec1End; ++Vec1) { for (BuiltinCandidateTypeSet::iterator Vec2 = CandidateTypes[1].vector_begin(), Vec2End = CandidateTypes[1].vector_end(); Vec2 != Vec2End; ++Vec2) { QualType ParamTypes[2]; ParamTypes[1] = *Vec2; // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(*Vec1); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { ParamTypes[0] = S.Context.getVolatileType(*Vec1); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); } } } } // C++ [over.built]p22: // // For every triple (L, VQ, R), where L is an integral type, VQ // is either volatile or empty, and R is a promoted integral // type, there exist candidate operator functions of the form // // VQ L& operator%=(VQ L&, R); // VQ L& operator<<=(VQ L&, R); // VQ L& operator>>=(VQ L&, R); // VQ L& operator&=(VQ L&, R); // VQ L& operator^=(VQ L&, R); // VQ L& operator|=(VQ L&, R); void addAssignmentIntegralOverloads() { if (!HasArithmeticOrEnumeralCandidateType) return; for (unsigned Left = FirstIntegralType; Left < LastIntegralType; ++Left) { for (unsigned Right = FirstPromotedIntegralType; Right < LastPromotedIntegralType; ++Right) { QualType ParamTypes[2]; ParamTypes[1] = ArithmeticTypes[Right]; auto LeftBaseTy = AdjustAddressSpaceForBuiltinOperandType( S, ArithmeticTypes[Left], Args[0]); // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(LeftBaseTy); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); if (VisibleTypeConversionsQuals.hasVolatile()) { // Add this built-in operator as a candidate (VQ is 'volatile'). ParamTypes[0] = LeftBaseTy; ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } } // C++ [over.operator]p23: // // There also exist candidate operator functions of the form // // bool operator!(bool); // bool operator&&(bool, bool); // bool operator||(bool, bool); void addExclaimOverload() { QualType ParamTy = S.Context.BoolTy; S.AddBuiltinCandidate(&ParamTy, Args, CandidateSet, /*IsAssignmentOperator=*/false, /*NumContextualBoolArguments=*/1); } void addAmpAmpOrPipePipeOverload() { QualType ParamTypes[2] = { S.Context.BoolTy, S.Context.BoolTy }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/false, /*NumContextualBoolArguments=*/2); } // C++ [over.built]p13: // // For every cv-qualified or cv-unqualified object type T there // exist candidate operator functions of the form // // T* operator+(T*, ptrdiff_t); [ABOVE] // T& operator[](T*, ptrdiff_t); // T* operator-(T*, ptrdiff_t); [ABOVE] // T* operator+(ptrdiff_t, T*); [ABOVE] // T& operator[](ptrdiff_t, T*); void addSubscriptOverloads() { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType ParamTypes[2] = { *Ptr, S.Context.getPointerDiffType() }; QualType PointeeType = (*Ptr)->getPointeeType(); if (!PointeeType->isObjectType()) continue; // T& operator[](T*, ptrdiff_t) S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[1].pointer_begin(), PtrEnd = CandidateTypes[1].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType ParamTypes[2] = { S.Context.getPointerDiffType(), *Ptr }; QualType PointeeType = (*Ptr)->getPointeeType(); if (!PointeeType->isObjectType()) continue; // T& operator[](ptrdiff_t, T*) S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } // C++ [over.built]p11: // For every quintuple (C1, C2, T, CV1, CV2), where C2 is a class type, // C1 is the same type as C2 or is a derived class of C2, T is an object // type or a function type, and CV1 and CV2 are cv-qualifier-seqs, // there exist candidate operator functions of the form // // CV12 T& operator->*(CV1 C1*, CV2 T C2::*); // // where CV12 is the union of CV1 and CV2. void addArrowStarOverloads() { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[0].pointer_begin(), PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType C1Ty = (*Ptr); QualType C1; QualifierCollector Q1; C1 = QualType(Q1.strip(C1Ty->getPointeeType()), 0); if (!isa(C1)) continue; // heuristic to reduce number of builtin candidates in the set. // Add volatile/restrict version only if there are conversions to a // volatile/restrict type. if (!VisibleTypeConversionsQuals.hasVolatile() && Q1.hasVolatile()) continue; if (!VisibleTypeConversionsQuals.hasRestrict() && Q1.hasRestrict()) continue; for (BuiltinCandidateTypeSet::iterator MemPtr = CandidateTypes[1].member_pointer_begin(), MemPtrEnd = CandidateTypes[1].member_pointer_end(); MemPtr != MemPtrEnd; ++MemPtr) { const MemberPointerType *mptr = cast(*MemPtr); QualType C2 = QualType(mptr->getClass(), 0); C2 = C2.getUnqualifiedType(); if (C1 != C2 && !S.IsDerivedFrom(CandidateSet.getLocation(), C1, C2)) break; QualType ParamTypes[2] = { *Ptr, *MemPtr }; // build CV12 T& QualType T = mptr->getPointeeType(); if (!VisibleTypeConversionsQuals.hasVolatile() && T.isVolatileQualified()) continue; if (!VisibleTypeConversionsQuals.hasRestrict() && T.isRestrictQualified()) continue; T = Q1.apply(S.Context, T); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } // Note that we don't consider the first argument, since it has been // contextually converted to bool long ago. The candidates below are // therefore added as binary. // // C++ [over.built]p25: // For every type T, where T is a pointer, pointer-to-member, or scoped // enumeration type, there exist candidate operator functions of the form // // T operator?(bool, T, T); // void addConditionalOperatorOverloads() { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet AddedTypes; for (unsigned ArgIdx = 0; ArgIdx < 2; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[ArgIdx].pointer_begin(), PtrEnd = CandidateTypes[ArgIdx].pointer_end(); Ptr != PtrEnd; ++Ptr) { if (!AddedTypes.insert(S.Context.getCanonicalType(*Ptr)).second) continue; QualType ParamTypes[2] = { *Ptr, *Ptr }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(), MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end(); MemPtr != MemPtrEnd; ++MemPtr) { if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)).second) continue; QualType ParamTypes[2] = { *MemPtr, *MemPtr }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } if (S.getLangOpts().CPlusPlus11) { for (BuiltinCandidateTypeSet::iterator Enum = CandidateTypes[ArgIdx].enumeration_begin(), EnumEnd = CandidateTypes[ArgIdx].enumeration_end(); Enum != EnumEnd; ++Enum) { if (!(*Enum)->castAs()->getDecl()->isScoped()) continue; if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum)).second) continue; QualType ParamTypes[2] = { *Enum, *Enum }; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); } } } } }; } // end anonymous namespace /// AddBuiltinOperatorCandidates - Add the appropriate built-in /// operator overloads to the candidate set (C++ [over.built]), based /// on the operator @p Op and the arguments given. For example, if the /// operator is a binary '+', this routine might add "int /// operator+(int, int)" to cover integer addition. void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, SourceLocation OpLoc, ArrayRef Args, OverloadCandidateSet &CandidateSet) { // Find all of the types that the arguments can convert to, but only // if the operator we're looking at has built-in operator candidates // that make use of these types. Also record whether we encounter non-record // candidate types or either arithmetic or enumeral candidate types. Qualifiers VisibleTypeConversionsQuals; VisibleTypeConversionsQuals.addConst(); for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) VisibleTypeConversionsQuals += CollectVRQualifiers(Context, Args[ArgIdx]); bool HasNonRecordCandidateType = false; bool HasArithmeticOrEnumeralCandidateType = false; SmallVector CandidateTypes; for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { CandidateTypes.emplace_back(*this); CandidateTypes[ArgIdx].AddTypesConvertedFrom(Args[ArgIdx]->getType(), OpLoc, true, (Op == OO_Exclaim || Op == OO_AmpAmp || Op == OO_PipePipe), VisibleTypeConversionsQuals); HasNonRecordCandidateType = HasNonRecordCandidateType || CandidateTypes[ArgIdx].hasNonRecordTypes(); HasArithmeticOrEnumeralCandidateType = HasArithmeticOrEnumeralCandidateType || CandidateTypes[ArgIdx].hasArithmeticOrEnumeralTypes(); } // Exit early when no non-record types have been added to the candidate set // for any of the arguments to the operator. // // We can't exit early for !, ||, or &&, since there we have always have // 'bool' overloads. if (!HasNonRecordCandidateType && !(Op == OO_Exclaim || Op == OO_AmpAmp || Op == OO_PipePipe)) return; // Setup an object to manage the common state for building overloads. BuiltinOperatorOverloadBuilder OpBuilder(*this, Args, VisibleTypeConversionsQuals, HasArithmeticOrEnumeralCandidateType, CandidateTypes, CandidateSet); // Dispatch over the operation to add in only those overloads which apply. switch (Op) { case OO_None: case NUM_OVERLOADED_OPERATORS: llvm_unreachable("Expected an overloaded operator"); case OO_New: case OO_Delete: case OO_Array_New: case OO_Array_Delete: case OO_Call: llvm_unreachable( "Special operators don't use AddBuiltinOperatorCandidates"); case OO_Comma: case OO_Arrow: case OO_Coawait: // C++ [over.match.oper]p3: // -- For the operator ',', the unary operator '&', the // operator '->', or the operator 'co_await', the // built-in candidates set is empty. break; case OO_Plus: // '+' is either unary or binary if (Args.size() == 1) OpBuilder.addUnaryPlusPointerOverloads(); LLVM_FALLTHROUGH; case OO_Minus: // '-' is either unary or binary if (Args.size() == 1) { OpBuilder.addUnaryPlusOrMinusArithmeticOverloads(); } else { OpBuilder.addBinaryPlusOrMinusPointerOverloads(Op); OpBuilder.addGenericBinaryArithmeticOverloads(); } break; case OO_Star: // '*' is either unary or binary if (Args.size() == 1) OpBuilder.addUnaryStarPointerOverloads(); else OpBuilder.addGenericBinaryArithmeticOverloads(); break; case OO_Slash: OpBuilder.addGenericBinaryArithmeticOverloads(); break; case OO_PlusPlus: case OO_MinusMinus: OpBuilder.addPlusPlusMinusMinusArithmeticOverloads(Op); OpBuilder.addPlusPlusMinusMinusPointerOverloads(); break; case OO_EqualEqual: case OO_ExclaimEqual: OpBuilder.addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads(); LLVM_FALLTHROUGH; case OO_Less: case OO_Greater: case OO_LessEqual: case OO_GreaterEqual: OpBuilder.addGenericBinaryPointerOrEnumeralOverloads(); OpBuilder.addGenericBinaryArithmeticOverloads(); break; case OO_Spaceship: OpBuilder.addGenericBinaryPointerOrEnumeralOverloads(); OpBuilder.addThreeWayArithmeticOverloads(); break; case OO_Percent: case OO_Caret: case OO_Pipe: case OO_LessLess: case OO_GreaterGreater: OpBuilder.addBinaryBitwiseArithmeticOverloads(Op); break; case OO_Amp: // '&' is either unary or binary if (Args.size() == 1) // C++ [over.match.oper]p3: // -- For the operator ',', the unary operator '&', or the // operator '->', the built-in candidates set is empty. break; OpBuilder.addBinaryBitwiseArithmeticOverloads(Op); break; case OO_Tilde: OpBuilder.addUnaryTildePromotedIntegralOverloads(); break; case OO_Equal: OpBuilder.addAssignmentMemberPointerOrEnumeralOverloads(); LLVM_FALLTHROUGH; case OO_PlusEqual: case OO_MinusEqual: OpBuilder.addAssignmentPointerOverloads(Op == OO_Equal); LLVM_FALLTHROUGH; case OO_StarEqual: case OO_SlashEqual: OpBuilder.addAssignmentArithmeticOverloads(Op == OO_Equal); break; case OO_PercentEqual: case OO_LessLessEqual: case OO_GreaterGreaterEqual: case OO_AmpEqual: case OO_CaretEqual: case OO_PipeEqual: OpBuilder.addAssignmentIntegralOverloads(); break; case OO_Exclaim: OpBuilder.addExclaimOverload(); break; case OO_AmpAmp: case OO_PipePipe: OpBuilder.addAmpAmpOrPipePipeOverload(); break; case OO_Subscript: OpBuilder.addSubscriptOverloads(); break; case OO_ArrowStar: OpBuilder.addArrowStarOverloads(); break; case OO_Conditional: OpBuilder.addConditionalOperatorOverloads(); OpBuilder.addGenericBinaryArithmeticOverloads(); break; } } /// Add function candidates found via argument-dependent lookup /// to the set of overloading candidates. /// /// This routine performs argument-dependent name lookup based on the /// given function name (which may also be an operator name) and adds /// all of the overload candidates found by ADL to the overload /// candidate set (C++ [basic.lookup.argdep]). void Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, SourceLocation Loc, ArrayRef Args, TemplateArgumentListInfo *ExplicitTemplateArgs, OverloadCandidateSet& CandidateSet, bool PartialOverloading) { ADLResult Fns; // FIXME: This approach for uniquing ADL results (and removing // redundant candidates from the set) relies on pointer-equality, // which means we need to key off the canonical decl. However, // always going back to the canonical decl might not get us the // right set of default arguments. What default arguments are // we supposed to consider on ADL candidates, anyway? // FIXME: Pass in the explicit template arguments? ArgumentDependentLookup(Name, Loc, Args, Fns); // Erase all of the candidates we already knew about. for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(), CandEnd = CandidateSet.end(); Cand != CandEnd; ++Cand) if (Cand->Function) { Fns.erase(Cand->Function); if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate()) Fns.erase(FunTmpl); } // For each of the ADL candidates we found, add it to the overload // set. for (ADLResult::iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) { DeclAccessPair FoundDecl = DeclAccessPair::make(*I, AS_none); if (FunctionDecl *FD = dyn_cast(*I)) { if (ExplicitTemplateArgs) continue; AddOverloadCandidate( FD, FoundDecl, Args, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, /*AllowExplicit=*/true, /*AllowExplicitConversions=*/false, ADLCallKind::UsesADL); if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) { AddOverloadCandidate( FD, FoundDecl, {Args[1], Args[0]}, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, /*AllowExplicit=*/true, /*AllowExplicitConversions=*/false, ADLCallKind::UsesADL, None, OverloadCandidateParamOrder::Reversed); } } else { auto *FTD = cast(*I); AddTemplateOverloadCandidate( FTD, FoundDecl, ExplicitTemplateArgs, Args, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, /*AllowExplicit=*/true, ADLCallKind::UsesADL); if (CandidateSet.getRewriteInfo().shouldAddReversed( Context, FTD->getTemplatedDecl())) { AddTemplateOverloadCandidate( FTD, FoundDecl, ExplicitTemplateArgs, {Args[1], Args[0]}, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, /*AllowExplicit=*/true, ADLCallKind::UsesADL, OverloadCandidateParamOrder::Reversed); } } } } namespace { enum class Comparison { Equal, Better, Worse }; } /// Compares the enable_if attributes of two FunctionDecls, for the purposes of /// overload resolution. /// /// Cand1's set of enable_if attributes are said to be "better" than Cand2's iff /// Cand1's first N enable_if attributes have precisely the same conditions as /// Cand2's first N enable_if attributes (where N = the number of enable_if /// attributes on Cand2), and Cand1 has more than N enable_if attributes. /// /// Note that you can have a pair of candidates such that Cand1's enable_if /// attributes are worse than Cand2's, and Cand2's enable_if attributes are /// worse than Cand1's. static Comparison compareEnableIfAttrs(const Sema &S, const FunctionDecl *Cand1, const FunctionDecl *Cand2) { // Common case: One (or both) decls don't have enable_if attrs. bool Cand1Attr = Cand1->hasAttr(); bool Cand2Attr = Cand2->hasAttr(); if (!Cand1Attr || !Cand2Attr) { if (Cand1Attr == Cand2Attr) return Comparison::Equal; return Cand1Attr ? Comparison::Better : Comparison::Worse; } auto Cand1Attrs = Cand1->specific_attrs(); auto Cand2Attrs = Cand2->specific_attrs(); llvm::FoldingSetNodeID Cand1ID, Cand2ID; for (auto Pair : zip_longest(Cand1Attrs, Cand2Attrs)) { Optional Cand1A = std::get<0>(Pair); Optional Cand2A = std::get<1>(Pair); // It's impossible for Cand1 to be better than (or equal to) Cand2 if Cand1 // has fewer enable_if attributes than Cand2, and vice versa. if (!Cand1A) return Comparison::Worse; if (!Cand2A) return Comparison::Better; Cand1ID.clear(); Cand2ID.clear(); (*Cand1A)->getCond()->Profile(Cand1ID, S.getASTContext(), true); (*Cand2A)->getCond()->Profile(Cand2ID, S.getASTContext(), true); if (Cand1ID != Cand2ID) return Comparison::Worse; } return Comparison::Equal; } static bool isBetterMultiversionCandidate(const OverloadCandidate &Cand1, const OverloadCandidate &Cand2) { if (!Cand1.Function || !Cand1.Function->isMultiVersion() || !Cand2.Function || !Cand2.Function->isMultiVersion()) return false; // If Cand1 is invalid, it cannot be a better match, if Cand2 is invalid, this // is obviously better. if (Cand1.Function->isInvalidDecl()) return false; if (Cand2.Function->isInvalidDecl()) return true; // If this is a cpu_dispatch/cpu_specific multiversion situation, prefer // cpu_dispatch, else arbitrarily based on the identifiers. bool Cand1CPUDisp = Cand1.Function->hasAttr(); bool Cand2CPUDisp = Cand2.Function->hasAttr(); const auto *Cand1CPUSpec = Cand1.Function->getAttr(); const auto *Cand2CPUSpec = Cand2.Function->getAttr(); if (!Cand1CPUDisp && !Cand2CPUDisp && !Cand1CPUSpec && !Cand2CPUSpec) return false; if (Cand1CPUDisp && !Cand2CPUDisp) return true; if (Cand2CPUDisp && !Cand1CPUDisp) return false; if (Cand1CPUSpec && Cand2CPUSpec) { if (Cand1CPUSpec->cpus_size() != Cand2CPUSpec->cpus_size()) return Cand1CPUSpec->cpus_size() < Cand2CPUSpec->cpus_size(); std::pair FirstDiff = std::mismatch( Cand1CPUSpec->cpus_begin(), Cand1CPUSpec->cpus_end(), Cand2CPUSpec->cpus_begin(), [](const IdentifierInfo *LHS, const IdentifierInfo *RHS) { return LHS->getName() == RHS->getName(); }); assert(FirstDiff.first != Cand1CPUSpec->cpus_end() && "Two different cpu-specific versions should not have the same " "identifier list, otherwise they'd be the same decl!"); return (*FirstDiff.first)->getName() < (*FirstDiff.second)->getName(); } llvm_unreachable("No way to get here unless both had cpu_dispatch"); } /// isBetterOverloadCandidate - Determines whether the first overload /// candidate is a better candidate than the second (C++ 13.3.3p1). bool clang::isBetterOverloadCandidate( Sema &S, const OverloadCandidate &Cand1, const OverloadCandidate &Cand2, SourceLocation Loc, OverloadCandidateSet::CandidateSetKind Kind) { // Define viable functions to be better candidates than non-viable // functions. if (!Cand2.Viable) return Cand1.Viable; else if (!Cand1.Viable) return false; // C++ [over.match.best]p1: // // -- if F is a static member function, ICS1(F) is defined such // that ICS1(F) is neither better nor worse than ICS1(G) for // any function G, and, symmetrically, ICS1(G) is neither // better nor worse than ICS1(F). unsigned StartArg = 0; if (Cand1.IgnoreObjectArgument || Cand2.IgnoreObjectArgument) StartArg = 1; auto IsIllFormedConversion = [&](const ImplicitConversionSequence &ICS) { // We don't allow incompatible pointer conversions in C++. if (!S.getLangOpts().CPlusPlus) return ICS.isStandard() && ICS.Standard.Second == ICK_Incompatible_Pointer_Conversion; // The only ill-formed conversion we allow in C++ is the string literal to // char* conversion, which is only considered ill-formed after C++11. return S.getLangOpts().CPlusPlus11 && !S.getLangOpts().WritableStrings && hasDeprecatedStringLiteralToCharPtrConversion(ICS); }; // Define functions that don't require ill-formed conversions for a given // argument to be better candidates than functions that do. unsigned NumArgs = Cand1.Conversions.size(); assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch"); bool HasBetterConversion = false; for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) { bool Cand1Bad = IsIllFormedConversion(Cand1.Conversions[ArgIdx]); bool Cand2Bad = IsIllFormedConversion(Cand2.Conversions[ArgIdx]); if (Cand1Bad != Cand2Bad) { if (Cand1Bad) return false; HasBetterConversion = true; } } if (HasBetterConversion) return true; // C++ [over.match.best]p1: // A viable function F1 is defined to be a better function than another // viable function F2 if for all arguments i, ICSi(F1) is not a worse // conversion sequence than ICSi(F2), and then... bool HasWorseConversion = false; for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) { switch (CompareImplicitConversionSequences(S, Loc, Cand1.Conversions[ArgIdx], Cand2.Conversions[ArgIdx])) { case ImplicitConversionSequence::Better: // Cand1 has a better conversion sequence. HasBetterConversion = true; break; case ImplicitConversionSequence::Worse: if (Cand1.Function && Cand1.Function == Cand2.Function && (Cand2.RewriteKind & CRK_Reversed) != 0) { // Work around large-scale breakage caused by considering reversed // forms of operator== in C++20: // // When comparing a function against its reversed form, if we have a // better conversion for one argument and a worse conversion for the // other, we prefer the non-reversed form. // // This prevents a conversion function from being considered ambiguous // with its own reversed form in various where it's only incidentally // heterogeneous. // // We diagnose this as an extension from CreateOverloadedBinOp. HasWorseConversion = true; break; } // Cand1 can't be better than Cand2. return false; case ImplicitConversionSequence::Indistinguishable: // Do nothing. break; } } // -- for some argument j, ICSj(F1) is a better conversion sequence than // ICSj(F2), or, if not that, if (HasBetterConversion) return true; if (HasWorseConversion) return false; // -- the context is an initialization by user-defined conversion // (see 8.5, 13.3.1.5) and the standard conversion sequence // from the return type of F1 to the destination type (i.e., // the type of the entity being initialized) is a better // conversion sequence than the standard conversion sequence // from the return type of F2 to the destination type. if (Kind == OverloadCandidateSet::CSK_InitByUserDefinedConversion && Cand1.Function && Cand2.Function && isa(Cand1.Function) && isa(Cand2.Function)) { // First check whether we prefer one of the conversion functions over the // other. This only distinguishes the results in non-standard, extension // cases such as the conversion from a lambda closure type to a function // pointer or block. ImplicitConversionSequence::CompareKind Result = compareConversionFunctions(S, Cand1.Function, Cand2.Function); if (Result == ImplicitConversionSequence::Indistinguishable) Result = CompareStandardConversionSequences(S, Loc, Cand1.FinalConversion, Cand2.FinalConversion); if (Result != ImplicitConversionSequence::Indistinguishable) return Result == ImplicitConversionSequence::Better; // FIXME: Compare kind of reference binding if conversion functions // convert to a reference type used in direct reference binding, per // C++14 [over.match.best]p1 section 2 bullet 3. } // FIXME: Work around a defect in the C++17 guaranteed copy elision wording, // as combined with the resolution to CWG issue 243. // // When the context is initialization by constructor ([over.match.ctor] or // either phase of [over.match.list]), a constructor is preferred over // a conversion function. if (Kind == OverloadCandidateSet::CSK_InitByConstructor && NumArgs == 1 && Cand1.Function && Cand2.Function && isa(Cand1.Function) != isa(Cand2.Function)) return isa(Cand1.Function); // -- F1 is a non-template function and F2 is a function template // specialization, or, if not that, bool Cand1IsSpecialization = Cand1.Function && Cand1.Function->getPrimaryTemplate(); bool Cand2IsSpecialization = Cand2.Function && Cand2.Function->getPrimaryTemplate(); if (Cand1IsSpecialization != Cand2IsSpecialization) return Cand2IsSpecialization; // -- F1 and F2 are function template specializations, and the function // template for F1 is more specialized than the template for F2 // according to the partial ordering rules described in 14.5.5.2, or, // if not that, if (Cand1IsSpecialization && Cand2IsSpecialization) { if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(), Cand2.Function->getPrimaryTemplate(), Loc, isa(Cand1.Function)? TPOC_Conversion : TPOC_Call, Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments)) return BetterTemplate == Cand1.Function->getPrimaryTemplate(); } // -— F1 and F2 are non-template functions with the same // parameter-type-lists, and F1 is more constrained than F2 [...], if (Cand1.Function && Cand2.Function && !Cand1IsSpecialization && !Cand2IsSpecialization && Cand1.Function->hasPrototype() && Cand2.Function->hasPrototype()) { auto *PT1 = cast(Cand1.Function->getFunctionType()); auto *PT2 = cast(Cand2.Function->getFunctionType()); if (PT1->getNumParams() == PT2->getNumParams() && PT1->isVariadic() == PT2->isVariadic() && S.FunctionParamTypesAreEqual(PT1, PT2)) { Expr *RC1 = Cand1.Function->getTrailingRequiresClause(); Expr *RC2 = Cand2.Function->getTrailingRequiresClause(); if (RC1 && RC2) { bool AtLeastAsConstrained1, AtLeastAsConstrained2; if (S.IsAtLeastAsConstrained(Cand1.Function, {RC1}, Cand2.Function, {RC2}, AtLeastAsConstrained1) || S.IsAtLeastAsConstrained(Cand2.Function, {RC2}, Cand1.Function, {RC1}, AtLeastAsConstrained2)) return false; if (AtLeastAsConstrained1 != AtLeastAsConstrained2) return AtLeastAsConstrained1; } else if (RC1 || RC2) { return RC1 != nullptr; } } } // -- F1 is a constructor for a class D, F2 is a constructor for a base // class B of D, and for all arguments the corresponding parameters of // F1 and F2 have the same type. // FIXME: Implement the "all parameters have the same type" check. bool Cand1IsInherited = dyn_cast_or_null(Cand1.FoundDecl.getDecl()); bool Cand2IsInherited = dyn_cast_or_null(Cand2.FoundDecl.getDecl()); if (Cand1IsInherited != Cand2IsInherited) return Cand2IsInherited; else if (Cand1IsInherited) { assert(Cand2IsInherited); auto *Cand1Class = cast(Cand1.Function->getDeclContext()); auto *Cand2Class = cast(Cand2.Function->getDeclContext()); if (Cand1Class->isDerivedFrom(Cand2Class)) return true; if (Cand2Class->isDerivedFrom(Cand1Class)) return false; // Inherited from sibling base classes: still ambiguous. } // -- F2 is a rewritten candidate (12.4.1.2) and F1 is not // -- F1 and F2 are rewritten candidates, and F2 is a synthesized candidate // with reversed order of parameters and F1 is not // // We rank reversed + different operator as worse than just reversed, but // that comparison can never happen, because we only consider reversing for // the maximally-rewritten operator (== or <=>). if (Cand1.RewriteKind != Cand2.RewriteKind) return Cand1.RewriteKind < Cand2.RewriteKind; // Check C++17 tie-breakers for deduction guides. { auto *Guide1 = dyn_cast_or_null(Cand1.Function); auto *Guide2 = dyn_cast_or_null(Cand2.Function); if (Guide1 && Guide2) { // -- F1 is generated from a deduction-guide and F2 is not if (Guide1->isImplicit() != Guide2->isImplicit()) return Guide2->isImplicit(); // -- F1 is the copy deduction candidate(16.3.1.8) and F2 is not if (Guide1->isCopyDeductionCandidate()) return true; } } // Check for enable_if value-based overload resolution. if (Cand1.Function && Cand2.Function) { Comparison Cmp = compareEnableIfAttrs(S, Cand1.Function, Cand2.Function); if (Cmp != Comparison::Equal) return Cmp == Comparison::Better; } if (S.getLangOpts().CUDA && Cand1.Function && Cand2.Function) { FunctionDecl *Caller = dyn_cast(S.CurContext); return S.IdentifyCUDAPreference(Caller, Cand1.Function) > S.IdentifyCUDAPreference(Caller, Cand2.Function); } bool HasPS1 = Cand1.Function != nullptr && functionHasPassObjectSizeParams(Cand1.Function); bool HasPS2 = Cand2.Function != nullptr && functionHasPassObjectSizeParams(Cand2.Function); if (HasPS1 != HasPS2 && HasPS1) return true; return isBetterMultiversionCandidate(Cand1, Cand2); } /// Determine whether two declarations are "equivalent" for the purposes of /// name lookup and overload resolution. This applies when the same internal/no /// linkage entity is defined by two modules (probably by textually including /// the same header). In such a case, we don't consider the declarations to /// declare the same entity, but we also don't want lookups with both /// declarations visible to be ambiguous in some cases (this happens when using /// a modularized libstdc++). bool Sema::isEquivalentInternalLinkageDeclaration(const NamedDecl *A, const NamedDecl *B) { auto *VA = dyn_cast_or_null(A); auto *VB = dyn_cast_or_null(B); if (!VA || !VB) return false; // The declarations must be declaring the same name as an internal linkage // entity in different modules. if (!VA->getDeclContext()->getRedeclContext()->Equals( VB->getDeclContext()->getRedeclContext()) || getOwningModule(VA) == getOwningModule(VB) || VA->isExternallyVisible() || VB->isExternallyVisible()) return false; // Check that the declarations appear to be equivalent. // // FIXME: Checking the type isn't really enough to resolve the ambiguity. // For constants and functions, we should check the initializer or body is // the same. For non-constant variables, we shouldn't allow it at all. if (Context.hasSameType(VA->getType(), VB->getType())) return true; // Enum constants within unnamed enumerations will have different types, but // may still be similar enough to be interchangeable for our purposes. if (auto *EA = dyn_cast(VA)) { if (auto *EB = dyn_cast(VB)) { // Only handle anonymous enums. If the enumerations were named and // equivalent, they would have been merged to the same type. auto *EnumA = cast(EA->getDeclContext()); auto *EnumB = cast(EB->getDeclContext()); if (EnumA->hasNameForLinkage() || EnumB->hasNameForLinkage() || !Context.hasSameType(EnumA->getIntegerType(), EnumB->getIntegerType())) return false; // Allow this only if the value is the same for both enumerators. return llvm::APSInt::isSameValue(EA->getInitVal(), EB->getInitVal()); } } // Nothing else is sufficiently similar. return false; } void Sema::diagnoseEquivalentInternalLinkageDeclarations( SourceLocation Loc, const NamedDecl *D, ArrayRef Equiv) { Diag(Loc, diag::ext_equivalent_internal_linkage_decl_in_modules) << D; Module *M = getOwningModule(D); Diag(D->getLocation(), diag::note_equivalent_internal_linkage_decl) << !M << (M ? M->getFullModuleName() : ""); for (auto *E : Equiv) { Module *M = getOwningModule(E); Diag(E->getLocation(), diag::note_equivalent_internal_linkage_decl) << !M << (M ? M->getFullModuleName() : ""); } } /// Computes the best viable function (C++ 13.3.3) /// within an overload candidate set. /// /// \param Loc The location of the function name (or operator symbol) for /// which overload resolution occurs. /// /// \param Best If overload resolution was successful or found a deleted /// function, \p Best points to the candidate function found. /// /// \returns The result of overload resolution. OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, iterator &Best) { llvm::SmallVector Candidates; std::transform(begin(), end(), std::back_inserter(Candidates), [](OverloadCandidate &Cand) { return &Cand; }); // [CUDA] HD->H or HD->D calls are technically not allowed by CUDA but // are accepted by both clang and NVCC. However, during a particular // compilation mode only one call variant is viable. We need to // exclude non-viable overload candidates from consideration based // only on their host/device attributes. Specifically, if one // candidate call is WrongSide and the other is SameSide, we ignore // the WrongSide candidate. if (S.getLangOpts().CUDA) { const FunctionDecl *Caller = dyn_cast(S.CurContext); bool ContainsSameSideCandidate = llvm::any_of(Candidates, [&](OverloadCandidate *Cand) { // Check viable function only. return Cand->Viable && Cand->Function && S.IdentifyCUDAPreference(Caller, Cand->Function) == Sema::CFP_SameSide; }); if (ContainsSameSideCandidate) { auto IsWrongSideCandidate = [&](OverloadCandidate *Cand) { // Check viable function only to avoid unnecessary data copying/moving. return Cand->Viable && Cand->Function && S.IdentifyCUDAPreference(Caller, Cand->Function) == Sema::CFP_WrongSide; }; llvm::erase_if(Candidates, IsWrongSideCandidate); } } // Find the best viable function. Best = end(); for (auto *Cand : Candidates) { Cand->Best = false; if (Cand->Viable) if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc, Kind)) Best = Cand; } // If we didn't find any viable functions, abort. if (Best == end()) return OR_No_Viable_Function; llvm::SmallVector EquivalentCands; llvm::SmallVector PendingBest; PendingBest.push_back(&*Best); Best->Best = true; // Make sure that this function is better than every other viable // function. If not, we have an ambiguity. while (!PendingBest.empty()) { auto *Curr = PendingBest.pop_back_val(); for (auto *Cand : Candidates) { if (Cand->Viable && !Cand->Best && !isBetterOverloadCandidate(S, *Curr, *Cand, Loc, Kind)) { PendingBest.push_back(Cand); Cand->Best = true; if (S.isEquivalentInternalLinkageDeclaration(Cand->Function, Curr->Function)) EquivalentCands.push_back(Cand->Function); else Best = end(); } } } // If we found more than one best candidate, this is ambiguous. if (Best == end()) return OR_Ambiguous; // Best is the best viable function. if (Best->Function && Best->Function->isDeleted()) return OR_Deleted; if (!EquivalentCands.empty()) S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function, EquivalentCands); return OR_Success; } namespace { enum OverloadCandidateKind { oc_function, oc_method, oc_reversed_binary_operator, oc_constructor, oc_implicit_default_constructor, oc_implicit_copy_constructor, oc_implicit_move_constructor, oc_implicit_copy_assignment, oc_implicit_move_assignment, oc_implicit_equality_comparison, oc_inherited_constructor }; enum OverloadCandidateSelect { ocs_non_template, ocs_template, ocs_described_template, }; static std::pair ClassifyOverloadCandidate(Sema &S, NamedDecl *Found, FunctionDecl *Fn, OverloadCandidateRewriteKind CRK, std::string &Description) { bool isTemplate = Fn->isTemplateDecl() || Found->isTemplateDecl(); if (FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate()) { isTemplate = true; Description = S.getTemplateArgumentBindingsText( FunTmpl->getTemplateParameters(), *Fn->getTemplateSpecializationArgs()); } OverloadCandidateSelect Select = [&]() { if (!Description.empty()) return ocs_described_template; return isTemplate ? ocs_template : ocs_non_template; }(); OverloadCandidateKind Kind = [&]() { if (Fn->isImplicit() && Fn->getOverloadedOperator() == OO_EqualEqual) return oc_implicit_equality_comparison; if (CRK & CRK_Reversed) return oc_reversed_binary_operator; if (CXXConstructorDecl *Ctor = dyn_cast(Fn)) { if (!Ctor->isImplicit()) { if (isa(Found)) return oc_inherited_constructor; else return oc_constructor; } if (Ctor->isDefaultConstructor()) return oc_implicit_default_constructor; if (Ctor->isMoveConstructor()) return oc_implicit_move_constructor; assert(Ctor->isCopyConstructor() && "unexpected sort of implicit constructor"); return oc_implicit_copy_constructor; } if (CXXMethodDecl *Meth = dyn_cast(Fn)) { // This actually gets spelled 'candidate function' for now, but // it doesn't hurt to split it out. if (!Meth->isImplicit()) return oc_method; if (Meth->isMoveAssignmentOperator()) return oc_implicit_move_assignment; if (Meth->isCopyAssignmentOperator()) return oc_implicit_copy_assignment; assert(isa(Meth) && "expected conversion"); return oc_method; } return oc_function; }(); return std::make_pair(Kind, Select); } void MaybeEmitInheritedConstructorNote(Sema &S, Decl *FoundDecl) { // FIXME: It'd be nice to only emit a note once per using-decl per overload // set. if (auto *Shadow = dyn_cast(FoundDecl)) S.Diag(FoundDecl->getLocation(), diag::note_ovl_candidate_inherited_constructor) << Shadow->getNominatedBaseClass(); } } // end anonymous namespace static bool isFunctionAlwaysEnabled(const ASTContext &Ctx, const FunctionDecl *FD) { for (auto *EnableIf : FD->specific_attrs()) { bool AlwaysTrue; if (EnableIf->getCond()->isValueDependent() || !EnableIf->getCond()->EvaluateAsBooleanCondition(AlwaysTrue, Ctx)) return false; if (!AlwaysTrue) return false; } return true; } /// Returns true if we can take the address of the function. /// /// \param Complain - If true, we'll emit a diagnostic /// \param InOverloadResolution - For the purposes of emitting a diagnostic, are /// we in overload resolution? /// \param Loc - The location of the statement we're complaining about. Ignored /// if we're not complaining, or if we're in overload resolution. static bool checkAddressOfFunctionIsAvailable(Sema &S, const FunctionDecl *FD, bool Complain, bool InOverloadResolution, SourceLocation Loc) { if (!isFunctionAlwaysEnabled(S.Context, FD)) { if (Complain) { if (InOverloadResolution) S.Diag(FD->getBeginLoc(), diag::note_addrof_ovl_candidate_disabled_by_enable_if_attr); else S.Diag(Loc, diag::err_addrof_function_disabled_by_enable_if_attr) << FD; } return false; } if (FD->getTrailingRequiresClause()) { ConstraintSatisfaction Satisfaction; if (S.CheckFunctionConstraints(FD, Satisfaction, Loc)) return false; if (!Satisfaction.IsSatisfied) { if (Complain) { if (InOverloadResolution) S.Diag(FD->getBeginLoc(), diag::note_ovl_candidate_unsatisfied_constraints); else S.Diag(Loc, diag::err_addrof_function_constraints_not_satisfied) << FD; S.DiagnoseUnsatisfiedConstraint(Satisfaction); } return false; } } auto I = llvm::find_if(FD->parameters(), [](const ParmVarDecl *P) { return P->hasAttr(); }); if (I == FD->param_end()) return true; if (Complain) { // Add one to ParamNo because it's user-facing unsigned ParamNo = std::distance(FD->param_begin(), I) + 1; if (InOverloadResolution) S.Diag(FD->getLocation(), diag::note_ovl_candidate_has_pass_object_size_params) << ParamNo; else S.Diag(Loc, diag::err_address_of_function_with_pass_object_size_params) << FD << ParamNo; } return false; } static bool checkAddressOfCandidateIsAvailable(Sema &S, const FunctionDecl *FD) { return checkAddressOfFunctionIsAvailable(S, FD, /*Complain=*/true, /*InOverloadResolution=*/true, /*Loc=*/SourceLocation()); } bool Sema::checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain, SourceLocation Loc) { return ::checkAddressOfFunctionIsAvailable(*this, Function, Complain, /*InOverloadResolution=*/false, Loc); } // Notes the location of an overload candidate. void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn, OverloadCandidateRewriteKind RewriteKind, QualType DestType, bool TakingAddress) { if (TakingAddress && !checkAddressOfCandidateIsAvailable(*this, Fn)) return; if (Fn->isMultiVersion() && Fn->hasAttr() && !Fn->getAttr()->isDefaultVersion()) return; std::string FnDesc; std::pair KSPair = ClassifyOverloadCandidate(*this, Found, Fn, RewriteKind, FnDesc); PartialDiagnostic PD = PDiag(diag::note_ovl_candidate) << (unsigned)KSPair.first << (unsigned)KSPair.second << Fn << FnDesc; HandleFunctionTypeMismatch(PD, Fn->getType(), DestType); Diag(Fn->getLocation(), PD); MaybeEmitInheritedConstructorNote(*this, Found); } static void MaybeDiagnoseAmbiguousConstraints(Sema &S, ArrayRef Cands) { // Perhaps the ambiguity was caused by two atomic constraints that are // 'identical' but not equivalent: // // void foo() requires (sizeof(T) > 4) { } // #1 // void foo() requires (sizeof(T) > 4) && T::value { } // #2 // // The 'sizeof(T) > 4' constraints are seemingly equivalent and should cause // #2 to subsume #1, but these constraint are not considered equivalent // according to the subsumption rules because they are not the same // source-level construct. This behavior is quite confusing and we should try // to help the user figure out what happened. SmallVector FirstAC, SecondAC; FunctionDecl *FirstCand = nullptr, *SecondCand = nullptr; for (auto I = Cands.begin(), E = Cands.end(); I != E; ++I) { if (!I->Function) continue; SmallVector AC; if (auto *Template = I->Function->getPrimaryTemplate()) Template->getAssociatedConstraints(AC); else I->Function->getAssociatedConstraints(AC); if (AC.empty()) continue; if (FirstCand == nullptr) { FirstCand = I->Function; FirstAC = AC; } else if (SecondCand == nullptr) { SecondCand = I->Function; SecondAC = AC; } else { // We have more than one pair of constrained functions - this check is // expensive and we'd rather not try to diagnose it. return; } } if (!SecondCand) return; // The diagnostic can only happen if there are associated constraints on // both sides (there needs to be some identical atomic constraint). if (S.MaybeEmitAmbiguousAtomicConstraintsDiagnostic(FirstCand, FirstAC, SecondCand, SecondAC)) // Just show the user one diagnostic, they'll probably figure it out // from here. return; } // Notes the location of all overload candidates designated through // OverloadedExpr void Sema::NoteAllOverloadCandidates(Expr *OverloadedExpr, QualType DestType, bool TakingAddress) { assert(OverloadedExpr->getType() == Context.OverloadTy); OverloadExpr::FindResult Ovl = OverloadExpr::find(OverloadedExpr); OverloadExpr *OvlExpr = Ovl.Expression; for (UnresolvedSetIterator I = OvlExpr->decls_begin(), IEnd = OvlExpr->decls_end(); I != IEnd; ++I) { if (FunctionTemplateDecl *FunTmpl = dyn_cast((*I)->getUnderlyingDecl()) ) { NoteOverloadCandidate(*I, FunTmpl->getTemplatedDecl(), CRK_None, DestType, TakingAddress); } else if (FunctionDecl *Fun = dyn_cast((*I)->getUnderlyingDecl()) ) { NoteOverloadCandidate(*I, Fun, CRK_None, DestType, TakingAddress); } } } /// Diagnoses an ambiguous conversion. The partial diagnostic is the /// "lead" diagnostic; it will be given two arguments, the source and /// target types of the conversion. void ImplicitConversionSequence::DiagnoseAmbiguousConversion( Sema &S, SourceLocation CaretLoc, const PartialDiagnostic &PDiag) const { S.Diag(CaretLoc, PDiag) << Ambiguous.getFromType() << Ambiguous.getToType(); // FIXME: The note limiting machinery is borrowed from // OverloadCandidateSet::NoteCandidates; there's an opportunity for // refactoring here. const OverloadsShown ShowOverloads = S.Diags.getShowOverloads(); unsigned CandsShown = 0; AmbiguousConversionSequence::const_iterator I, E; for (I = Ambiguous.begin(), E = Ambiguous.end(); I != E; ++I) { if (CandsShown >= 4 && ShowOverloads == Ovl_Best) break; ++CandsShown; S.NoteOverloadCandidate(I->first, I->second); } if (I != E) S.Diag(SourceLocation(), diag::note_ovl_too_many_candidates) << int(E - I); } static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I, bool TakingCandidateAddress) { const ImplicitConversionSequence &Conv = Cand->Conversions[I]; assert(Conv.isBad()); assert(Cand->Function && "for now, candidate must be a function"); FunctionDecl *Fn = Cand->Function; // There's a conversion slot for the object argument if this is a // non-constructor method. Note that 'I' corresponds the // conversion-slot index. bool isObjectArgument = false; if (isa(Fn) && !isa(Fn)) { if (I == 0) isObjectArgument = true; else I--; } std::string FnDesc; std::pair FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, Cand->getRewriteKind(), FnDesc); Expr *FromExpr = Conv.Bad.FromExpr; QualType FromTy = Conv.Bad.getFromType(); QualType ToTy = Conv.Bad.getToType(); if (FromTy == S.Context.OverloadTy) { assert(FromExpr && "overload set argument came from implicit argument?"); Expr *E = FromExpr->IgnoreParens(); if (isa(E)) E = cast(E)->getSubExpr()->IgnoreParens(); DeclarationName Name = cast(E)->getName(); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_overload) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << ToTy << Name << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // Do some hand-waving analysis to see if the non-viability is due // to a qualifier mismatch. CanQualType CFromTy = S.Context.getCanonicalType(FromTy); CanQualType CToTy = S.Context.getCanonicalType(ToTy); if (CanQual RT = CToTy->getAs()) CToTy = RT->getPointeeType(); else { // TODO: detect and diagnose the full richness of const mismatches. if (CanQual FromPT = CFromTy->getAs()) if (CanQual ToPT = CToTy->getAs()) { CFromTy = FromPT->getPointeeType(); CToTy = ToPT->getPointeeType(); } } if (CToTy.getUnqualifiedType() == CFromTy.getUnqualifiedType() && !CToTy.isAtLeastAsQualifiedAs(CFromTy)) { Qualifiers FromQs = CFromTy.getQualifiers(); Qualifiers ToQs = CToTy.getQualifiers(); if (FromQs.getAddressSpace() != ToQs.getAddressSpace()) { if (isObjectArgument) S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_addrspace_this) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromQs.getAddressSpace() << ToQs.getAddressSpace(); else S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_addrspace) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromQs.getAddressSpace() << ToQs.getAddressSpace() << ToTy->isReferenceType() << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (FromQs.getObjCLifetime() != ToQs.getObjCLifetime()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_ownership) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << FromQs.getObjCLifetime() << ToQs.getObjCLifetime() << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (FromQs.getObjCGCAttr() != ToQs.getObjCGCAttr()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_gc) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << FromQs.getObjCGCAttr() << ToQs.getObjCGCAttr() << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (FromQs.hasUnaligned() != ToQs.hasUnaligned()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_unaligned) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << FromQs.hasUnaligned() << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } unsigned CVR = FromQs.getCVRQualifiers() & ~ToQs.getCVRQualifiers(); assert(CVR && "unexpected qualifiers mismatch"); if (isObjectArgument) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_cvr_this) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << (CVR - 1); } else { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_cvr) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << (CVR - 1) << I + 1; } MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // Special diagnostic for failure to convert an initializer list, since // telling the user that it has type void is not useful. if (FromExpr && isa(FromExpr)) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_list_argument) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << ToTy << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // Diagnose references or pointers to incomplete types differently, // since it's far from impossible that the incompleteness triggered // the failure. QualType TempFromTy = FromTy.getNonReferenceType(); if (const PointerType *PTy = TempFromTy->getAs()) TempFromTy = PTy->getPointeeType(); if (TempFromTy->isIncompleteType()) { // Emit the generic diagnostic and, optionally, add the hints to it. S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << ToTy << (unsigned)isObjectArgument << I + 1 << (unsigned)(Cand->Fix.Kind); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // Diagnose base -> derived pointer conversions. unsigned BaseToDerivedConversion = 0; if (const PointerType *FromPtrTy = FromTy->getAs()) { if (const PointerType *ToPtrTy = ToTy->getAs()) { if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs( FromPtrTy->getPointeeType()) && !FromPtrTy->getPointeeType()->isIncompleteType() && !ToPtrTy->getPointeeType()->isIncompleteType() && S.IsDerivedFrom(SourceLocation(), ToPtrTy->getPointeeType(), FromPtrTy->getPointeeType())) BaseToDerivedConversion = 1; } } else if (const ObjCObjectPointerType *FromPtrTy = FromTy->getAs()) { if (const ObjCObjectPointerType *ToPtrTy = ToTy->getAs()) if (const ObjCInterfaceDecl *FromIface = FromPtrTy->getInterfaceDecl()) if (const ObjCInterfaceDecl *ToIface = ToPtrTy->getInterfaceDecl()) if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs( FromPtrTy->getPointeeType()) && FromIface->isSuperClassOf(ToIface)) BaseToDerivedConversion = 2; } else if (const ReferenceType *ToRefTy = ToTy->getAs()) { if (ToRefTy->getPointeeType().isAtLeastAsQualifiedAs(FromTy) && !FromTy->isIncompleteType() && !ToRefTy->getPointeeType()->isIncompleteType() && S.IsDerivedFrom(SourceLocation(), ToRefTy->getPointeeType(), FromTy)) { BaseToDerivedConversion = 3; } else if (ToTy->isLValueReferenceType() && !FromExpr->isLValue() && ToTy.getNonReferenceType().getCanonicalType() == FromTy.getNonReferenceType().getCanonicalType()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_lvalue) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (unsigned)isObjectArgument << I + 1 << (FromExpr ? FromExpr->getSourceRange() : SourceRange()); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } } if (BaseToDerivedConversion) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_base_to_derived_conv) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << (BaseToDerivedConversion - 1) << FromTy << ToTy << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } if (isa(CFromTy) && isa(CToTy)) { Qualifiers FromQs = CFromTy.getQualifiers(); Qualifiers ToQs = CToTy.getQualifiers(); if (FromQs.getObjCLifetime() != ToQs.getObjCLifetime()) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_arc_conv) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << ToTy << (unsigned)isObjectArgument << I + 1; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } } if (TakingCandidateAddress && !checkAddressOfCandidateIsAvailable(S, Cand->Function)) return; // Emit the generic diagnostic and, optionally, add the hints to it. PartialDiagnostic FDiag = S.PDiag(diag::note_ovl_candidate_bad_conv); FDiag << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << ToTy << (unsigned)isObjectArgument << I + 1 << (unsigned)(Cand->Fix.Kind); // If we can fix the conversion, suggest the FixIts. for (std::vector::iterator HI = Cand->Fix.Hints.begin(), HE = Cand->Fix.Hints.end(); HI != HE; ++HI) FDiag << *HI; S.Diag(Fn->getLocation(), FDiag); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); } /// Additional arity mismatch diagnosis specific to a function overload /// candidates. This is not covered by the more general DiagnoseArityMismatch() /// over a candidate in any candidate set. static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand, unsigned NumArgs) { FunctionDecl *Fn = Cand->Function; unsigned MinParams = Fn->getMinRequiredArguments(); // With invalid overloaded operators, it's possible that we think we // have an arity mismatch when in fact it looks like we have the // right number of arguments, because only overloaded operators have // the weird behavior of overloading member and non-member functions. // Just don't report anything. if (Fn->isInvalidDecl() && Fn->getDeclName().getNameKind() == DeclarationName::CXXOperatorName) return true; if (NumArgs < MinParams) { assert((Cand->FailureKind == ovl_fail_too_few_arguments) || (Cand->FailureKind == ovl_fail_bad_deduction && Cand->DeductionFailure.Result == Sema::TDK_TooFewArguments)); } else { assert((Cand->FailureKind == ovl_fail_too_many_arguments) || (Cand->FailureKind == ovl_fail_bad_deduction && Cand->DeductionFailure.Result == Sema::TDK_TooManyArguments)); } return false; } /// General arity mismatch diagnosis over a candidate in a candidate set. static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D, unsigned NumFormalArgs) { assert(isa(D) && "The templated declaration should at least be a function" " when diagnosing bad template argument deduction due to too many" " or too few arguments"); FunctionDecl *Fn = cast(D); // TODO: treat calls to a missing default constructor as a special case const auto *FnTy = Fn->getType()->castAs(); unsigned MinParams = Fn->getMinRequiredArguments(); // at least / at most / exactly unsigned mode, modeCount; if (NumFormalArgs < MinParams) { if (MinParams != FnTy->getNumParams() || FnTy->isVariadic() || FnTy->isTemplateVariadic()) mode = 0; // "at least" else mode = 2; // "exactly" modeCount = MinParams; } else { if (MinParams != FnTy->getNumParams()) mode = 1; // "at most" else mode = 2; // "exactly" modeCount = FnTy->getNumParams(); } std::string Description; std::pair FnKindPair = ClassifyOverloadCandidate(S, Found, Fn, CRK_None, Description); if (modeCount == 1 && Fn->getParamDecl(0)->getDeclName()) S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity_one) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << Description << mode << Fn->getParamDecl(0) << NumFormalArgs; else S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << Description << mode << modeCount << NumFormalArgs; MaybeEmitInheritedConstructorNote(S, Found); } /// Arity mismatch diagnosis specific to a function overload candidate. static void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand, unsigned NumFormalArgs) { if (!CheckArityMismatch(S, Cand, NumFormalArgs)) DiagnoseArityMismatch(S, Cand->FoundDecl, Cand->Function, NumFormalArgs); } static TemplateDecl *getDescribedTemplate(Decl *Templated) { if (TemplateDecl *TD = Templated->getDescribedTemplate()) return TD; llvm_unreachable("Unsupported: Getting the described template declaration" " for bad deduction diagnosis"); } /// Diagnose a failed template-argument deduction. static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, DeductionFailureInfo &DeductionFailure, unsigned NumArgs, bool TakingCandidateAddress) { TemplateParameter Param = DeductionFailure.getTemplateParameter(); NamedDecl *ParamD; (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()) || (ParamD = Param.dyn_cast()); switch (DeductionFailure.Result) { case Sema::TDK_Success: llvm_unreachable("TDK_success while diagnosing bad deduction"); case Sema::TDK_Incomplete: { assert(ParamD && "no parameter found for incomplete deduction result"); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_incomplete_deduction) << ParamD->getDeclName(); MaybeEmitInheritedConstructorNote(S, Found); return; } case Sema::TDK_IncompletePack: { assert(ParamD && "no parameter found for incomplete deduction result"); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_incomplete_deduction_pack) << ParamD->getDeclName() << (DeductionFailure.getFirstArg()->pack_size() + 1) << *DeductionFailure.getFirstArg(); MaybeEmitInheritedConstructorNote(S, Found); return; } case Sema::TDK_Underqualified: { assert(ParamD && "no parameter found for bad qualifiers deduction result"); TemplateTypeParmDecl *TParam = cast(ParamD); QualType Param = DeductionFailure.getFirstArg()->getAsType(); // Param will have been canonicalized, but it should just be a // qualified version of ParamD, so move the qualifiers to that. QualifierCollector Qs; Qs.strip(Param); QualType NonCanonParam = Qs.apply(S.Context, TParam->getTypeForDecl()); assert(S.Context.hasSameType(Param, NonCanonParam)); // Arg has also been canonicalized, but there's nothing we can do // about that. It also doesn't matter as much, because it won't // have any template parameters in it (because deduction isn't // done on dependent types). QualType Arg = DeductionFailure.getSecondArg()->getAsType(); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_underqualified) << ParamD->getDeclName() << Arg << NonCanonParam; MaybeEmitInheritedConstructorNote(S, Found); return; } case Sema::TDK_Inconsistent: { assert(ParamD && "no parameter found for inconsistent deduction result"); int which = 0; if (isa(ParamD)) which = 0; else if (isa(ParamD)) { // Deduction might have failed because we deduced arguments of two // different types for a non-type template parameter. // FIXME: Use a different TDK value for this. QualType T1 = DeductionFailure.getFirstArg()->getNonTypeTemplateArgumentType(); QualType T2 = DeductionFailure.getSecondArg()->getNonTypeTemplateArgumentType(); if (!T1.isNull() && !T2.isNull() && !S.Context.hasSameType(T1, T2)) { S.Diag(Templated->getLocation(), diag::note_ovl_candidate_inconsistent_deduction_types) << ParamD->getDeclName() << *DeductionFailure.getFirstArg() << T1 << *DeductionFailure.getSecondArg() << T2; MaybeEmitInheritedConstructorNote(S, Found); return; } which = 1; } else { which = 2; } // Tweak the diagnostic if the problem is that we deduced packs of // different arities. We'll print the actual packs anyway in case that // includes additional useful information. if (DeductionFailure.getFirstArg()->getKind() == TemplateArgument::Pack && DeductionFailure.getSecondArg()->getKind() == TemplateArgument::Pack && DeductionFailure.getFirstArg()->pack_size() != DeductionFailure.getSecondArg()->pack_size()) { which = 3; } S.Diag(Templated->getLocation(), diag::note_ovl_candidate_inconsistent_deduction) << which << ParamD->getDeclName() << *DeductionFailure.getFirstArg() << *DeductionFailure.getSecondArg(); MaybeEmitInheritedConstructorNote(S, Found); return; } case Sema::TDK_InvalidExplicitArguments: assert(ParamD && "no parameter found for invalid explicit arguments"); if (ParamD->getDeclName()) S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_named) << ParamD->getDeclName(); else { int index = 0; if (TemplateTypeParmDecl *TTP = dyn_cast(ParamD)) index = TTP->getIndex(); else if (NonTypeTemplateParmDecl *NTTP = dyn_cast(ParamD)) index = NTTP->getIndex(); else index = cast(ParamD)->getIndex(); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_explicit_arg_mismatch_unnamed) << (index + 1); } MaybeEmitInheritedConstructorNote(S, Found); return; case Sema::TDK_ConstraintsNotSatisfied: { // Format the template argument list into the argument string. SmallString<128> TemplateArgString; TemplateArgumentList *Args = DeductionFailure.getTemplateArgumentList(); TemplateArgString = " "; TemplateArgString += S.getTemplateArgumentBindingsText( getDescribedTemplate(Templated)->getTemplateParameters(), *Args); if (TemplateArgString.size() == 1) TemplateArgString.clear(); S.Diag(Templated->getLocation(), diag::note_ovl_candidate_unsatisfied_constraints) << TemplateArgString; S.DiagnoseUnsatisfiedConstraint( static_cast(DeductionFailure.Data)->Satisfaction); return; } case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: DiagnoseArityMismatch(S, Found, Templated, NumArgs); return; case Sema::TDK_InstantiationDepth: S.Diag(Templated->getLocation(), diag::note_ovl_candidate_instantiation_depth); MaybeEmitInheritedConstructorNote(S, Found); return; case Sema::TDK_SubstitutionFailure: { // Format the template argument list into the argument string. SmallString<128> TemplateArgString; if (TemplateArgumentList *Args = DeductionFailure.getTemplateArgumentList()) { TemplateArgString = " "; TemplateArgString += S.getTemplateArgumentBindingsText( getDescribedTemplate(Templated)->getTemplateParameters(), *Args); if (TemplateArgString.size() == 1) TemplateArgString.clear(); } // If this candidate was disabled by enable_if, say so. PartialDiagnosticAt *PDiag = DeductionFailure.getSFINAEDiagnostic(); if (PDiag && PDiag->second.getDiagID() == diag::err_typename_nested_not_found_enable_if) { // FIXME: Use the source range of the condition, and the fully-qualified // name of the enable_if template. These are both present in PDiag. S.Diag(PDiag->first, diag::note_ovl_candidate_disabled_by_enable_if) << "'enable_if'" << TemplateArgString; return; } // We found a specific requirement that disabled the enable_if. if (PDiag && PDiag->second.getDiagID() == diag::err_typename_nested_not_found_requirement) { S.Diag(Templated->getLocation(), diag::note_ovl_candidate_disabled_by_requirement) << PDiag->second.getStringArg(0) << TemplateArgString; return; } // Format the SFINAE diagnostic into the argument string. // FIXME: Add a general mechanism to include a PartialDiagnostic *'s // formatted message in another diagnostic. SmallString<128> SFINAEArgString; SourceRange R; if (PDiag) { SFINAEArgString = ": "; R = SourceRange(PDiag->first, PDiag->first); PDiag->second.EmitToString(S.getDiagnostics(), SFINAEArgString); } S.Diag(Templated->getLocation(), diag::note_ovl_candidate_substitution_failure) << TemplateArgString << SFINAEArgString << R; MaybeEmitInheritedConstructorNote(S, Found); return; } case Sema::TDK_DeducedMismatch: case Sema::TDK_DeducedMismatchNested: { // Format the template argument list into the argument string. SmallString<128> TemplateArgString; if (TemplateArgumentList *Args = DeductionFailure.getTemplateArgumentList()) { TemplateArgString = " "; TemplateArgString += S.getTemplateArgumentBindingsText( getDescribedTemplate(Templated)->getTemplateParameters(), *Args); if (TemplateArgString.size() == 1) TemplateArgString.clear(); } S.Diag(Templated->getLocation(), diag::note_ovl_candidate_deduced_mismatch) << (*DeductionFailure.getCallArgIndex() + 1) << *DeductionFailure.getFirstArg() << *DeductionFailure.getSecondArg() << TemplateArgString << (DeductionFailure.Result == Sema::TDK_DeducedMismatchNested); break; } case Sema::TDK_NonDeducedMismatch: { // FIXME: Provide a source location to indicate what we couldn't match. TemplateArgument FirstTA = *DeductionFailure.getFirstArg(); TemplateArgument SecondTA = *DeductionFailure.getSecondArg(); if (FirstTA.getKind() == TemplateArgument::Template && SecondTA.getKind() == TemplateArgument::Template) { TemplateName FirstTN = FirstTA.getAsTemplate(); TemplateName SecondTN = SecondTA.getAsTemplate(); if (FirstTN.getKind() == TemplateName::Template && SecondTN.getKind() == TemplateName::Template) { if (FirstTN.getAsTemplateDecl()->getName() == SecondTN.getAsTemplateDecl()->getName()) { // FIXME: This fixes a bad diagnostic where both templates are named // the same. This particular case is a bit difficult since: // 1) It is passed as a string to the diagnostic printer. // 2) The diagnostic printer only attempts to find a better // name for types, not decls. // Ideally, this should folded into the diagnostic printer. S.Diag(Templated->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch_qualified) << FirstTN.getAsTemplateDecl() << SecondTN.getAsTemplateDecl(); return; } } } if (TakingCandidateAddress && isa(Templated) && !checkAddressOfCandidateIsAvailable(S, cast(Templated))) return; // FIXME: For generic lambda parameters, check if the function is a lambda // call operator, and if so, emit a prettier and more informative // diagnostic that mentions 'auto' and lambda in addition to // (or instead of?) the canonical template type parameters. S.Diag(Templated->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch) << FirstTA << SecondTA; return; } // TODO: diagnose these individually, then kill off // note_ovl_candidate_bad_deduction, which is uselessly vague. case Sema::TDK_MiscellaneousDeductionFailure: S.Diag(Templated->getLocation(), diag::note_ovl_candidate_bad_deduction); MaybeEmitInheritedConstructorNote(S, Found); return; case Sema::TDK_CUDATargetMismatch: S.Diag(Templated->getLocation(), diag::note_cuda_ovl_candidate_target_mismatch); return; } } /// Diagnose a failed template-argument deduction, for function calls. static void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, unsigned NumArgs, bool TakingCandidateAddress) { unsigned TDK = Cand->DeductionFailure.Result; if (TDK == Sema::TDK_TooFewArguments || TDK == Sema::TDK_TooManyArguments) { if (CheckArityMismatch(S, Cand, NumArgs)) return; } DiagnoseBadDeduction(S, Cand->FoundDecl, Cand->Function, // pattern Cand->DeductionFailure, NumArgs, TakingCandidateAddress); } /// CUDA: diagnose an invalid call across targets. static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) { FunctionDecl *Caller = cast(S.CurContext); FunctionDecl *Callee = Cand->Function; Sema::CUDAFunctionTarget CallerTarget = S.IdentifyCUDATarget(Caller), CalleeTarget = S.IdentifyCUDATarget(Callee); std::string FnDesc; std::pair FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Callee, Cand->getRewriteKind(), FnDesc); S.Diag(Callee->getLocation(), diag::note_ovl_candidate_bad_target) << (unsigned)FnKindPair.first << (unsigned)ocs_non_template << FnDesc /* Ignored */ << CalleeTarget << CallerTarget; // This could be an implicit constructor for which we could not infer the // target due to a collsion. Diagnose that case. CXXMethodDecl *Meth = dyn_cast(Callee); if (Meth != nullptr && Meth->isImplicit()) { CXXRecordDecl *ParentClass = Meth->getParent(); Sema::CXXSpecialMember CSM; switch (FnKindPair.first) { default: return; case oc_implicit_default_constructor: CSM = Sema::CXXDefaultConstructor; break; case oc_implicit_copy_constructor: CSM = Sema::CXXCopyConstructor; break; case oc_implicit_move_constructor: CSM = Sema::CXXMoveConstructor; break; case oc_implicit_copy_assignment: CSM = Sema::CXXCopyAssignment; break; case oc_implicit_move_assignment: CSM = Sema::CXXMoveAssignment; break; }; bool ConstRHS = false; if (Meth->getNumParams()) { if (const ReferenceType *RT = Meth->getParamDecl(0)->getType()->getAs()) { ConstRHS = RT->getPointeeType().isConstQualified(); } } S.inferCUDATargetForImplicitSpecialMember(ParentClass, CSM, Meth, /* ConstRHS */ ConstRHS, /* Diagnose */ true); } } static void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) { FunctionDecl *Callee = Cand->Function; EnableIfAttr *Attr = static_cast(Cand->DeductionFailure.Data); S.Diag(Callee->getLocation(), diag::note_ovl_candidate_disabled_by_function_cond_attr) << Attr->getCond()->getSourceRange() << Attr->getMessage(); } static void DiagnoseFailedExplicitSpec(Sema &S, OverloadCandidate *Cand) { ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(Cand->Function); assert(ES.isExplicit() && "not an explicit candidate"); unsigned Kind; switch (Cand->Function->getDeclKind()) { case Decl::Kind::CXXConstructor: Kind = 0; break; case Decl::Kind::CXXConversion: Kind = 1; break; case Decl::Kind::CXXDeductionGuide: Kind = Cand->Function->isImplicit() ? 0 : 2; break; default: llvm_unreachable("invalid Decl"); } // Note the location of the first (in-class) declaration; a redeclaration // (particularly an out-of-class definition) will typically lack the // 'explicit' specifier. // FIXME: This is probably a good thing to do for all 'candidate' notes. FunctionDecl *First = Cand->Function->getFirstDecl(); if (FunctionDecl *Pattern = First->getTemplateInstantiationPattern()) First = Pattern->getFirstDecl(); S.Diag(First->getLocation(), diag::note_ovl_candidate_explicit) << Kind << (ES.getExpr() ? 1 : 0) << (ES.getExpr() ? ES.getExpr()->getSourceRange() : SourceRange()); } static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) { FunctionDecl *Callee = Cand->Function; S.Diag(Callee->getLocation(), diag::note_ovl_candidate_disabled_by_extension) << S.getOpenCLExtensionsFromDeclExtMap(Callee); } /// Generates a 'note' diagnostic for an overload candidate. We've /// already generated a primary error at the call site. /// /// It really does need to be a single diagnostic with its caret /// pointed at the candidate declaration. Yes, this creates some /// major challenges of technical writing. Yes, this makes pointing /// out problems with specific arguments quite awkward. It's still /// better than generating twenty screens of text for every failed /// overload. /// /// It would be great to be able to express per-candidate problems /// more richly for those diagnostic clients that cared, but we'd /// still have to be just as careful with the default diagnostics. /// \param CtorDestAS Addr space of object being constructed (for ctor /// candidates only). static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, unsigned NumArgs, bool TakingCandidateAddress, LangAS CtorDestAS = LangAS::Default) { FunctionDecl *Fn = Cand->Function; // Note deleted candidates, but only if they're viable. if (Cand->Viable) { if (Fn->isDeleted()) { std::string FnDesc; std::pair FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, Cand->getRewriteKind(), FnDesc); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted) << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc << (Fn->isDeleted() ? (Fn->isDeletedAsWritten() ? 1 : 2) : 0); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // We don't really have anything else to say about viable candidates. S.NoteOverloadCandidate(Cand->FoundDecl, Fn, Cand->getRewriteKind()); return; } switch (Cand->FailureKind) { case ovl_fail_too_many_arguments: case ovl_fail_too_few_arguments: return DiagnoseArityMismatch(S, Cand, NumArgs); case ovl_fail_bad_deduction: return DiagnoseBadDeduction(S, Cand, NumArgs, TakingCandidateAddress); case ovl_fail_illegal_constructor: { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_illegal_constructor) << (Fn->getPrimaryTemplate() ? 1 : 0); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } case ovl_fail_object_addrspace_mismatch: { Qualifiers QualsForPrinting; QualsForPrinting.setAddressSpace(CtorDestAS); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_illegal_constructor_adrspace_mismatch) << QualsForPrinting; MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } case ovl_fail_trivial_conversion: case ovl_fail_bad_final_conversion: case ovl_fail_final_conversion_not_exact: return S.NoteOverloadCandidate(Cand->FoundDecl, Fn, Cand->getRewriteKind()); case ovl_fail_bad_conversion: { unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0); for (unsigned N = Cand->Conversions.size(); I != N; ++I) if (Cand->Conversions[I].isBad()) return DiagnoseBadConversion(S, Cand, I, TakingCandidateAddress); // FIXME: this currently happens when we're called from SemaInit // when user-conversion overload fails. Figure out how to handle // those conditions and diagnose them well. return S.NoteOverloadCandidate(Cand->FoundDecl, Fn, Cand->getRewriteKind()); } case ovl_fail_bad_target: return DiagnoseBadTarget(S, Cand); case ovl_fail_enable_if: return DiagnoseFailedEnableIfAttr(S, Cand); case ovl_fail_explicit: return DiagnoseFailedExplicitSpec(S, Cand); case ovl_fail_ext_disabled: return DiagnoseOpenCLExtensionDisabled(S, Cand); case ovl_fail_inhctor_slice: // It's generally not interesting to note copy/move constructors here. if (cast(Fn)->isCopyOrMoveConstructor()) return; S.Diag(Fn->getLocation(), diag::note_ovl_candidate_inherited_constructor_slice) << (Fn->getPrimaryTemplate() ? 1 : 0) << Fn->getParamDecl(0)->getType()->isRValueReferenceType(); MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; case ovl_fail_addr_not_available: { bool Available = checkAddressOfCandidateIsAvailable(S, Cand->Function); (void)Available; assert(!Available); break; } case ovl_non_default_multiversion_function: // Do nothing, these should simply be ignored. break; case ovl_fail_constraints_not_satisfied: { std::string FnDesc; std::pair FnKindPair = ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, Cand->getRewriteKind(), FnDesc); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_constraints_not_satisfied) << (unsigned)FnKindPair.first << (unsigned)ocs_non_template << FnDesc /* Ignored */; ConstraintSatisfaction Satisfaction; if (S.CheckFunctionConstraints(Fn, Satisfaction)) break; S.DiagnoseUnsatisfiedConstraint(Satisfaction); } } } static void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) { // Desugar the type of the surrogate down to a function type, // retaining as many typedefs as possible while still showing // the function type (and, therefore, its parameter types). QualType FnType = Cand->Surrogate->getConversionType(); bool isLValueReference = false; bool isRValueReference = false; bool isPointer = false; if (const LValueReferenceType *FnTypeRef = FnType->getAs()) { FnType = FnTypeRef->getPointeeType(); isLValueReference = true; } else if (const RValueReferenceType *FnTypeRef = FnType->getAs()) { FnType = FnTypeRef->getPointeeType(); isRValueReference = true; } if (const PointerType *FnTypePtr = FnType->getAs()) { FnType = FnTypePtr->getPointeeType(); isPointer = true; } // Desugar down to a function type. FnType = QualType(FnType->getAs(), 0); // Reconstruct the pointer/reference as appropriate. if (isPointer) FnType = S.Context.getPointerType(FnType); if (isRValueReference) FnType = S.Context.getRValueReferenceType(FnType); if (isLValueReference) FnType = S.Context.getLValueReferenceType(FnType); S.Diag(Cand->Surrogate->getLocation(), diag::note_ovl_surrogate_cand) << FnType; } static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc, SourceLocation OpLoc, OverloadCandidate *Cand) { assert(Cand->Conversions.size() <= 2 && "builtin operator is not binary"); std::string TypeStr("operator"); TypeStr += Opc; TypeStr += "("; TypeStr += Cand->BuiltinParamTypes[0].getAsString(); if (Cand->Conversions.size() == 1) { TypeStr += ")"; S.Diag(OpLoc, diag::note_ovl_builtin_candidate) << TypeStr; } else { TypeStr += ", "; TypeStr += Cand->BuiltinParamTypes[1].getAsString(); TypeStr += ")"; S.Diag(OpLoc, diag::note_ovl_builtin_candidate) << TypeStr; } } static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc, OverloadCandidate *Cand) { for (const ImplicitConversionSequence &ICS : Cand->Conversions) { if (ICS.isBad()) break; // all meaningless after first invalid if (!ICS.isAmbiguous()) continue; ICS.DiagnoseAmbiguousConversion( S, OpLoc, S.PDiag(diag::note_ambiguous_type_conversion)); } } static SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) { if (Cand->Function) return Cand->Function->getLocation(); if (Cand->IsSurrogate) return Cand->Surrogate->getLocation(); return SourceLocation(); } static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) { switch ((Sema::TemplateDeductionResult)DFI.Result) { case Sema::TDK_Success: case Sema::TDK_NonDependentConversionFailure: llvm_unreachable("non-deduction failure while diagnosing bad deduction"); case Sema::TDK_Invalid: case Sema::TDK_Incomplete: case Sema::TDK_IncompletePack: return 1; case Sema::TDK_Underqualified: case Sema::TDK_Inconsistent: return 2; case Sema::TDK_SubstitutionFailure: case Sema::TDK_DeducedMismatch: case Sema::TDK_ConstraintsNotSatisfied: case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_MiscellaneousDeductionFailure: case Sema::TDK_CUDATargetMismatch: return 3; case Sema::TDK_InstantiationDepth: return 4; case Sema::TDK_InvalidExplicitArguments: return 5; case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: return 6; } llvm_unreachable("Unhandled deduction result"); } namespace { struct CompareOverloadCandidatesForDisplay { Sema &S; SourceLocation Loc; size_t NumArgs; OverloadCandidateSet::CandidateSetKind CSK; CompareOverloadCandidatesForDisplay( Sema &S, SourceLocation Loc, size_t NArgs, OverloadCandidateSet::CandidateSetKind CSK) : S(S), NumArgs(NArgs), CSK(CSK) {} OverloadFailureKind EffectiveFailureKind(const OverloadCandidate *C) const { // If there are too many or too few arguments, that's the high-order bit we // want to sort by, even if the immediate failure kind was something else. if (C->FailureKind == ovl_fail_too_many_arguments || C->FailureKind == ovl_fail_too_few_arguments) return static_cast(C->FailureKind); if (C->Function) { if (NumArgs > C->Function->getNumParams() && !C->Function->isVariadic()) return ovl_fail_too_many_arguments; if (NumArgs < C->Function->getMinRequiredArguments()) return ovl_fail_too_few_arguments; } return static_cast(C->FailureKind); } bool operator()(const OverloadCandidate *L, const OverloadCandidate *R) { // Fast-path this check. if (L == R) return false; // Order first by viability. if (L->Viable) { if (!R->Viable) return true; // TODO: introduce a tri-valued comparison for overload // candidates. Would be more worthwhile if we had a sort // that could exploit it. if (isBetterOverloadCandidate(S, *L, *R, SourceLocation(), CSK)) return true; if (isBetterOverloadCandidate(S, *R, *L, SourceLocation(), CSK)) return false; } else if (R->Viable) return false; assert(L->Viable == R->Viable); // Criteria by which we can sort non-viable candidates: if (!L->Viable) { OverloadFailureKind LFailureKind = EffectiveFailureKind(L); OverloadFailureKind RFailureKind = EffectiveFailureKind(R); // 1. Arity mismatches come after other candidates. if (LFailureKind == ovl_fail_too_many_arguments || LFailureKind == ovl_fail_too_few_arguments) { if (RFailureKind == ovl_fail_too_many_arguments || RFailureKind == ovl_fail_too_few_arguments) { int LDist = std::abs((int)L->getNumParams() - (int)NumArgs); int RDist = std::abs((int)R->getNumParams() - (int)NumArgs); if (LDist == RDist) { if (LFailureKind == RFailureKind) // Sort non-surrogates before surrogates. return !L->IsSurrogate && R->IsSurrogate; // Sort candidates requiring fewer parameters than there were // arguments given after candidates requiring more parameters // than there were arguments given. return LFailureKind == ovl_fail_too_many_arguments; } return LDist < RDist; } return false; } if (RFailureKind == ovl_fail_too_many_arguments || RFailureKind == ovl_fail_too_few_arguments) return true; // 2. Bad conversions come first and are ordered by the number // of bad conversions and quality of good conversions. if (LFailureKind == ovl_fail_bad_conversion) { if (RFailureKind != ovl_fail_bad_conversion) return true; // The conversion that can be fixed with a smaller number of changes, // comes first. unsigned numLFixes = L->Fix.NumConversionsFixed; unsigned numRFixes = R->Fix.NumConversionsFixed; numLFixes = (numLFixes == 0) ? UINT_MAX : numLFixes; numRFixes = (numRFixes == 0) ? UINT_MAX : numRFixes; if (numLFixes != numRFixes) { return numLFixes < numRFixes; } // If there's any ordering between the defined conversions... // FIXME: this might not be transitive. assert(L->Conversions.size() == R->Conversions.size()); int leftBetter = 0; unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument); for (unsigned E = L->Conversions.size(); I != E; ++I) { switch (CompareImplicitConversionSequences(S, Loc, L->Conversions[I], R->Conversions[I])) { case ImplicitConversionSequence::Better: leftBetter++; break; case ImplicitConversionSequence::Worse: leftBetter--; break; case ImplicitConversionSequence::Indistinguishable: break; } } if (leftBetter > 0) return true; if (leftBetter < 0) return false; } else if (RFailureKind == ovl_fail_bad_conversion) return false; if (LFailureKind == ovl_fail_bad_deduction) { if (RFailureKind != ovl_fail_bad_deduction) return true; if (L->DeductionFailure.Result != R->DeductionFailure.Result) return RankDeductionFailure(L->DeductionFailure) < RankDeductionFailure(R->DeductionFailure); } else if (RFailureKind == ovl_fail_bad_deduction) return false; // TODO: others? } // Sort everything else by location. SourceLocation LLoc = GetLocationForCandidate(L); SourceLocation RLoc = GetLocationForCandidate(R); // Put candidates without locations (e.g. builtins) at the end. if (LLoc.isInvalid()) return false; if (RLoc.isInvalid()) return true; return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc); } }; } /// CompleteNonViableCandidate - Normally, overload resolution only /// computes up to the first bad conversion. Produces the FixIt set if /// possible. static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, ArrayRef Args, OverloadCandidateSet::CandidateSetKind CSK) { assert(!Cand->Viable); // Don't do anything on failures other than bad conversion. if (Cand->FailureKind != ovl_fail_bad_conversion) return; // We only want the FixIts if all the arguments can be corrected. bool Unfixable = false; // Use a implicit copy initialization to check conversion fixes. Cand->Fix.setConversionChecker(TryCopyInitialization); // Attempt to fix the bad conversion. unsigned ConvCount = Cand->Conversions.size(); for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); /**/; ++ConvIdx) { assert(ConvIdx != ConvCount && "no bad conversion in candidate"); if (Cand->Conversions[ConvIdx].isInitialized() && Cand->Conversions[ConvIdx].isBad()) { Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S); break; } } // FIXME: this should probably be preserved from the overload // operation somehow. bool SuppressUserConversions = false; unsigned ConvIdx = 0; unsigned ArgIdx = 0; ArrayRef ParamTypes; bool Reversed = Cand->RewriteKind & CRK_Reversed; if (Cand->IsSurrogate) { QualType ConvType = Cand->Surrogate->getConversionType().getNonReferenceType(); if (const PointerType *ConvPtrType = ConvType->getAs()) ConvType = ConvPtrType->getPointeeType(); ParamTypes = ConvType->castAs()->getParamTypes(); // Conversion 0 is 'this', which doesn't have a corresponding parameter. ConvIdx = 1; } else if (Cand->Function) { ParamTypes = Cand->Function->getType()->castAs()->getParamTypes(); if (isa(Cand->Function) && !isa(Cand->Function) && !Reversed) { // Conversion 0 is 'this', which doesn't have a corresponding parameter. ConvIdx = 1; if (CSK == OverloadCandidateSet::CSK_Operator && Cand->Function->getDeclName().getCXXOverloadedOperator() != OO_Call) // Argument 0 is 'this', which doesn't have a corresponding parameter. ArgIdx = 1; } } else { // Builtin operator. assert(ConvCount <= 3); ParamTypes = Cand->BuiltinParamTypes; } // Fill in the rest of the conversions. for (unsigned ParamIdx = Reversed ? ParamTypes.size() - 1 : 0; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx, ParamIdx += (Reversed ? -1 : 1)) { assert(ArgIdx < Args.size() && "no argument for this arg conversion"); if (Cand->Conversions[ConvIdx].isInitialized()) { // We've already checked this conversion. } else if (ParamIdx < ParamTypes.size()) { if (ParamTypes[ParamIdx]->isDependentType()) Cand->Conversions[ConvIdx].setAsIdentityConversion( Args[ArgIdx]->getType()); else { Cand->Conversions[ConvIdx] = TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ParamIdx], SuppressUserConversions, /*InOverloadResolution=*/true, /*AllowObjCWritebackConversion=*/ S.getLangOpts().ObjCAutoRefCount); // Store the FixIt in the candidate if it exists. if (!Unfixable && Cand->Conversions[ConvIdx].isBad()) Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S); } } else Cand->Conversions[ConvIdx].setEllipsis(); } } SmallVector OverloadCandidateSet::CompleteCandidates( Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef Args, SourceLocation OpLoc, llvm::function_ref Filter) { // Sort the candidates by viability and position. Sorting directly would // be prohibitive, so we make a set of pointers and sort those. SmallVector Cands; if (OCD == OCD_AllCandidates) Cands.reserve(size()); for (iterator Cand = begin(), LastCand = end(); Cand != LastCand; ++Cand) { if (!Filter(*Cand)) continue; switch (OCD) { case OCD_AllCandidates: if (!Cand->Viable) { if (!Cand->Function && !Cand->IsSurrogate) { // This a non-viable builtin candidate. We do not, in general, // want to list every possible builtin candidate. continue; } CompleteNonViableCandidate(S, Cand, Args, Kind); } break; case OCD_ViableCandidates: if (!Cand->Viable) continue; break; case OCD_AmbiguousCandidates: if (!Cand->Best) continue; break; } Cands.push_back(Cand); } llvm::stable_sort( Cands, CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size(), Kind)); return Cands; } /// When overload resolution fails, prints diagnostic messages containing the /// candidates in the candidate set. void OverloadCandidateSet::NoteCandidates(PartialDiagnosticAt PD, Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef Args, StringRef Opc, SourceLocation OpLoc, llvm::function_ref Filter) { auto Cands = CompleteCandidates(S, OCD, Args, OpLoc, Filter); S.Diag(PD.first, PD.second); NoteCandidates(S, Args, Cands, Opc, OpLoc); if (OCD == OCD_AmbiguousCandidates) MaybeDiagnoseAmbiguousConstraints(S, {begin(), end()}); } void OverloadCandidateSet::NoteCandidates(Sema &S, ArrayRef Args, ArrayRef Cands, StringRef Opc, SourceLocation OpLoc) { bool ReportedAmbiguousConversions = false; const OverloadsShown ShowOverloads = S.Diags.getShowOverloads(); unsigned CandsShown = 0; auto I = Cands.begin(), E = Cands.end(); for (; I != E; ++I) { OverloadCandidate *Cand = *I; // Set an arbitrary limit on the number of candidate functions we'll spam // the user with. FIXME: This limit should depend on details of the // candidate list. if (CandsShown >= 4 && ShowOverloads == Ovl_Best) { break; } ++CandsShown; if (Cand->Function) NoteFunctionCandidate(S, Cand, Args.size(), /*TakingCandidateAddress=*/false, DestAS); else if (Cand->IsSurrogate) NoteSurrogateCandidate(S, Cand); else { assert(Cand->Viable && "Non-viable built-in candidates are not added to Cands."); // Generally we only see ambiguities including viable builtin // operators if overload resolution got screwed up by an // ambiguous user-defined conversion. // // FIXME: It's quite possible for different conversions to see // different ambiguities, though. if (!ReportedAmbiguousConversions) { NoteAmbiguousUserConversions(S, OpLoc, Cand); ReportedAmbiguousConversions = true; } // If this is a viable builtin, print it. NoteBuiltinOperatorCandidate(S, Opc, OpLoc, Cand); } } if (I != E) S.Diag(OpLoc, diag::note_ovl_too_many_candidates) << int(E - I); } static SourceLocation GetLocationForCandidate(const TemplateSpecCandidate *Cand) { return Cand->Specialization ? Cand->Specialization->getLocation() : SourceLocation(); } namespace { struct CompareTemplateSpecCandidatesForDisplay { Sema &S; CompareTemplateSpecCandidatesForDisplay(Sema &S) : S(S) {} bool operator()(const TemplateSpecCandidate *L, const TemplateSpecCandidate *R) { // Fast-path this check. if (L == R) return false; // Assuming that both candidates are not matches... // Sort by the ranking of deduction failures. if (L->DeductionFailure.Result != R->DeductionFailure.Result) return RankDeductionFailure(L->DeductionFailure) < RankDeductionFailure(R->DeductionFailure); // Sort everything else by location. SourceLocation LLoc = GetLocationForCandidate(L); SourceLocation RLoc = GetLocationForCandidate(R); // Put candidates without locations (e.g. builtins) at the end. if (LLoc.isInvalid()) return false; if (RLoc.isInvalid()) return true; return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc); } }; } /// Diagnose a template argument deduction failure. /// We are treating these failures as overload failures due to bad /// deductions. void TemplateSpecCandidate::NoteDeductionFailure(Sema &S, bool ForTakingAddress) { DiagnoseBadDeduction(S, FoundDecl, Specialization, // pattern DeductionFailure, /*NumArgs=*/0, ForTakingAddress); } void TemplateSpecCandidateSet::destroyCandidates() { for (iterator i = begin(), e = end(); i != e; ++i) { i->DeductionFailure.Destroy(); } } void TemplateSpecCandidateSet::clear() { destroyCandidates(); Candidates.clear(); } /// NoteCandidates - When no template specialization match is found, prints /// diagnostic messages containing the non-matching specializations that form /// the candidate set. /// This is analoguous to OverloadCandidateSet::NoteCandidates() with /// OCD == OCD_AllCandidates and Cand->Viable == false. void TemplateSpecCandidateSet::NoteCandidates(Sema &S, SourceLocation Loc) { // Sort the candidates by position (assuming no candidate is a match). // Sorting directly would be prohibitive, so we make a set of pointers // and sort those. SmallVector Cands; Cands.reserve(size()); for (iterator Cand = begin(), LastCand = end(); Cand != LastCand; ++Cand) { if (Cand->Specialization) Cands.push_back(Cand); // Otherwise, this is a non-matching builtin candidate. We do not, // in general, want to list every possible builtin candidate. } llvm::sort(Cands, CompareTemplateSpecCandidatesForDisplay(S)); // FIXME: Perhaps rename OverloadsShown and getShowOverloads() // for generalization purposes (?). const OverloadsShown ShowOverloads = S.Diags.getShowOverloads(); SmallVectorImpl::iterator I, E; unsigned CandsShown = 0; for (I = Cands.begin(), E = Cands.end(); I != E; ++I) { TemplateSpecCandidate *Cand = *I; // Set an arbitrary limit on the number of candidates we'll spam // the user with. FIXME: This limit should depend on details of the // candidate list. if (CandsShown >= 4 && ShowOverloads == Ovl_Best) break; ++CandsShown; assert(Cand->Specialization && "Non-matching built-in candidates are not added to Cands."); Cand->NoteDeductionFailure(S, ForTakingAddress); } if (I != E) S.Diag(Loc, diag::note_ovl_too_many_candidates) << int(E - I); } // [PossiblyAFunctionType] --> [Return] // NonFunctionType --> NonFunctionType // R (A) --> R(A) // R (*)(A) --> R (A) // R (&)(A) --> R (A) // R (S::*)(A) --> R (A) QualType Sema::ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType) { QualType Ret = PossiblyAFunctionType; if (const PointerType *ToTypePtr = PossiblyAFunctionType->getAs()) Ret = ToTypePtr->getPointeeType(); else if (const ReferenceType *ToTypeRef = PossiblyAFunctionType->getAs()) Ret = ToTypeRef->getPointeeType(); else if (const MemberPointerType *MemTypePtr = PossiblyAFunctionType->getAs()) Ret = MemTypePtr->getPointeeType(); Ret = Context.getCanonicalType(Ret).getUnqualifiedType(); return Ret; } static bool completeFunctionType(Sema &S, FunctionDecl *FD, SourceLocation Loc, bool Complain = true) { if (S.getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && S.DeduceReturnType(FD, Loc, Complain)) return true; auto *FPT = FD->getType()->castAs(); if (S.getLangOpts().CPlusPlus17 && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) && !S.ResolveExceptionSpec(Loc, FPT)) return true; return false; } namespace { // A helper class to help with address of function resolution // - allows us to avoid passing around all those ugly parameters class AddressOfFunctionResolver { Sema& S; Expr* SourceExpr; const QualType& TargetType; QualType TargetFunctionType; // Extracted function type from target type bool Complain; //DeclAccessPair& ResultFunctionAccessPair; ASTContext& Context; bool TargetTypeIsNonStaticMemberFunction; bool FoundNonTemplateFunction; bool StaticMemberFunctionFromBoundPointer; bool HasComplained; OverloadExpr::FindResult OvlExprInfo; OverloadExpr *OvlExpr; TemplateArgumentListInfo OvlExplicitTemplateArgs; SmallVector, 4> Matches; TemplateSpecCandidateSet FailedCandidates; public: AddressOfFunctionResolver(Sema &S, Expr *SourceExpr, const QualType &TargetType, bool Complain) : S(S), SourceExpr(SourceExpr), TargetType(TargetType), Complain(Complain), Context(S.getASTContext()), TargetTypeIsNonStaticMemberFunction( !!TargetType->getAs()), FoundNonTemplateFunction(false), StaticMemberFunctionFromBoundPointer(false), HasComplained(false), OvlExprInfo(OverloadExpr::find(SourceExpr)), OvlExpr(OvlExprInfo.Expression), FailedCandidates(OvlExpr->getNameLoc(), /*ForTakingAddress=*/true) { ExtractUnqualifiedFunctionTypeFromTargetType(); if (TargetFunctionType->isFunctionType()) { if (UnresolvedMemberExpr *UME = dyn_cast(OvlExpr)) if (!UME->isImplicitAccess() && !S.ResolveSingleFunctionTemplateSpecialization(UME)) StaticMemberFunctionFromBoundPointer = true; } else if (OvlExpr->hasExplicitTemplateArgs()) { DeclAccessPair dap; if (FunctionDecl *Fn = S.ResolveSingleFunctionTemplateSpecialization( OvlExpr, false, &dap)) { if (CXXMethodDecl *Method = dyn_cast(Fn)) if (!Method->isStatic()) { // If the target type is a non-function type and the function found // is a non-static member function, pretend as if that was the // target, it's the only possible type to end up with. TargetTypeIsNonStaticMemberFunction = true; // And skip adding the function if its not in the proper form. // We'll diagnose this due to an empty set of functions. if (!OvlExprInfo.HasFormOfMemberPointer) return; } Matches.push_back(std::make_pair(dap, Fn)); } return; } if (OvlExpr->hasExplicitTemplateArgs()) OvlExpr->copyTemplateArgumentsInto(OvlExplicitTemplateArgs); if (FindAllFunctionsThatMatchTargetTypeExactly()) { // C++ [over.over]p4: // If more than one function is selected, [...] if (Matches.size() > 1 && !eliminiateSuboptimalOverloadCandidates()) { if (FoundNonTemplateFunction) EliminateAllTemplateMatches(); else EliminateAllExceptMostSpecializedTemplate(); } } if (S.getLangOpts().CUDA && Matches.size() > 1) EliminateSuboptimalCudaMatches(); } bool hasComplained() const { return HasComplained; } private: bool candidateHasExactlyCorrectType(const FunctionDecl *FD) { QualType Discard; return Context.hasSameUnqualifiedType(TargetFunctionType, FD->getType()) || S.IsFunctionConversion(FD->getType(), TargetFunctionType, Discard); } /// \return true if A is considered a better overload candidate for the /// desired type than B. bool isBetterCandidate(const FunctionDecl *A, const FunctionDecl *B) { // If A doesn't have exactly the correct type, we don't want to classify it // as "better" than anything else. This way, the user is required to // disambiguate for us if there are multiple candidates and no exact match. return candidateHasExactlyCorrectType(A) && (!candidateHasExactlyCorrectType(B) || compareEnableIfAttrs(S, A, B) == Comparison::Better); } /// \return true if we were able to eliminate all but one overload candidate, /// false otherwise. bool eliminiateSuboptimalOverloadCandidates() { // Same algorithm as overload resolution -- one pass to pick the "best", // another pass to be sure that nothing is better than the best. auto Best = Matches.begin(); for (auto I = Matches.begin()+1, E = Matches.end(); I != E; ++I) if (isBetterCandidate(I->second, Best->second)) Best = I; const FunctionDecl *BestFn = Best->second; auto IsBestOrInferiorToBest = [this, BestFn]( const std::pair &Pair) { return BestFn == Pair.second || isBetterCandidate(BestFn, Pair.second); }; // Note: We explicitly leave Matches unmodified if there isn't a clear best // option, so we can potentially give the user a better error if (!llvm::all_of(Matches, IsBestOrInferiorToBest)) return false; Matches[0] = *Best; Matches.resize(1); return true; } bool isTargetTypeAFunction() const { return TargetFunctionType->isFunctionType(); } // [ToType] [Return] // R (*)(A) --> R (A), IsNonStaticMemberFunction = false // R (&)(A) --> R (A), IsNonStaticMemberFunction = false // R (S::*)(A) --> R (A), IsNonStaticMemberFunction = true void inline ExtractUnqualifiedFunctionTypeFromTargetType() { TargetFunctionType = S.ExtractUnqualifiedFunctionType(TargetType); } // return true if any matching specializations were found bool AddMatchingTemplateFunction(FunctionTemplateDecl* FunctionTemplate, const DeclAccessPair& CurAccessFunPair) { if (CXXMethodDecl *Method = dyn_cast(FunctionTemplate->getTemplatedDecl())) { // Skip non-static function templates when converting to pointer, and // static when converting to member pointer. if (Method->isStatic() == TargetTypeIsNonStaticMemberFunction) return false; } else if (TargetTypeIsNonStaticMemberFunction) return false; // C++ [over.over]p2: // If the name is a function template, template argument deduction is // done (14.8.2.2), and if the argument deduction succeeds, the // resulting template argument list is used to generate a single // function template specialization, which is added to the set of // overloaded functions considered. FunctionDecl *Specialization = nullptr; TemplateDeductionInfo Info(FailedCandidates.getLocation()); if (Sema::TemplateDeductionResult Result = S.DeduceTemplateArguments(FunctionTemplate, &OvlExplicitTemplateArgs, TargetFunctionType, Specialization, Info, /*IsAddressOfFunction*/true)) { // Make a note of the failed deduction for diagnostics. FailedCandidates.addCandidate() .set(CurAccessFunPair, FunctionTemplate->getTemplatedDecl(), MakeDeductionFailureInfo(Context, Result, Info)); return false; } // Template argument deduction ensures that we have an exact match or // compatible pointer-to-function arguments that would be adjusted by ICS. // This function template specicalization works. assert(S.isSameOrCompatibleFunctionType( Context.getCanonicalType(Specialization->getType()), Context.getCanonicalType(TargetFunctionType))); if (!S.checkAddressOfFunctionIsAvailable(Specialization)) return false; Matches.push_back(std::make_pair(CurAccessFunPair, Specialization)); return true; } bool AddMatchingNonTemplateFunction(NamedDecl* Fn, const DeclAccessPair& CurAccessFunPair) { if (CXXMethodDecl *Method = dyn_cast(Fn)) { // Skip non-static functions when converting to pointer, and static // when converting to member pointer. if (Method->isStatic() == TargetTypeIsNonStaticMemberFunction) return false; } else if (TargetTypeIsNonStaticMemberFunction) return false; if (FunctionDecl *FunDecl = dyn_cast(Fn)) { if (S.getLangOpts().CUDA) if (FunctionDecl *Caller = dyn_cast(S.CurContext)) if (!Caller->isImplicit() && !S.IsAllowedCUDACall(Caller, FunDecl)) return false; if (FunDecl->isMultiVersion()) { const auto *TA = FunDecl->getAttr(); if (TA && !TA->isDefaultVersion()) return false; } // If any candidate has a placeholder return type, trigger its deduction // now. if (completeFunctionType(S, FunDecl, SourceExpr->getBeginLoc(), Complain)) { HasComplained |= Complain; return false; } if (!S.checkAddressOfFunctionIsAvailable(FunDecl)) return false; // If we're in C, we need to support types that aren't exactly identical. if (!S.getLangOpts().CPlusPlus || candidateHasExactlyCorrectType(FunDecl)) { Matches.push_back(std::make_pair( CurAccessFunPair, cast(FunDecl->getCanonicalDecl()))); FoundNonTemplateFunction = true; return true; } } return false; } bool FindAllFunctionsThatMatchTargetTypeExactly() { bool Ret = false; // If the overload expression doesn't have the form of a pointer to // member, don't try to convert it to a pointer-to-member type. if (IsInvalidFormOfPointerToMemberFunction()) return false; for (UnresolvedSetIterator I = OvlExpr->decls_begin(), E = OvlExpr->decls_end(); I != E; ++I) { // Look through any using declarations to find the underlying function. NamedDecl *Fn = (*I)->getUnderlyingDecl(); // C++ [over.over]p3: // Non-member functions and static member functions match // targets of type "pointer-to-function" or "reference-to-function." // Nonstatic member functions match targets of // type "pointer-to-member-function." // Note that according to DR 247, the containing class does not matter. if (FunctionTemplateDecl *FunctionTemplate = dyn_cast(Fn)) { if (AddMatchingTemplateFunction(FunctionTemplate, I.getPair())) Ret = true; } // If we have explicit template arguments supplied, skip non-templates. else if (!OvlExpr->hasExplicitTemplateArgs() && AddMatchingNonTemplateFunction(Fn, I.getPair())) Ret = true; } assert(Ret || Matches.empty()); return Ret; } void EliminateAllExceptMostSpecializedTemplate() { // [...] and any given function template specialization F1 is // eliminated if the set contains a second function template // specialization whose function template is more specialized // than the function template of F1 according to the partial // ordering rules of 14.5.5.2. // The algorithm specified above is quadratic. We instead use a // two-pass algorithm (similar to the one used to identify the // best viable function in an overload set) that identifies the // best function template (if it exists). UnresolvedSet<4> MatchesCopy; // TODO: avoid! for (unsigned I = 0, E = Matches.size(); I != E; ++I) MatchesCopy.addDecl(Matches[I].second, Matches[I].first.getAccess()); // TODO: It looks like FailedCandidates does not serve much purpose // here, since the no_viable diagnostic has index 0. UnresolvedSetIterator Result = S.getMostSpecialized( MatchesCopy.begin(), MatchesCopy.end(), FailedCandidates, SourceExpr->getBeginLoc(), S.PDiag(), S.PDiag(diag::err_addr_ovl_ambiguous) << Matches[0].second->getDeclName(), S.PDiag(diag::note_ovl_candidate) << (unsigned)oc_function << (unsigned)ocs_described_template, Complain, TargetFunctionType); if (Result != MatchesCopy.end()) { // Make it the first and only element Matches[0].first = Matches[Result - MatchesCopy.begin()].first; Matches[0].second = cast(*Result); Matches.resize(1); } else HasComplained |= Complain; } void EliminateAllTemplateMatches() { // [...] any function template specializations in the set are // eliminated if the set also contains a non-template function, [...] for (unsigned I = 0, N = Matches.size(); I != N; ) { if (Matches[I].second->getPrimaryTemplate() == nullptr) ++I; else { Matches[I] = Matches[--N]; Matches.resize(N); } } } void EliminateSuboptimalCudaMatches() { S.EraseUnwantedCUDAMatches(dyn_cast(S.CurContext), Matches); } public: void ComplainNoMatchesFound() const { assert(Matches.empty()); S.Diag(OvlExpr->getBeginLoc(), diag::err_addr_ovl_no_viable) << OvlExpr->getName() << TargetFunctionType << OvlExpr->getSourceRange(); if (FailedCandidates.empty()) S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType, /*TakingAddress=*/true); else { // We have some deduction failure messages. Use them to diagnose // the function templates, and diagnose the non-template candidates // normally. for (UnresolvedSetIterator I = OvlExpr->decls_begin(), IEnd = OvlExpr->decls_end(); I != IEnd; ++I) if (FunctionDecl *Fun = dyn_cast((*I)->getUnderlyingDecl())) if (!functionHasPassObjectSizeParams(Fun)) S.NoteOverloadCandidate(*I, Fun, CRK_None, TargetFunctionType, /*TakingAddress=*/true); FailedCandidates.NoteCandidates(S, OvlExpr->getBeginLoc()); } } bool IsInvalidFormOfPointerToMemberFunction() const { return TargetTypeIsNonStaticMemberFunction && !OvlExprInfo.HasFormOfMemberPointer; } void ComplainIsInvalidFormOfPointerToMemberFunction() const { // TODO: Should we condition this on whether any functions might // have matched, or is it more appropriate to do that in callers? // TODO: a fixit wouldn't hurt. S.Diag(OvlExpr->getNameLoc(), diag::err_addr_ovl_no_qualifier) << TargetType << OvlExpr->getSourceRange(); } bool IsStaticMemberFunctionFromBoundPointer() const { return StaticMemberFunctionFromBoundPointer; } void ComplainIsStaticMemberFunctionFromBoundPointer() const { S.Diag(OvlExpr->getBeginLoc(), diag::err_invalid_form_pointer_member_function) << OvlExpr->getSourceRange(); } void ComplainOfInvalidConversion() const { S.Diag(OvlExpr->getBeginLoc(), diag::err_addr_ovl_not_func_ptrref) << OvlExpr->getName() << TargetType; } void ComplainMultipleMatchesFound() const { assert(Matches.size() > 1); S.Diag(OvlExpr->getBeginLoc(), diag::err_addr_ovl_ambiguous) << OvlExpr->getName() << OvlExpr->getSourceRange(); S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType, /*TakingAddress=*/true); } bool hadMultipleCandidates() const { return (OvlExpr->getNumDecls() > 1); } int getNumMatches() const { return Matches.size(); } FunctionDecl* getMatchingFunctionDecl() const { if (Matches.size() != 1) return nullptr; return Matches[0].second; } const DeclAccessPair* getMatchingFunctionAccessPair() const { if (Matches.size() != 1) return nullptr; return &Matches[0].first; } }; } /// ResolveAddressOfOverloadedFunction - Try to resolve the address of /// an overloaded function (C++ [over.over]), where @p From is an /// expression with overloaded function type and @p ToType is the type /// we're trying to resolve to. For example: /// /// @code /// int f(double); /// int f(int); /// /// int (*pfd)(double) = f; // selects f(double) /// @endcode /// /// This routine returns the resulting FunctionDecl if it could be /// resolved, and NULL otherwise. When @p Complain is true, this /// routine will emit diagnostics if there is an error. FunctionDecl * Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, QualType TargetType, bool Complain, DeclAccessPair &FoundResult, bool *pHadMultipleCandidates) { assert(AddressOfExpr->getType() == Context.OverloadTy); AddressOfFunctionResolver Resolver(*this, AddressOfExpr, TargetType, Complain); int NumMatches = Resolver.getNumMatches(); FunctionDecl *Fn = nullptr; bool ShouldComplain = Complain && !Resolver.hasComplained(); if (NumMatches == 0 && ShouldComplain) { if (Resolver.IsInvalidFormOfPointerToMemberFunction()) Resolver.ComplainIsInvalidFormOfPointerToMemberFunction(); else Resolver.ComplainNoMatchesFound(); } else if (NumMatches > 1 && ShouldComplain) Resolver.ComplainMultipleMatchesFound(); else if (NumMatches == 1) { Fn = Resolver.getMatchingFunctionDecl(); assert(Fn); if (auto *FPT = Fn->getType()->getAs()) ResolveExceptionSpec(AddressOfExpr->getExprLoc(), FPT); FoundResult = *Resolver.getMatchingFunctionAccessPair(); if (Complain) { if (Resolver.IsStaticMemberFunctionFromBoundPointer()) Resolver.ComplainIsStaticMemberFunctionFromBoundPointer(); else CheckAddressOfMemberAccess(AddressOfExpr, FoundResult); } } if (pHadMultipleCandidates) *pHadMultipleCandidates = Resolver.hadMultipleCandidates(); return Fn; } /// Given an expression that refers to an overloaded function, try to /// resolve that function to a single function that can have its address taken. /// This will modify `Pair` iff it returns non-null. /// /// This routine can only succeed if from all of the candidates in the overload /// set for SrcExpr that can have their addresses taken, there is one candidate /// that is more constrained than the rest. FunctionDecl * Sema::resolveAddressOfSingleOverloadCandidate(Expr *E, DeclAccessPair &Pair) { OverloadExpr::FindResult R = OverloadExpr::find(E); OverloadExpr *Ovl = R.Expression; bool IsResultAmbiguous = false; FunctionDecl *Result = nullptr; DeclAccessPair DAP; SmallVector AmbiguousDecls; auto CheckMoreConstrained = [&] (FunctionDecl *FD1, FunctionDecl *FD2) -> Optional { SmallVector AC1, AC2; FD1->getAssociatedConstraints(AC1); FD2->getAssociatedConstraints(AC2); bool AtLeastAsConstrained1, AtLeastAsConstrained2; if (IsAtLeastAsConstrained(FD1, AC1, FD2, AC2, AtLeastAsConstrained1)) return None; if (IsAtLeastAsConstrained(FD2, AC2, FD1, AC1, AtLeastAsConstrained2)) return None; if (AtLeastAsConstrained1 == AtLeastAsConstrained2) return None; return AtLeastAsConstrained1; }; // Don't use the AddressOfResolver because we're specifically looking for // cases where we have one overload candidate that lacks // enable_if/pass_object_size/... for (auto I = Ovl->decls_begin(), E = Ovl->decls_end(); I != E; ++I) { auto *FD = dyn_cast(I->getUnderlyingDecl()); if (!FD) return nullptr; if (!checkAddressOfFunctionIsAvailable(FD)) continue; // We have more than one result - see if it is more constrained than the // previous one. if (Result) { Optional MoreConstrainedThanPrevious = CheckMoreConstrained(FD, Result); if (!MoreConstrainedThanPrevious) { IsResultAmbiguous = true; AmbiguousDecls.push_back(FD); continue; } if (!*MoreConstrainedThanPrevious) continue; // FD is more constrained - replace Result with it. } IsResultAmbiguous = false; DAP = I.getPair(); Result = FD; } if (IsResultAmbiguous) return nullptr; if (Result) { SmallVector ResultAC; // We skipped over some ambiguous declarations which might be ambiguous with // the selected result. for (FunctionDecl *Skipped : AmbiguousDecls) if (!CheckMoreConstrained(Skipped, Result).hasValue()) return nullptr; Pair = DAP; } return Result; } /// Given an overloaded function, tries to turn it into a non-overloaded /// function reference using resolveAddressOfSingleOverloadCandidate. This /// will perform access checks, diagnose the use of the resultant decl, and, if /// requested, potentially perform a function-to-pointer decay. /// /// Returns false if resolveAddressOfSingleOverloadCandidate fails. /// Otherwise, returns true. This may emit diagnostics and return true. bool Sema::resolveAndFixAddressOfSingleOverloadCandidate( ExprResult &SrcExpr, bool DoFunctionPointerConverion) { Expr *E = SrcExpr.get(); assert(E->getType() == Context.OverloadTy && "SrcExpr must be an overload"); DeclAccessPair DAP; FunctionDecl *Found = resolveAddressOfSingleOverloadCandidate(E, DAP); if (!Found || Found->isCPUDispatchMultiVersion() || Found->isCPUSpecificMultiVersion()) return false; // Emitting multiple diagnostics for a function that is both inaccessible and // unavailable is consistent with our behavior elsewhere. So, always check // for both. DiagnoseUseOfDecl(Found, E->getExprLoc()); CheckAddressOfMemberAccess(E, DAP); Expr *Fixed = FixOverloadedFunctionReference(E, DAP, Found); if (DoFunctionPointerConverion && Fixed->getType()->isFunctionType()) SrcExpr = DefaultFunctionArrayConversion(Fixed, /*Diagnose=*/false); else SrcExpr = Fixed; return true; } /// Given an expression that refers to an overloaded function, try to /// resolve that overloaded function expression down to a single function. /// /// This routine can only resolve template-ids that refer to a single function /// template, where that template-id refers to a single template whose template /// arguments are either provided by the template-id or have defaults, /// as described in C++0x [temp.arg.explicit]p3. /// /// If no template-ids are found, no diagnostics are emitted and NULL is /// returned. FunctionDecl * Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain, DeclAccessPair *FoundResult) { // C++ [over.over]p1: // [...] [Note: any redundant set of parentheses surrounding the // overloaded function name is ignored (5.1). ] // C++ [over.over]p1: // [...] The overloaded function name can be preceded by the & // operator. // If we didn't actually find any template-ids, we're done. if (!ovl->hasExplicitTemplateArgs()) return nullptr; TemplateArgumentListInfo ExplicitTemplateArgs; ovl->copyTemplateArgumentsInto(ExplicitTemplateArgs); TemplateSpecCandidateSet FailedCandidates(ovl->getNameLoc()); // Look through all of the overloaded functions, searching for one // whose type matches exactly. FunctionDecl *Matched = nullptr; for (UnresolvedSetIterator I = ovl->decls_begin(), E = ovl->decls_end(); I != E; ++I) { // C++0x [temp.arg.explicit]p3: // [...] In contexts where deduction is done and fails, or in contexts // where deduction is not done, if a template argument list is // specified and it, along with any default template arguments, // identifies a single function template specialization, then the // template-id is an lvalue for the function template specialization. FunctionTemplateDecl *FunctionTemplate = cast((*I)->getUnderlyingDecl()); // C++ [over.over]p2: // If the name is a function template, template argument deduction is // done (14.8.2.2), and if the argument deduction succeeds, the // resulting template argument list is used to generate a single // function template specialization, which is added to the set of // overloaded functions considered. FunctionDecl *Specialization = nullptr; TemplateDeductionInfo Info(FailedCandidates.getLocation()); if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs, Specialization, Info, /*IsAddressOfFunction*/true)) { // Make a note of the failed deduction for diagnostics. // TODO: Actually use the failed-deduction info? FailedCandidates.addCandidate() .set(I.getPair(), FunctionTemplate->getTemplatedDecl(), MakeDeductionFailureInfo(Context, Result, Info)); continue; } assert(Specialization && "no specialization and no error?"); // Multiple matches; we can't resolve to a single declaration. if (Matched) { if (Complain) { Diag(ovl->getExprLoc(), diag::err_addr_ovl_ambiguous) << ovl->getName(); NoteAllOverloadCandidates(ovl); } return nullptr; } Matched = Specialization; if (FoundResult) *FoundResult = I.getPair(); } if (Matched && completeFunctionType(*this, Matched, ovl->getExprLoc(), Complain)) return nullptr; return Matched; } // Resolve and fix an overloaded expression that can be resolved // because it identifies a single function template specialization. // // Last three arguments should only be supplied if Complain = true // // Return true if it was logically possible to so resolve the // expression, regardless of whether or not it succeeded. Always // returns true if 'complain' is set. bool Sema::ResolveAndFixSingleFunctionTemplateSpecialization( ExprResult &SrcExpr, bool doFunctionPointerConverion, bool complain, SourceRange OpRangeForComplaining, QualType DestTypeForComplaining, unsigned DiagIDForComplaining) { assert(SrcExpr.get()->getType() == Context.OverloadTy); OverloadExpr::FindResult ovl = OverloadExpr::find(SrcExpr.get()); DeclAccessPair found; ExprResult SingleFunctionExpression; if (FunctionDecl *fn = ResolveSingleFunctionTemplateSpecialization( ovl.Expression, /*complain*/ false, &found)) { if (DiagnoseUseOfDecl(fn, SrcExpr.get()->getBeginLoc())) { SrcExpr = ExprError(); return true; } // It is only correct to resolve to an instance method if we're // resolving a form that's permitted to be a pointer to member. // Otherwise we'll end up making a bound member expression, which // is illegal in all the contexts we resolve like this. if (!ovl.HasFormOfMemberPointer && isa(fn) && cast(fn)->isInstance()) { if (!complain) return false; Diag(ovl.Expression->getExprLoc(), diag::err_bound_member_function) << 0 << ovl.Expression->getSourceRange(); // TODO: I believe we only end up here if there's a mix of // static and non-static candidates (otherwise the expression // would have 'bound member' type, not 'overload' type). // Ideally we would note which candidate was chosen and why // the static candidates were rejected. SrcExpr = ExprError(); return true; } // Fix the expression to refer to 'fn'. SingleFunctionExpression = FixOverloadedFunctionReference(SrcExpr.get(), found, fn); // If desired, do function-to-pointer decay. if (doFunctionPointerConverion) { SingleFunctionExpression = DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.get()); if (SingleFunctionExpression.isInvalid()) { SrcExpr = ExprError(); return true; } } } if (!SingleFunctionExpression.isUsable()) { if (complain) { Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining) << ovl.Expression->getName() << DestTypeForComplaining << OpRangeForComplaining << ovl.Expression->getQualifierLoc().getSourceRange(); NoteAllOverloadCandidates(SrcExpr.get()); SrcExpr = ExprError(); return true; } return false; } SrcExpr = SingleFunctionExpression; return true; } /// Add a single candidate to the overload set. static void AddOverloadedCallCandidate(Sema &S, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool PartialOverloading, bool KnownValid) { NamedDecl *Callee = FoundDecl.getDecl(); if (isa(Callee)) Callee = cast(Callee)->getTargetDecl(); if (FunctionDecl *Func = dyn_cast(Callee)) { if (ExplicitTemplateArgs) { assert(!KnownValid && "Explicit template arguments?"); return; } // Prevent ill-formed function decls to be added as overload candidates. if (!dyn_cast(Func->getType()->getAs())) return; S.AddOverloadCandidate(Func, FoundDecl, Args, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading); return; } if (FunctionTemplateDecl *FuncTemplate = dyn_cast(Callee)) { S.AddTemplateOverloadCandidate(FuncTemplate, FoundDecl, ExplicitTemplateArgs, Args, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading); return; } assert(!KnownValid && "unhandled case in overloaded call candidate"); } /// Add the overload candidates named by callee and/or found by argument /// dependent lookup to the given overload set. void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool PartialOverloading) { #ifndef NDEBUG // Verify that ArgumentDependentLookup is consistent with the rules // in C++0x [basic.lookup.argdep]p3: // // Let X be the lookup set produced by unqualified lookup (3.4.1) // and let Y be the lookup set produced by argument dependent // lookup (defined as follows). If X contains // // -- a declaration of a class member, or // // -- a block-scope function declaration that is not a // using-declaration, or // // -- a declaration that is neither a function or a function // template // // then Y is empty. if (ULE->requiresADL()) { for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(), E = ULE->decls_end(); I != E; ++I) { assert(!(*I)->getDeclContext()->isRecord()); assert(isa(*I) || !(*I)->getDeclContext()->isFunctionOrMethod()); assert((*I)->getUnderlyingDecl()->isFunctionOrFunctionTemplate()); } } #endif // It would be nice to avoid this copy. TemplateArgumentListInfo TABuffer; TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr; if (ULE->hasExplicitTemplateArgs()) { ULE->copyTemplateArgumentsInto(TABuffer); ExplicitTemplateArgs = &TABuffer; } for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(), E = ULE->decls_end(); I != E; ++I) AddOverloadedCallCandidate(*this, I.getPair(), ExplicitTemplateArgs, Args, CandidateSet, PartialOverloading, /*KnownValid*/ true); if (ULE->requiresADL()) AddArgumentDependentLookupCandidates(ULE->getName(), ULE->getExprLoc(), Args, ExplicitTemplateArgs, CandidateSet, PartialOverloading); } /// Determine whether a declaration with the specified name could be moved into /// a different namespace. static bool canBeDeclaredInNamespace(const DeclarationName &Name) { switch (Name.getCXXOverloadedOperator()) { case OO_New: case OO_Array_New: case OO_Delete: case OO_Array_Delete: return false; default: return true; } } /// Attempt to recover from an ill-formed use of a non-dependent name in a /// template, where the non-dependent name was declared after the template /// was defined. This is common in code written for a compilers which do not /// correctly implement two-stage name lookup. /// /// Returns true if a viable candidate was found and a diagnostic was issued. static bool DiagnoseTwoPhaseLookup(Sema &SemaRef, SourceLocation FnLoc, const CXXScopeSpec &SS, LookupResult &R, OverloadCandidateSet::CandidateSetKind CSK, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef Args, bool *DoDiagnoseEmptyLookup = nullptr) { if (!SemaRef.inTemplateInstantiation() || !SS.isEmpty()) return false; for (DeclContext *DC = SemaRef.CurContext; DC; DC = DC->getParent()) { if (DC->isTransparentContext()) continue; SemaRef.LookupQualifiedName(R, DC); if (!R.empty()) { R.suppressDiagnostics(); if (isa(DC)) { // Don't diagnose names we find in classes; we get much better // diagnostics for these from DiagnoseEmptyLookup. R.clear(); if (DoDiagnoseEmptyLookup) *DoDiagnoseEmptyLookup = true; return false; } OverloadCandidateSet Candidates(FnLoc, CSK); for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) AddOverloadedCallCandidate(SemaRef, I.getPair(), ExplicitTemplateArgs, Args, Candidates, false, /*KnownValid*/ false); OverloadCandidateSet::iterator Best; if (Candidates.BestViableFunction(SemaRef, FnLoc, Best) != OR_Success) { // No viable functions. Don't bother the user with notes for functions // which don't work and shouldn't be found anyway. R.clear(); return false; } // Find the namespaces where ADL would have looked, and suggest // declaring the function there instead. Sema::AssociatedNamespaceSet AssociatedNamespaces; Sema::AssociatedClassSet AssociatedClasses; SemaRef.FindAssociatedClassesAndNamespaces(FnLoc, Args, AssociatedNamespaces, AssociatedClasses); Sema::AssociatedNamespaceSet SuggestedNamespaces; if (canBeDeclaredInNamespace(R.getLookupName())) { DeclContext *Std = SemaRef.getStdNamespace(); for (Sema::AssociatedNamespaceSet::iterator it = AssociatedNamespaces.begin(), end = AssociatedNamespaces.end(); it != end; ++it) { // Never suggest declaring a function within namespace 'std'. if (Std && Std->Encloses(*it)) continue; // Never suggest declaring a function within a namespace with a // reserved name, like __gnu_cxx. NamespaceDecl *NS = dyn_cast(*it); if (NS && NS->getQualifiedNameAsString().find("__") != std::string::npos) continue; SuggestedNamespaces.insert(*it); } } SemaRef.Diag(R.getNameLoc(), diag::err_not_found_by_two_phase_lookup) << R.getLookupName(); if (SuggestedNamespaces.empty()) { SemaRef.Diag(Best->Function->getLocation(), diag::note_not_found_by_two_phase_lookup) << R.getLookupName() << 0; } else if (SuggestedNamespaces.size() == 1) { SemaRef.Diag(Best->Function->getLocation(), diag::note_not_found_by_two_phase_lookup) << R.getLookupName() << 1 << *SuggestedNamespaces.begin(); } else { // FIXME: It would be useful to list the associated namespaces here, // but the diagnostics infrastructure doesn't provide a way to produce // a localized representation of a list of items. SemaRef.Diag(Best->Function->getLocation(), diag::note_not_found_by_two_phase_lookup) << R.getLookupName() << 2; } // Try to recover by calling this function. return true; } R.clear(); } return false; } /// Attempt to recover from ill-formed use of a non-dependent operator in a /// template, where the non-dependent operator was declared after the template /// was defined. /// /// Returns true if a viable candidate was found and a diagnostic was issued. static bool DiagnoseTwoPhaseOperatorLookup(Sema &SemaRef, OverloadedOperatorKind Op, SourceLocation OpLoc, ArrayRef Args) { DeclarationName OpName = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op); LookupResult R(SemaRef, OpName, OpLoc, Sema::LookupOperatorName); return DiagnoseTwoPhaseLookup(SemaRef, OpLoc, CXXScopeSpec(), R, OverloadCandidateSet::CSK_Operator, /*ExplicitTemplateArgs=*/nullptr, Args); } namespace { class BuildRecoveryCallExprRAII { Sema &SemaRef; public: BuildRecoveryCallExprRAII(Sema &S) : SemaRef(S) { assert(SemaRef.IsBuildingRecoveryCallExpr == false); SemaRef.IsBuildingRecoveryCallExpr = true; } ~BuildRecoveryCallExprRAII() { SemaRef.IsBuildingRecoveryCallExpr = false; } }; } /// Attempts to recover from a call where no functions were found. /// /// Returns true if new candidates were found. static ExprResult BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, MutableArrayRef Args, SourceLocation RParenLoc, bool EmptyLookup, bool AllowTypoCorrection) { // Do not try to recover if it is already building a recovery call. // This stops infinite loops for template instantiations like // // template auto foo(T t) -> decltype(foo(t)) {} // template auto foo(T t) -> decltype(foo(&t)) {} // if (SemaRef.IsBuildingRecoveryCallExpr) return ExprError(); BuildRecoveryCallExprRAII RCE(SemaRef); CXXScopeSpec SS; SS.Adopt(ULE->getQualifierLoc()); SourceLocation TemplateKWLoc = ULE->getTemplateKeywordLoc(); TemplateArgumentListInfo TABuffer; TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr; if (ULE->hasExplicitTemplateArgs()) { ULE->copyTemplateArgumentsInto(TABuffer); ExplicitTemplateArgs = &TABuffer; } LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(), Sema::LookupOrdinaryName); bool DoDiagnoseEmptyLookup = EmptyLookup; if (!DiagnoseTwoPhaseLookup( SemaRef, Fn->getExprLoc(), SS, R, OverloadCandidateSet::CSK_Normal, ExplicitTemplateArgs, Args, &DoDiagnoseEmptyLookup)) { NoTypoCorrectionCCC NoTypoValidator{}; FunctionCallFilterCCC FunctionCallValidator(SemaRef, Args.size(), ExplicitTemplateArgs != nullptr, dyn_cast(Fn)); CorrectionCandidateCallback &Validator = AllowTypoCorrection ? static_cast(FunctionCallValidator) : static_cast(NoTypoValidator); if (!DoDiagnoseEmptyLookup || SemaRef.DiagnoseEmptyLookup(S, SS, R, Validator, ExplicitTemplateArgs, Args)) return ExprError(); } assert(!R.empty() && "lookup results empty despite recovery"); // If recovery created an ambiguity, just bail out. if (R.isAmbiguous()) { R.suppressDiagnostics(); return ExprError(); } // Build an implicit member call if appropriate. Just drop the // casts and such from the call, we don't really care. ExprResult NewFn = ExprError(); if ((*R.begin())->isCXXClassMember()) NewFn = SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R, ExplicitTemplateArgs, S); else if (ExplicitTemplateArgs || TemplateKWLoc.isValid()) NewFn = SemaRef.BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, ExplicitTemplateArgs); else NewFn = SemaRef.BuildDeclarationNameExpr(SS, R, false); if (NewFn.isInvalid()) return ExprError(); // This shouldn't cause an infinite loop because we're giving it // an expression with viable lookup results, which should never // end up here. return SemaRef.BuildCallExpr(/*Scope*/ nullptr, NewFn.get(), LParenLoc, MultiExprArg(Args.data(), Args.size()), RParenLoc); } /// Constructs and populates an OverloadedCandidateSet from /// the given function. /// \returns true when an the ExprResult output parameter has been set. bool Sema::buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, MultiExprArg Args, SourceLocation RParenLoc, OverloadCandidateSet *CandidateSet, ExprResult *Result) { #ifndef NDEBUG if (ULE->requiresADL()) { // To do ADL, we must have found an unqualified name. assert(!ULE->getQualifier() && "qualified name with ADL"); // We don't perform ADL for implicit declarations of builtins. // Verify that this was correctly set up. FunctionDecl *F; if (ULE->decls_begin() != ULE->decls_end() && ULE->decls_begin() + 1 == ULE->decls_end() && (F = dyn_cast(*ULE->decls_begin())) && F->getBuiltinID() && F->isImplicit()) llvm_unreachable("performing ADL for builtin"); // We don't perform ADL in C. assert(getLangOpts().CPlusPlus && "ADL enabled in C"); } #endif UnbridgedCastsSet UnbridgedCasts; if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts)) { *Result = ExprError(); return true; } // Add the functions denoted by the callee to the set of candidate // functions, including those from argument-dependent lookup. AddOverloadedCallCandidates(ULE, Args, *CandidateSet); if (getLangOpts().MSVCCompat && CurContext->isDependentContext() && !isSFINAEContext() && (isa(CurContext) || isa(CurContext))) { OverloadCandidateSet::iterator Best; if (CandidateSet->empty() || CandidateSet->BestViableFunction(*this, Fn->getBeginLoc(), Best) == OR_No_Viable_Function) { // In Microsoft mode, if we are inside a template class member function // then create a type dependent CallExpr. The goal is to postpone name // lookup to instantiation time to be able to search into type dependent // base classes. CallExpr *CE = CallExpr::Create(Context, Fn, Args, Context.DependentTy, VK_RValue, RParenLoc); CE->setTypeDependent(true); CE->setValueDependent(true); CE->setInstantiationDependent(true); *Result = CE; return true; } } if (CandidateSet->empty()) return false; UnbridgedCasts.restore(); return false; } /// FinishOverloadedCallExpr - given an OverloadCandidateSet, builds and returns /// the completed call expression. If overload resolution fails, emits /// diagnostics and returns ExprError() static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig, OverloadCandidateSet *CandidateSet, OverloadCandidateSet::iterator *Best, OverloadingResult OverloadResult, bool AllowTypoCorrection) { if (CandidateSet->empty()) return BuildRecoveryCallExpr(SemaRef, S, Fn, ULE, LParenLoc, Args, RParenLoc, /*EmptyLookup=*/true, AllowTypoCorrection); switch (OverloadResult) { case OR_Success: { FunctionDecl *FDecl = (*Best)->Function; SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl); if (SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc())) return ExprError(); Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl); return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, RParenLoc, ExecConfig, /*IsExecConfig=*/false, (*Best)->IsADLCandidate); } case OR_No_Viable_Function: { // Try to recover by looking for viable functions which the user might // have meant to call. ExprResult Recovery = BuildRecoveryCallExpr(SemaRef, S, Fn, ULE, LParenLoc, Args, RParenLoc, /*EmptyLookup=*/false, AllowTypoCorrection); if (!Recovery.isInvalid()) return Recovery; // If the user passes in a function that we can't take the address of, we // generally end up emitting really bad error messages. Here, we attempt to // emit better ones. for (const Expr *Arg : Args) { if (!Arg->getType()->isFunctionType()) continue; if (auto *DRE = dyn_cast(Arg->IgnoreParenImpCasts())) { auto *FD = dyn_cast(DRE->getDecl()); if (FD && !SemaRef.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, Arg->getExprLoc())) return ExprError(); } } CandidateSet->NoteCandidates( PartialDiagnosticAt( Fn->getBeginLoc(), SemaRef.PDiag(diag::err_ovl_no_viable_function_in_call) << ULE->getName() << Fn->getSourceRange()), SemaRef, OCD_AllCandidates, Args); break; } case OR_Ambiguous: CandidateSet->NoteCandidates( PartialDiagnosticAt(Fn->getBeginLoc(), SemaRef.PDiag(diag::err_ovl_ambiguous_call) << ULE->getName() << Fn->getSourceRange()), SemaRef, OCD_AmbiguousCandidates, Args); break; case OR_Deleted: { CandidateSet->NoteCandidates( PartialDiagnosticAt(Fn->getBeginLoc(), SemaRef.PDiag(diag::err_ovl_deleted_call) << ULE->getName() << Fn->getSourceRange()), SemaRef, OCD_AllCandidates, Args); // We emitted an error for the unavailable/deleted function call but keep // the call in the AST. FunctionDecl *FDecl = (*Best)->Function; Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl); return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, RParenLoc, ExecConfig, /*IsExecConfig=*/false, (*Best)->IsADLCandidate); } } // Overload resolution failed. return ExprError(); } static void markUnaddressableCandidatesUnviable(Sema &S, OverloadCandidateSet &CS) { for (auto I = CS.begin(), E = CS.end(); I != E; ++I) { if (I->Viable && !S.checkAddressOfFunctionIsAvailable(I->Function, /*Complain=*/false)) { I->Viable = false; I->FailureKind = ovl_fail_addr_not_available; } } } /// BuildOverloadedCallExpr - Given the call expression that calls Fn /// (which eventually refers to the declaration Func) and the call /// arguments Args/NumArgs, attempt to resolve the function call down /// to a specific function. If overload resolution succeeds, returns /// the call expression produced by overload resolution. /// Otherwise, emits diagnostics and returns ExprError. ExprResult Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig, bool AllowTypoCorrection, bool CalleesAddressIsTaken) { OverloadCandidateSet CandidateSet(Fn->getExprLoc(), OverloadCandidateSet::CSK_Normal); ExprResult result; if (buildOverloadedCallSet(S, Fn, ULE, Args, LParenLoc, &CandidateSet, &result)) return result; // If the user handed us something like `(&Foo)(Bar)`, we need to ensure that // functions that aren't addressible are considered unviable. if (CalleesAddressIsTaken) markUnaddressableCandidatesUnviable(*this, CandidateSet); OverloadCandidateSet::iterator Best; OverloadingResult OverloadResult = CandidateSet.BestViableFunction(*this, Fn->getBeginLoc(), Best); return FinishOverloadedCallExpr(*this, S, Fn, ULE, LParenLoc, Args, RParenLoc, ExecConfig, &CandidateSet, &Best, OverloadResult, AllowTypoCorrection); } static bool IsOverloaded(const UnresolvedSetImpl &Functions) { return Functions.size() > 1 || (Functions.size() == 1 && isa(*Functions.begin())); } /// Create a unary operation that may resolve to an overloaded /// operator. /// /// \param OpLoc The location of the operator itself (e.g., '*'). /// /// \param Opc The UnaryOperatorKind that describes this operator. /// /// \param Fns The set of non-member functions that will be /// considered by overload resolution. The caller needs to build this /// set based on the context using, e.g., /// LookupOverloadedOperatorName() and ArgumentDependentLookup(). This /// set should not contain any member functions; those will be added /// by CreateOverloadedUnaryOp(). /// /// \param Input The input argument. ExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *Input, bool PerformADL) { OverloadedOperatorKind Op = UnaryOperator::getOverloadedOperator(Opc); assert(Op != OO_None && "Invalid opcode for overloaded unary operator"); DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); // TODO: provide better source location info. DeclarationNameInfo OpNameInfo(OpName, OpLoc); if (checkPlaceholderForOverload(*this, Input)) return ExprError(); Expr *Args[2] = { Input, nullptr }; unsigned NumArgs = 1; // For post-increment and post-decrement, add the implicit '0' as // the second argument, so that we know this is a post-increment or // post-decrement. if (Opc == UO_PostInc || Opc == UO_PostDec) { llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false); Args[1] = IntegerLiteral::Create(Context, Zero, Context.IntTy, SourceLocation()); NumArgs = 2; } ArrayRef ArgsArray(Args, NumArgs); if (Input->isTypeDependent()) { if (Fns.empty()) return new (Context) UnaryOperator(Input, Opc, Context.DependentTy, VK_RValue, OK_Ordinary, OpLoc, false); CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create( Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); return CXXOperatorCallExpr::Create(Context, Op, Fn, ArgsArray, Context.DependentTy, VK_RValue, OpLoc, FPOptions()); } // Build an empty overload set. OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator); // Add the candidates from the given function set. AddNonMemberOperatorCandidates(Fns, ArgsArray, CandidateSet); // Add operator candidates that are member functions. AddMemberOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); // Add candidates from ADL. if (PerformADL) { AddArgumentDependentLookupCandidates(OpName, OpLoc, ArgsArray, /*ExplicitTemplateArgs*/nullptr, CandidateSet); } // Add builtin operator candidates. AddBuiltinOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) { case OR_Success: { // We found a built-in operator or an overloaded operator. FunctionDecl *FnDecl = Best->Function; if (FnDecl) { Expr *Base = nullptr; // We matched an overloaded operator. Build a call to that // operator. // Convert the arguments. if (CXXMethodDecl *Method = dyn_cast(FnDecl)) { CheckMemberOperatorAccess(OpLoc, Args[0], nullptr, Best->FoundDecl); ExprResult InputRes = PerformObjectArgumentInitialization(Input, /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (InputRes.isInvalid()) return ExprError(); Base = Input = InputRes.get(); } else { // Convert the arguments. ExprResult InputInit = PerformCopyInitialization(InitializedEntity::InitializeParameter( Context, FnDecl->getParamDecl(0)), SourceLocation(), Input); if (InputInit.isInvalid()) return ExprError(); Input = InputInit.get(); } // Build the actual expression node. ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, Best->FoundDecl, Base, HadMultipleCandidates, OpLoc); if (FnExpr.isInvalid()) return ExprError(); // Determine the result type. QualType ResultTy = FnDecl->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); Args[0] = Input; CallExpr *TheCall = CXXOperatorCallExpr::Create( Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc, FPOptions(), Best->IsADLCandidate); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) return ExprError(); if (CheckFunctionCall(FnDecl, TheCall, FnDecl->getType()->castAs())) return ExprError(); return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in // operator node. ExprResult InputRes = PerformImplicitConversion( Input, Best->BuiltinParamTypes[0], Best->Conversions[0], AA_Passing, CCK_ForBuiltinOverloadedOp); if (InputRes.isInvalid()) return ExprError(); Input = InputRes.get(); break; } } case OR_No_Viable_Function: // This is an erroneous use of an operator which can be overloaded by // a non-member function. Check for non-member operators which were // defined too late to be candidates. if (DiagnoseTwoPhaseOperatorLookup(*this, Op, OpLoc, ArgsArray)) // FIXME: Recover by calling the found function. return ExprError(); // No viable function; fall through to handling this as a // built-in operator, which will produce an error message for us. break; case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_unary) << UnaryOperator::getOpcodeStr(Opc) << Input->getType() << Input->getSourceRange()), *this, OCD_AmbiguousCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper) << UnaryOperator::getOpcodeStr(Opc) << Input->getSourceRange()), *this, OCD_AllCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); } // Either we found no viable overloaded operator or we matched a // built-in operator. In either case, fall through to trying to // build a built-in operation. return CreateBuiltinUnaryOp(OpLoc, Opc, Input); } /// Perform lookup for an overloaded binary operator. void Sema::LookupOverloadedBinOp(OverloadCandidateSet &CandidateSet, OverloadedOperatorKind Op, const UnresolvedSetImpl &Fns, ArrayRef Args, bool PerformADL) { SourceLocation OpLoc = CandidateSet.getLocation(); OverloadedOperatorKind ExtraOp = CandidateSet.getRewriteInfo().AllowRewrittenCandidates ? getRewrittenOverloadedOperator(Op) : OO_None; // Add the candidates from the given function set. This also adds the // rewritten candidates using these functions if necessary. AddNonMemberOperatorCandidates(Fns, Args, CandidateSet); // Add operator candidates that are member functions. AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet); if (CandidateSet.getRewriteInfo().shouldAddReversed(Op)) AddMemberOperatorCandidates(Op, OpLoc, {Args[1], Args[0]}, CandidateSet, OverloadCandidateParamOrder::Reversed); // In C++20, also add any rewritten member candidates. if (ExtraOp) { AddMemberOperatorCandidates(ExtraOp, OpLoc, Args, CandidateSet); if (CandidateSet.getRewriteInfo().shouldAddReversed(ExtraOp)) AddMemberOperatorCandidates(ExtraOp, OpLoc, {Args[1], Args[0]}, CandidateSet, OverloadCandidateParamOrder::Reversed); } // Add candidates from ADL. Per [over.match.oper]p2, this lookup is not // performed for an assignment operator (nor for operator[] nor operator->, // which don't get here). if (Op != OO_Equal && PerformADL) { DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); AddArgumentDependentLookupCandidates(OpName, OpLoc, Args, /*ExplicitTemplateArgs*/ nullptr, CandidateSet); if (ExtraOp) { DeclarationName ExtraOpName = Context.DeclarationNames.getCXXOperatorName(ExtraOp); AddArgumentDependentLookupCandidates(ExtraOpName, OpLoc, Args, /*ExplicitTemplateArgs*/ nullptr, CandidateSet); } } // Add builtin operator candidates. // // FIXME: We don't add any rewritten candidates here. This is strictly // incorrect; a builtin candidate could be hidden by a non-viable candidate, // resulting in our selecting a rewritten builtin candidate. For example: // // enum class E { e }; // bool operator!=(E, E) requires false; // bool k = E::e != E::e; // // ... should select the rewritten builtin candidate 'operator==(E, E)'. But // it seems unreasonable to consider rewritten builtin candidates. A core // issue has been filed proposing to removed this requirement. AddBuiltinOperatorCandidates(Op, OpLoc, Args, CandidateSet); } /// Create a binary operation that may resolve to an overloaded /// operator. /// /// \param OpLoc The location of the operator itself (e.g., '+'). /// /// \param Opc The BinaryOperatorKind that describes this operator. /// /// \param Fns The set of non-member functions that will be /// considered by overload resolution. The caller needs to build this /// set based on the context using, e.g., /// LookupOverloadedOperatorName() and ArgumentDependentLookup(). This /// set should not contain any member functions; those will be added /// by CreateOverloadedBinOp(). /// /// \param LHS Left-hand argument. /// \param RHS Right-hand argument. /// \param PerformADL Whether to consider operator candidates found by ADL. /// \param AllowRewrittenCandidates Whether to consider candidates found by /// C++20 operator rewrites. /// \param DefaultedFn If we are synthesizing a defaulted operator function, /// the function in question. Such a function is never a candidate in /// our overload resolution. This also enables synthesizing a three-way /// comparison from < and == as described in C++20 [class.spaceship]p1. ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *LHS, Expr *RHS, bool PerformADL, bool AllowRewrittenCandidates, FunctionDecl *DefaultedFn) { Expr *Args[2] = { LHS, RHS }; LHS=RHS=nullptr; // Please use only Args instead of LHS/RHS couple if (!getLangOpts().CPlusPlus2a) AllowRewrittenCandidates = false; OverloadedOperatorKind Op = BinaryOperator::getOverloadedOperator(Opc); // If either side is type-dependent, create an appropriate dependent // expression. if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) { if (Fns.empty()) { // If there are no functions to store, just build a dependent // BinaryOperator or CompoundAssignment. if (Opc <= BO_Assign || Opc > BO_OrAssign) return new (Context) BinaryOperator( Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary, OpLoc, FPFeatures); return new (Context) CompoundAssignOperator( Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, OK_Ordinary, Context.DependentTy, Context.DependentTy, OpLoc, FPFeatures); } // FIXME: save results of ADL from here? CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators // TODO: provide better source location info in DNLoc component. DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); DeclarationNameInfo OpNameInfo(OpName, OpLoc); UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create( Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ PerformADL, IsOverloaded(Fns), Fns.begin(), Fns.end()); return CXXOperatorCallExpr::Create(Context, Op, Fn, Args, Context.DependentTy, VK_RValue, OpLoc, FPFeatures); } // Always do placeholder-like conversions on the RHS. if (checkPlaceholderForOverload(*this, Args[1])) return ExprError(); // Do placeholder-like conversion on the LHS; note that we should // not get here with a PseudoObject LHS. assert(Args[0]->getObjectKind() != OK_ObjCProperty); if (checkPlaceholderForOverload(*this, Args[0])) return ExprError(); // If this is the assignment operator, we only perform overload resolution // if the left-hand side is a class or enumeration type. This is actually // a hack. The standard requires that we do overload resolution between the // various built-in candidates, but as DR507 points out, this can lead to // problems. So we do it this way, which pretty much follows what GCC does. // Note that we go the traditional code path for compound assignment forms. if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType()) return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); // If this is the .* operator, which is not overloadable, just // create a built-in binary operator. if (Opc == BO_PtrMemD) return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); // Build the overload set. OverloadCandidateSet CandidateSet( OpLoc, OverloadCandidateSet::CSK_Operator, OverloadCandidateSet::OperatorRewriteInfo(Op, AllowRewrittenCandidates)); if (DefaultedFn) CandidateSet.exclude(DefaultedFn); LookupOverloadedBinOp(CandidateSet, Op, Fns, Args, PerformADL); bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) { case OR_Success: { // We found a built-in operator or an overloaded operator. FunctionDecl *FnDecl = Best->Function; bool IsReversed = (Best->RewriteKind & CRK_Reversed); if (IsReversed) std::swap(Args[0], Args[1]); if (FnDecl) { Expr *Base = nullptr; // We matched an overloaded operator. Build a call to that // operator. OverloadedOperatorKind ChosenOp = FnDecl->getDeclName().getCXXOverloadedOperator(); // C++2a [over.match.oper]p9: // If a rewritten operator== candidate is selected by overload // resolution for an operator@, its return type shall be cv bool if (Best->RewriteKind && ChosenOp == OO_EqualEqual && !FnDecl->getReturnType()->isBooleanType()) { Diag(OpLoc, diag::err_ovl_rewrite_equalequal_not_bool) << FnDecl->getReturnType() << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getSourceRange() << Args[1]->getSourceRange(); Diag(FnDecl->getLocation(), diag::note_declared_at); return ExprError(); } if (AllowRewrittenCandidates && !IsReversed && CandidateSet.getRewriteInfo().shouldAddReversed(ChosenOp)) { // We could have reversed this operator, but didn't. Check if the // reversed form was a viable candidate, and if so, if it had a // better conversion for either parameter. If so, this call is // formally ambiguous, and allowing it is an extension. for (OverloadCandidate &Cand : CandidateSet) { if (Cand.Viable && Cand.Function == FnDecl && Cand.RewriteKind & CRK_Reversed) { for (unsigned ArgIdx = 0; ArgIdx < 2; ++ArgIdx) { if (CompareImplicitConversionSequences( *this, OpLoc, Cand.Conversions[ArgIdx], Best->Conversions[ArgIdx]) == ImplicitConversionSequence::Better) { Diag(OpLoc, diag::ext_ovl_ambiguous_oper_binary_reversed) << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getType() << Args[1]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange(); Diag(FnDecl->getLocation(), diag::note_ovl_ambiguous_oper_binary_reversed_candidate); } } break; } } } // Convert the arguments. if (CXXMethodDecl *Method = dyn_cast(FnDecl)) { // Best->Access is only meaningful for class members. CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Best->FoundDecl); ExprResult Arg1 = PerformCopyInitialization( InitializedEntity::InitializeParameter(Context, FnDecl->getParamDecl(0)), SourceLocation(), Args[1]); if (Arg1.isInvalid()) return ExprError(); ExprResult Arg0 = PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (Arg0.isInvalid()) return ExprError(); Base = Args[0] = Arg0.getAs(); Args[1] = RHS = Arg1.getAs(); } else { // Convert the arguments. ExprResult Arg0 = PerformCopyInitialization( InitializedEntity::InitializeParameter(Context, FnDecl->getParamDecl(0)), SourceLocation(), Args[0]); if (Arg0.isInvalid()) return ExprError(); ExprResult Arg1 = PerformCopyInitialization( InitializedEntity::InitializeParameter(Context, FnDecl->getParamDecl(1)), SourceLocation(), Args[1]); if (Arg1.isInvalid()) return ExprError(); Args[0] = LHS = Arg0.getAs(); Args[1] = RHS = Arg1.getAs(); } // Build the actual expression node. ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, Best->FoundDecl, Base, HadMultipleCandidates, OpLoc); if (FnExpr.isInvalid()) return ExprError(); // Determine the result type. QualType ResultTy = FnDecl->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( Context, ChosenOp, FnExpr.get(), Args, ResultTy, VK, OpLoc, FPFeatures, Best->IsADLCandidate); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) return ExprError(); ArrayRef ArgsArray(Args, 2); const Expr *ImplicitThis = nullptr; // Cut off the implicit 'this'. if (isa(FnDecl)) { ImplicitThis = ArgsArray[0]; ArgsArray = ArgsArray.slice(1); } // Check for a self move. if (Op == OO_Equal) DiagnoseSelfMove(Args[0], Args[1], OpLoc); checkCall(FnDecl, nullptr, ImplicitThis, ArgsArray, isa(FnDecl), OpLoc, TheCall->getSourceRange(), VariadicDoesNotApply); ExprResult R = MaybeBindToTemporary(TheCall); if (R.isInvalid()) return ExprError(); // For a rewritten candidate, we've already reversed the arguments // if needed. Perform the rest of the rewrite now. if ((Best->RewriteKind & CRK_DifferentOperator) || (Op == OO_Spaceship && IsReversed)) { if (Op == OO_ExclaimEqual) { assert(ChosenOp == OO_EqualEqual && "unexpected operator name"); R = CreateBuiltinUnaryOp(OpLoc, UO_LNot, R.get()); } else { assert(ChosenOp == OO_Spaceship && "unexpected operator name"); llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false); Expr *ZeroLiteral = IntegerLiteral::Create(Context, Zero, Context.IntTy, OpLoc); Sema::CodeSynthesisContext Ctx; Ctx.Kind = Sema::CodeSynthesisContext::RewritingOperatorAsSpaceship; Ctx.Entity = FnDecl; pushCodeSynthesisContext(Ctx); R = CreateOverloadedBinOp( OpLoc, Opc, Fns, IsReversed ? ZeroLiteral : R.get(), IsReversed ? R.get() : ZeroLiteral, PerformADL, /*AllowRewrittenCandidates=*/false); popCodeSynthesisContext(); } if (R.isInvalid()) return ExprError(); } else { assert(ChosenOp == Op && "unexpected operator name"); } // Make a note in the AST if we did any rewriting. if (Best->RewriteKind != CRK_None) R = new (Context) CXXRewrittenBinaryOperator(R.get(), IsReversed); return R; } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in // operator node. ExprResult ArgsRes0 = PerformImplicitConversion( Args[0], Best->BuiltinParamTypes[0], Best->Conversions[0], AA_Passing, CCK_ForBuiltinOverloadedOp); if (ArgsRes0.isInvalid()) return ExprError(); Args[0] = ArgsRes0.get(); ExprResult ArgsRes1 = PerformImplicitConversion( Args[1], Best->BuiltinParamTypes[1], Best->Conversions[1], AA_Passing, CCK_ForBuiltinOverloadedOp); if (ArgsRes1.isInvalid()) return ExprError(); Args[1] = ArgsRes1.get(); break; } } case OR_No_Viable_Function: { // C++ [over.match.oper]p9: // If the operator is the operator , [...] and there are no // viable functions, then the operator is assumed to be the // built-in operator and interpreted according to clause 5. if (Opc == BO_Comma) break; // When defaulting an 'operator<=>', we can try to synthesize a three-way // compare result using '==' and '<'. if (DefaultedFn && Opc == BO_Cmp) { ExprResult E = BuildSynthesizedThreeWayComparison(OpLoc, Fns, Args[0], Args[1], DefaultedFn); if (E.isInvalid() || E.isUsable()) return E; } // For class as left operand for assignment or compound assignment // operator do not fall through to handling in built-in, but report that // no overloaded assignment operator found ExprResult Result = ExprError(); StringRef OpcStr = BinaryOperator::getOpcodeStr(Opc); auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates, Args, OpLoc); if (Args[0]->getType()->isRecordType() && Opc >= BO_Assign && Opc <= BO_OrAssign) { Diag(OpLoc, diag::err_ovl_no_viable_oper) << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getSourceRange() << Args[1]->getSourceRange(); if (Args[0]->getType()->isIncompleteType()) { Diag(OpLoc, diag::note_assign_lhs_incomplete) << Args[0]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange(); } } else { // This is an erroneous use of an operator which can be overloaded by // a non-member function. Check for non-member operators which were // defined too late to be candidates. if (DiagnoseTwoPhaseOperatorLookup(*this, Op, OpLoc, Args)) // FIXME: Recover by calling the found function. return ExprError(); // No viable function; try to create a built-in operation, which will // produce an error. Then, show the non-viable candidates. Result = CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); } assert(Result.isInvalid() && "C++ binary operator overloading is missing candidates!"); CandidateSet.NoteCandidates(*this, Args, Cands, OpcStr, OpLoc); return Result; } case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_binary) << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getType() << Args[1]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange()), *this, OCD_AmbiguousCandidates, Args, BinaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); case OR_Deleted: if (isImplicitlyDeleted(Best->Function)) { FunctionDecl *DeletedFD = Best->Function; DefaultedFunctionKind DFK = getDefaultedFunctionKind(DeletedFD); if (DFK.isSpecialMember()) { Diag(OpLoc, diag::err_ovl_deleted_special_oper) << Args[0]->getType() << DFK.asSpecialMember(); } else { assert(DFK.isComparison()); Diag(OpLoc, diag::err_ovl_deleted_comparison) << Args[0]->getType() << DeletedFD; } // The user probably meant to call this special member. Just // explain why it's deleted. NoteDeletedFunction(DeletedFD); return ExprError(); } CandidateSet.NoteCandidates( PartialDiagnosticAt( OpLoc, PDiag(diag::err_ovl_deleted_oper) << getOperatorSpelling(Best->Function->getDeclName() .getCXXOverloadedOperator()) << Args[0]->getSourceRange() << Args[1]->getSourceRange()), *this, OCD_AllCandidates, Args, BinaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); } // We matched a built-in operator; build it. return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); } ExprResult Sema::BuildSynthesizedThreeWayComparison( SourceLocation OpLoc, const UnresolvedSetImpl &Fns, Expr *LHS, Expr *RHS, FunctionDecl *DefaultedFn) { const ComparisonCategoryInfo *Info = Context.CompCategories.lookupInfoForType(DefaultedFn->getReturnType()); // If we're not producing a known comparison category type, we can't // synthesize a three-way comparison. Let the caller diagnose this. if (!Info) return ExprResult((Expr*)nullptr); // If we ever want to perform this synthesis more generally, we will need to // apply the temporary materialization conversion to the operands. assert(LHS->isGLValue() && RHS->isGLValue() && "cannot use prvalue expressions more than once"); Expr *OrigLHS = LHS; Expr *OrigRHS = RHS; // Replace the LHS and RHS with OpaqueValueExprs; we're going to refer to // each of them multiple times below. LHS = new (Context) OpaqueValueExpr(LHS->getExprLoc(), LHS->getType(), LHS->getValueKind(), LHS->getObjectKind(), LHS); RHS = new (Context) OpaqueValueExpr(RHS->getExprLoc(), RHS->getType(), RHS->getValueKind(), RHS->getObjectKind(), RHS); ExprResult Eq = CreateOverloadedBinOp(OpLoc, BO_EQ, Fns, LHS, RHS, true, true, DefaultedFn); if (Eq.isInvalid()) return ExprError(); ExprResult Less = CreateOverloadedBinOp(OpLoc, BO_LT, Fns, LHS, RHS, true, true, DefaultedFn); if (Less.isInvalid()) return ExprError(); ExprResult Greater; if (Info->isPartial()) { Greater = CreateOverloadedBinOp(OpLoc, BO_LT, Fns, RHS, LHS, true, true, DefaultedFn); if (Greater.isInvalid()) return ExprError(); } // Form the list of comparisons we're going to perform. struct Comparison { ExprResult Cmp; ComparisonCategoryResult Result; } Comparisons[4] = { {Eq, Info->isStrong() ? ComparisonCategoryResult::Equal : ComparisonCategoryResult::Equivalent}, {Less, ComparisonCategoryResult::Less}, {Greater, ComparisonCategoryResult::Greater}, {ExprResult(), ComparisonCategoryResult::Unordered}, }; int I = Info->isPartial() ? 3 : 2; // Combine the comparisons with suitable conditional expressions. ExprResult Result; for (; I >= 0; --I) { // Build a reference to the comparison category constant. auto *VI = Info->lookupValueInfo(Comparisons[I].Result); // FIXME: Missing a constant for a comparison category. Diagnose this? if (!VI) return ExprResult((Expr*)nullptr); ExprResult ThisResult = BuildDeclarationNameExpr(CXXScopeSpec(), DeclarationNameInfo(), VI->VD); if (ThisResult.isInvalid()) return ExprError(); // Build a conditional unless this is the final case. if (Result.get()) { Result = ActOnConditionalOp(OpLoc, OpLoc, Comparisons[I].Cmp.get(), ThisResult.get(), Result.get()); if (Result.isInvalid()) return ExprError(); } else { Result = ThisResult; } } // Build a PseudoObjectExpr to model the rewriting of an <=> operator, and to // bind the OpaqueValueExprs before they're (repeatedly) used. Expr *SyntacticForm = new (Context) BinaryOperator(OrigLHS, OrigRHS, BO_Cmp, Result.get()->getType(), Result.get()->getValueKind(), Result.get()->getObjectKind(), OpLoc, FPFeatures); Expr *SemanticForm[] = {LHS, RHS, Result.get()}; return PseudoObjectExpr::Create(Context, SyntacticForm, SemanticForm, 2); } ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, SourceLocation RLoc, Expr *Base, Expr *Idx) { Expr *Args[2] = { Base, Idx }; DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Subscript); // If either side is type-dependent, create an appropriate dependent // expression. if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) { CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators // CHECKME: no 'operator' keyword? DeclarationNameInfo OpNameInfo(OpName, LLoc); OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc)); UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create(Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ true, /*Overloaded*/ false, UnresolvedSetIterator(), UnresolvedSetIterator()); // Can't add any actual overloads yet return CXXOperatorCallExpr::Create(Context, OO_Subscript, Fn, Args, Context.DependentTy, VK_RValue, RLoc, FPOptions()); } // Handle placeholders on both operands. if (checkPlaceholderForOverload(*this, Args[0])) return ExprError(); if (checkPlaceholderForOverload(*this, Args[1])) return ExprError(); // Build an empty overload set. OverloadCandidateSet CandidateSet(LLoc, OverloadCandidateSet::CSK_Operator); // Subscript can only be overloaded as a member function. // Add operator candidates that are member functions. AddMemberOperatorCandidates(OO_Subscript, LLoc, Args, CandidateSet); // Add builtin operator candidates. AddBuiltinOperatorCandidates(OO_Subscript, LLoc, Args, CandidateSet); bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, LLoc, Best)) { case OR_Success: { // We found a built-in operator or an overloaded operator. FunctionDecl *FnDecl = Best->Function; if (FnDecl) { // We matched an overloaded operator. Build a call to that // operator. CheckMemberOperatorAccess(LLoc, Args[0], Args[1], Best->FoundDecl); // Convert the arguments. CXXMethodDecl *Method = cast(FnDecl); ExprResult Arg0 = PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (Arg0.isInvalid()) return ExprError(); Args[0] = Arg0.get(); // Convert the arguments. ExprResult InputInit = PerformCopyInitialization(InitializedEntity::InitializeParameter( Context, FnDecl->getParamDecl(0)), SourceLocation(), Args[1]); if (InputInit.isInvalid()) return ExprError(); Args[1] = InputInit.getAs(); // Build the actual expression node. DeclarationNameInfo OpLocInfo(OpName, LLoc); OpLocInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc)); ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, Best->FoundDecl, Base, HadMultipleCandidates, OpLocInfo.getLoc(), OpLocInfo.getInfo()); if (FnExpr.isInvalid()) return ExprError(); // Determine the result type QualType ResultTy = FnDecl->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(Context, OO_Subscript, FnExpr.get(), Args, ResultTy, VK, RLoc, FPOptions()); if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl)) return ExprError(); if (CheckFunctionCall(Method, TheCall, Method->getType()->castAs())) return ExprError(); return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in // operator node. ExprResult ArgsRes0 = PerformImplicitConversion( Args[0], Best->BuiltinParamTypes[0], Best->Conversions[0], AA_Passing, CCK_ForBuiltinOverloadedOp); if (ArgsRes0.isInvalid()) return ExprError(); Args[0] = ArgsRes0.get(); ExprResult ArgsRes1 = PerformImplicitConversion( Args[1], Best->BuiltinParamTypes[1], Best->Conversions[1], AA_Passing, CCK_ForBuiltinOverloadedOp); if (ArgsRes1.isInvalid()) return ExprError(); Args[1] = ArgsRes1.get(); break; } } case OR_No_Viable_Function: { PartialDiagnostic PD = CandidateSet.empty() ? (PDiag(diag::err_ovl_no_oper) << Args[0]->getType() << /*subscript*/ 0 << Args[0]->getSourceRange() << Args[1]->getSourceRange()) : (PDiag(diag::err_ovl_no_viable_subscript) << Args[0]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange()); CandidateSet.NoteCandidates(PartialDiagnosticAt(LLoc, PD), *this, OCD_AllCandidates, Args, "[]", LLoc); return ExprError(); } case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(LLoc, PDiag(diag::err_ovl_ambiguous_oper_binary) << "[]" << Args[0]->getType() << Args[1]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange()), *this, OCD_AmbiguousCandidates, Args, "[]", LLoc); return ExprError(); case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(LLoc, PDiag(diag::err_ovl_deleted_oper) << "[]" << Args[0]->getSourceRange() << Args[1]->getSourceRange()), *this, OCD_AllCandidates, Args, "[]", LLoc); return ExprError(); } // We matched a built-in operator; build it. return CreateBuiltinArraySubscriptExpr(Args[0], LLoc, Args[1], RLoc); } /// BuildCallToMemberFunction - Build a call to a member /// function. MemExpr is the expression that refers to the member /// function (and includes the object parameter), Args/NumArgs are the /// arguments to the function call (not including the object /// parameter). The caller needs to validate that the member /// expression refers to a non-static member function or an overloaded /// member function. ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc) { assert(MemExprE->getType() == Context.BoundMemberTy || MemExprE->getType() == Context.OverloadTy); // Dig out the member expression. This holds both the object // argument and the member function we're referring to. Expr *NakedMemExpr = MemExprE->IgnoreParens(); // Determine whether this is a call to a pointer-to-member function. if (BinaryOperator *op = dyn_cast(NakedMemExpr)) { assert(op->getType() == Context.BoundMemberTy); assert(op->getOpcode() == BO_PtrMemD || op->getOpcode() == BO_PtrMemI); QualType fnType = op->getRHS()->getType()->castAs()->getPointeeType(); const FunctionProtoType *proto = fnType->castAs(); QualType resultType = proto->getCallResultType(Context); ExprValueKind valueKind = Expr::getValueKindForType(proto->getReturnType()); // Check that the object type isn't more qualified than the // member function we're calling. Qualifiers funcQuals = proto->getMethodQuals(); QualType objectType = op->getLHS()->getType(); if (op->getOpcode() == BO_PtrMemI) objectType = objectType->castAs()->getPointeeType(); Qualifiers objectQuals = objectType.getQualifiers(); Qualifiers difference = objectQuals - funcQuals; difference.removeObjCGCAttr(); difference.removeAddressSpace(); if (difference) { std::string qualsString = difference.getAsString(); Diag(LParenLoc, diag::err_pointer_to_member_call_drops_quals) << fnType.getUnqualifiedType() << qualsString << (qualsString.find(' ') == std::string::npos ? 1 : 2); } CXXMemberCallExpr *call = CXXMemberCallExpr::Create(Context, MemExprE, Args, resultType, valueKind, RParenLoc, proto->getNumParams()); if (CheckCallReturnType(proto->getReturnType(), op->getRHS()->getBeginLoc(), call, nullptr)) return ExprError(); if (ConvertArgumentsForCall(call, op, nullptr, proto, Args, RParenLoc)) return ExprError(); if (CheckOtherCall(call, proto)) return ExprError(); return MaybeBindToTemporary(call); } if (isa(NakedMemExpr)) return CallExpr::Create(Context, MemExprE, Args, Context.VoidTy, VK_RValue, RParenLoc); UnbridgedCastsSet UnbridgedCasts; if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts)) return ExprError(); MemberExpr *MemExpr; CXXMethodDecl *Method = nullptr; DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_public); NestedNameSpecifier *Qualifier = nullptr; if (isa(NakedMemExpr)) { MemExpr = cast(NakedMemExpr); Method = cast(MemExpr->getMemberDecl()); FoundDecl = MemExpr->getFoundDecl(); Qualifier = MemExpr->getQualifier(); UnbridgedCasts.restore(); } else { UnresolvedMemberExpr *UnresExpr = cast(NakedMemExpr); Qualifier = UnresExpr->getQualifier(); QualType ObjectType = UnresExpr->getBaseType(); Expr::Classification ObjectClassification = UnresExpr->isArrow()? Expr::Classification::makeSimpleLValue() : UnresExpr->getBase()->Classify(Context); // Add overload candidates OverloadCandidateSet CandidateSet(UnresExpr->getMemberLoc(), OverloadCandidateSet::CSK_Normal); // FIXME: avoid copy. TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr; if (UnresExpr->hasExplicitTemplateArgs()) { UnresExpr->copyTemplateArgumentsInto(TemplateArgsBuffer); TemplateArgs = &TemplateArgsBuffer; } for (UnresolvedMemberExpr::decls_iterator I = UnresExpr->decls_begin(), E = UnresExpr->decls_end(); I != E; ++I) { NamedDecl *Func = *I; CXXRecordDecl *ActingDC = cast(Func->getDeclContext()); if (isa(Func)) Func = cast(Func)->getTargetDecl(); // Microsoft supports direct constructor calls. if (getLangOpts().MicrosoftExt && isa(Func)) { AddOverloadCandidate(cast(Func), I.getPair(), Args, CandidateSet, /*SuppressUserConversions*/ false); } else if ((Method = dyn_cast(Func))) { // If explicit template arguments were provided, we can't call a // non-template member function. if (TemplateArgs) continue; AddMethodCandidate(Method, I.getPair(), ActingDC, ObjectType, ObjectClassification, Args, CandidateSet, /*SuppressUserConversions=*/false); } else { AddMethodTemplateCandidate( cast(Func), I.getPair(), ActingDC, TemplateArgs, ObjectType, ObjectClassification, Args, CandidateSet, /*SuppressUserConversions=*/false); } } DeclarationName DeclName = UnresExpr->getMemberName(); UnbridgedCasts.restore(); OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, UnresExpr->getBeginLoc(), Best)) { case OR_Success: Method = cast(Best->Function); FoundDecl = Best->FoundDecl; CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl); if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc())) return ExprError(); // If FoundDecl is different from Method (such as if one is a template // and the other a specialization), make sure DiagnoseUseOfDecl is // called on both. // FIXME: This would be more comprehensively addressed by modifying // DiagnoseUseOfDecl to accept both the FoundDecl and the decl // being used. if (Method != FoundDecl.getDecl() && DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc())) return ExprError(); break; case OR_No_Viable_Function: CandidateSet.NoteCandidates( PartialDiagnosticAt( UnresExpr->getMemberLoc(), PDiag(diag::err_ovl_no_viable_member_function_in_call) << DeclName << MemExprE->getSourceRange()), *this, OCD_AllCandidates, Args); // FIXME: Leaking incoming expressions! return ExprError(); case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(UnresExpr->getMemberLoc(), PDiag(diag::err_ovl_ambiguous_member_call) << DeclName << MemExprE->getSourceRange()), *this, OCD_AmbiguousCandidates, Args); // FIXME: Leaking incoming expressions! return ExprError(); case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(UnresExpr->getMemberLoc(), PDiag(diag::err_ovl_deleted_member_call) << DeclName << MemExprE->getSourceRange()), *this, OCD_AllCandidates, Args); // FIXME: Leaking incoming expressions! return ExprError(); } MemExprE = FixOverloadedFunctionReference(MemExprE, FoundDecl, Method); // If overload resolution picked a static member, build a // non-member call based on that function. if (Method->isStatic()) { return BuildResolvedCallExpr(MemExprE, Method, LParenLoc, Args, RParenLoc); } MemExpr = cast(MemExprE->IgnoreParens()); } QualType ResultType = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultType); ResultType = ResultType.getNonLValueExprType(Context); assert(Method && "Member call to something that isn't a method?"); const auto *Proto = Method->getType()->castAs(); CXXMemberCallExpr *TheCall = CXXMemberCallExpr::Create(Context, MemExprE, Args, ResultType, VK, RParenLoc, Proto->getNumParams()); // Check for a valid return type. if (CheckCallReturnType(Method->getReturnType(), MemExpr->getMemberLoc(), TheCall, Method)) return ExprError(); // Convert the object argument (for a non-static member function call). // We only need to do this if there was actually an overload; otherwise // it was done at lookup. if (!Method->isStatic()) { ExprResult ObjectArg = PerformObjectArgumentInitialization(MemExpr->getBase(), Qualifier, FoundDecl, Method); if (ObjectArg.isInvalid()) return ExprError(); MemExpr->setBase(ObjectArg.get()); } // Convert the rest of the arguments if (ConvertArgumentsForCall(TheCall, MemExpr, Method, Proto, Args, RParenLoc)) return ExprError(); DiagnoseSentinelCalls(Method, LParenLoc, Args); if (CheckFunctionCall(Method, TheCall, Proto)) return ExprError(); // In the case the method to call was not selected by the overloading // resolution process, we still need to handle the enable_if attribute. Do // that here, so it will not hide previous -- and more relevant -- errors. if (auto *MemE = dyn_cast(NakedMemExpr)) { if (const EnableIfAttr *Attr = CheckEnableIf(Method, Args, true)) { Diag(MemE->getMemberLoc(), diag::err_ovl_no_viable_member_function_in_call) << Method << Method->getSourceRange(); Diag(Method->getLocation(), diag::note_ovl_candidate_disabled_by_function_cond_attr) << Attr->getCond()->getSourceRange() << Attr->getMessage(); return ExprError(); } } if ((isa(CurContext) || isa(CurContext)) && TheCall->getMethodDecl()->isPure()) { const CXXMethodDecl *MD = TheCall->getMethodDecl(); if (isa(MemExpr->getBase()->IgnoreParenCasts()) && MemExpr->performsVirtualDispatch(getLangOpts())) { Diag(MemExpr->getBeginLoc(), diag::warn_call_to_pure_virtual_member_function_from_ctor_dtor) << MD->getDeclName() << isa(CurContext) << MD->getParent()->getDeclName(); Diag(MD->getBeginLoc(), diag::note_previous_decl) << MD->getDeclName(); if (getLangOpts().AppleKext) Diag(MemExpr->getBeginLoc(), diag::note_pure_qualified_call_kext) << MD->getParent()->getDeclName() << MD->getDeclName(); } } if (CXXDestructorDecl *DD = dyn_cast(TheCall->getMethodDecl())) { // a->A::f() doesn't go through the vtable, except in AppleKext mode. bool CallCanBeVirtual = !MemExpr->hasQualifier() || getLangOpts().AppleKext; CheckVirtualDtorCall(DD, MemExpr->getBeginLoc(), /*IsDelete=*/false, CallCanBeVirtual, /*WarnOnNonAbstractTypes=*/true, MemExpr->getMemberLoc()); } return MaybeBindToTemporary(TheCall); } /// BuildCallToObjectOfClassType - Build a call to an object of class /// type (C++ [over.call.object]), which can end up invoking an /// overloaded function call operator (@c operator()) or performing a /// user-defined conversion on the object argument. ExprResult Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc) { if (checkPlaceholderForOverload(*this, Obj)) return ExprError(); ExprResult Object = Obj; UnbridgedCastsSet UnbridgedCasts; if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts)) return ExprError(); assert(Object.get()->getType()->isRecordType() && "Requires object type argument"); // C++ [over.call.object]p1: // If the primary-expression E in the function call syntax // evaluates to a class object of type "cv T", then the set of // candidate functions includes at least the function call // operators of T. The function call operators of T are obtained by // ordinary lookup of the name operator() in the context of // (E).operator(). OverloadCandidateSet CandidateSet(LParenLoc, OverloadCandidateSet::CSK_Operator); DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call); if (RequireCompleteType(LParenLoc, Object.get()->getType(), diag::err_incomplete_object_call, Object.get())) return true; const auto *Record = Object.get()->getType()->castAs(); LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName); LookupQualifiedName(R, Record->getDecl()); R.suppressDiagnostics(); for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Object.get()->getType(), Object.get()->Classify(Context), Args, CandidateSet, /*SuppressUserConversion=*/false); } // C++ [over.call.object]p2: // In addition, for each (non-explicit in C++0x) conversion function // declared in T of the form // // operator conversion-type-id () cv-qualifier; // // where cv-qualifier is the same cv-qualification as, or a // greater cv-qualification than, cv, and where conversion-type-id // denotes the type "pointer to function of (P1,...,Pn) returning // R", or the type "reference to pointer to function of // (P1,...,Pn) returning R", or the type "reference to function // of (P1,...,Pn) returning R", a surrogate call function [...] // is also considered as a candidate function. Similarly, // surrogate call functions are added to the set of candidate // functions for each conversion function declared in an // accessible base class provided the function is not hidden // within T by another intervening declaration. const auto &Conversions = cast(Record->getDecl())->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { NamedDecl *D = *I; CXXRecordDecl *ActingContext = cast(D->getDeclContext()); if (isa(D)) D = cast(D)->getTargetDecl(); // Skip over templated conversion functions; they aren't // surrogates. if (isa(D)) continue; CXXConversionDecl *Conv = cast(D); if (!Conv->isExplicit()) { // Strip the reference type (if any) and then the pointer type (if // any) to get down to what might be a function type. QualType ConvType = Conv->getConversionType().getNonReferenceType(); if (const PointerType *ConvPtrType = ConvType->getAs()) ConvType = ConvPtrType->getPointeeType(); if (const FunctionProtoType *Proto = ConvType->getAs()) { AddSurrogateCandidate(Conv, I.getPair(), ActingContext, Proto, Object.get(), Args, CandidateSet); } } } bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, Object.get()->getBeginLoc(), Best)) { case OR_Success: // Overload resolution succeeded; we'll build the appropriate call // below. break; case OR_No_Viable_Function: { PartialDiagnostic PD = CandidateSet.empty() ? (PDiag(diag::err_ovl_no_oper) << Object.get()->getType() << /*call*/ 1 << Object.get()->getSourceRange()) : (PDiag(diag::err_ovl_no_viable_object_call) << Object.get()->getType() << Object.get()->getSourceRange()); CandidateSet.NoteCandidates( PartialDiagnosticAt(Object.get()->getBeginLoc(), PD), *this, OCD_AllCandidates, Args); break; } case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(Object.get()->getBeginLoc(), PDiag(diag::err_ovl_ambiguous_object_call) << Object.get()->getType() << Object.get()->getSourceRange()), *this, OCD_AmbiguousCandidates, Args); break; case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(Object.get()->getBeginLoc(), PDiag(diag::err_ovl_deleted_object_call) << Object.get()->getType() << Object.get()->getSourceRange()), *this, OCD_AllCandidates, Args); break; } if (Best == CandidateSet.end()) return true; UnbridgedCasts.restore(); if (Best->Function == nullptr) { // Since there is no function declaration, this is one of the // surrogate candidates. Dig out the conversion function. CXXConversionDecl *Conv = cast( Best->Conversions[0].UserDefined.ConversionFunction); CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr, Best->FoundDecl); if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc)) return ExprError(); assert(Conv == Best->FoundDecl.getDecl() && "Found Decl & conversion-to-functionptr should be same, right?!"); // We selected one of the surrogate functions that converts the // object parameter to a function pointer. Perform the conversion // on the object argument, then let BuildCallExpr finish the job. // Create an implicit member expr to refer to the conversion operator. // and then call it. ExprResult Call = BuildCXXMemberCallExpr(Object.get(), Best->FoundDecl, Conv, HadMultipleCandidates); if (Call.isInvalid()) return ExprError(); // Record usage of conversion in an implicit cast. Call = ImplicitCastExpr::Create(Context, Call.get()->getType(), CK_UserDefinedConversion, Call.get(), nullptr, VK_RValue); return BuildCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc); } CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr, Best->FoundDecl); // We found an overloaded operator(). Build a CXXOperatorCallExpr // that calls this method, using Object for the implicit object // parameter and passing along the remaining arguments. CXXMethodDecl *Method = cast(Best->Function); // An error diagnostic has already been printed when parsing the declaration. if (Method->isInvalidDecl()) return ExprError(); const auto *Proto = Method->getType()->castAs(); unsigned NumParams = Proto->getNumParams(); DeclarationNameInfo OpLocInfo( Context.DeclarationNames.getCXXOperatorName(OO_Call), LParenLoc); OpLocInfo.setCXXOperatorNameRange(SourceRange(LParenLoc, RParenLoc)); ExprResult NewFn = CreateFunctionRefExpr(*this, Method, Best->FoundDecl, Obj, HadMultipleCandidates, OpLocInfo.getLoc(), OpLocInfo.getInfo()); if (NewFn.isInvalid()) return true; // The number of argument slots to allocate in the call. If we have default // arguments we need to allocate space for them as well. We additionally // need one more slot for the object parameter. unsigned NumArgsSlots = 1 + std::max(Args.size(), NumParams); // Build the full argument list for the method call (the implicit object // parameter is placed at the beginning of the list). SmallVector MethodArgs(NumArgsSlots); bool IsError = false; // Initialize the implicit object parameter. ExprResult ObjRes = PerformObjectArgumentInitialization(Object.get(), /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (ObjRes.isInvalid()) IsError = true; else Object = ObjRes; MethodArgs[0] = Object.get(); // Check the argument types. for (unsigned i = 0; i != NumParams; i++) { Expr *Arg; if (i < Args.size()) { Arg = Args[i]; // Pass the argument. ExprResult InputInit = PerformCopyInitialization(InitializedEntity::InitializeParameter( Context, Method->getParamDecl(i)), SourceLocation(), Arg); IsError |= InputInit.isInvalid(); Arg = InputInit.getAs(); } else { ExprResult DefArg = BuildCXXDefaultArgExpr(LParenLoc, Method, Method->getParamDecl(i)); if (DefArg.isInvalid()) { IsError = true; break; } Arg = DefArg.getAs(); } MethodArgs[i + 1] = Arg; } // If this is a variadic call, handle args passed through "...". if (Proto->isVariadic()) { // Promote the arguments (C99 6.5.2.2p7). for (unsigned i = NumParams, e = Args.size(); i < e; i++) { ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, nullptr); IsError |= Arg.isInvalid(); MethodArgs[i + 1] = Arg.get(); } } if (IsError) return true; DiagnoseSentinelCalls(Method, LParenLoc, Args); // Once we've built TheCall, all of the expressions are properly owned. QualType ResultTy = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy, VK, RParenLoc, FPOptions()); if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method)) return true; if (CheckFunctionCall(Method, TheCall, Proto)) return true; return MaybeBindToTemporary(TheCall); } /// BuildOverloadedArrowExpr - Build a call to an overloaded @c operator-> /// (if one exists), where @c Base is an expression of class type and /// @c Member is the name of the member we're trying to find. ExprResult Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, bool *NoArrowOperatorFound) { assert(Base->getType()->isRecordType() && "left-hand side must have class type"); if (checkPlaceholderForOverload(*this, Base)) return ExprError(); SourceLocation Loc = Base->getExprLoc(); // C++ [over.ref]p1: // // [...] An expression x->m is interpreted as (x.operator->())->m // for a class object x of type T if T::operator->() exists and if // the operator is selected as the best match function by the // overload resolution mechanism (13.3). DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Arrow); OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Operator); if (RequireCompleteType(Loc, Base->getType(), diag::err_typecheck_incomplete_tag, Base)) return ExprError(); LookupResult R(*this, OpName, OpLoc, LookupOrdinaryName); LookupQualifiedName(R, Base->getType()->castAs()->getDecl()); R.suppressDiagnostics(); for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Base->getType(), Base->Classify(Context), None, CandidateSet, /*SuppressUserConversion=*/false); } bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) { case OR_Success: // Overload resolution succeeded; we'll build the call below. break; case OR_No_Viable_Function: { auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates, Base); if (CandidateSet.empty()) { QualType BaseType = Base->getType(); if (NoArrowOperatorFound) { // Report this specific error to the caller instead of emitting a // diagnostic, as requested. *NoArrowOperatorFound = true; return ExprError(); } Diag(OpLoc, diag::err_typecheck_member_reference_arrow) << BaseType << Base->getSourceRange(); if (BaseType->isRecordType() && !BaseType->isPointerType()) { Diag(OpLoc, diag::note_typecheck_member_reference_suggestion) << FixItHint::CreateReplacement(OpLoc, "."); } } else Diag(OpLoc, diag::err_ovl_no_viable_oper) << "operator->" << Base->getSourceRange(); CandidateSet.NoteCandidates(*this, Base, Cands); return ExprError(); } case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_unary) << "->" << Base->getType() << Base->getSourceRange()), *this, OCD_AmbiguousCandidates, Base); return ExprError(); case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper) << "->" << Base->getSourceRange()), *this, OCD_AllCandidates, Base); return ExprError(); } CheckMemberOperatorAccess(OpLoc, Base, nullptr, Best->FoundDecl); // Convert the object parameter. CXXMethodDecl *Method = cast(Best->Function); ExprResult BaseResult = PerformObjectArgumentInitialization(Base, /*Qualifier=*/nullptr, Best->FoundDecl, Method); if (BaseResult.isInvalid()) return ExprError(); Base = BaseResult.get(); // Build the operator call. ExprResult FnExpr = CreateFunctionRefExpr(*this, Method, Best->FoundDecl, Base, HadMultipleCandidates, OpLoc); if (FnExpr.isInvalid()) return ExprError(); QualType ResultTy = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( Context, OO_Arrow, FnExpr.get(), Base, ResultTy, VK, OpLoc, FPOptions()); if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method)) return ExprError(); if (CheckFunctionCall(Method, TheCall, Method->getType()->castAs())) return ExprError(); return MaybeBindToTemporary(TheCall); } /// BuildLiteralOperatorCall - Build a UserDefinedLiteral by creating a call to /// a literal operator described by the provided lookup results. ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R, DeclarationNameInfo &SuffixInfo, ArrayRef Args, SourceLocation LitEndLoc, TemplateArgumentListInfo *TemplateArgs) { SourceLocation UDSuffixLoc = SuffixInfo.getCXXLiteralOperatorNameLoc(); OverloadCandidateSet CandidateSet(UDSuffixLoc, OverloadCandidateSet::CSK_Normal); AddNonMemberOperatorCandidates(R.asUnresolvedSet(), Args, CandidateSet, TemplateArgs); bool HadMultipleCandidates = (CandidateSet.size() > 1); // Perform overload resolution. This will usually be trivial, but might need // to perform substitutions for a literal operator template. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, UDSuffixLoc, Best)) { case OR_Success: case OR_Deleted: break; case OR_No_Viable_Function: CandidateSet.NoteCandidates( PartialDiagnosticAt(UDSuffixLoc, PDiag(diag::err_ovl_no_viable_function_in_call) << R.getLookupName()), *this, OCD_AllCandidates, Args); return ExprError(); case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(R.getNameLoc(), PDiag(diag::err_ovl_ambiguous_call) << R.getLookupName()), *this, OCD_AmbiguousCandidates, Args); return ExprError(); } FunctionDecl *FD = Best->Function; ExprResult Fn = CreateFunctionRefExpr(*this, FD, Best->FoundDecl, nullptr, HadMultipleCandidates, SuffixInfo.getLoc(), SuffixInfo.getInfo()); if (Fn.isInvalid()) return true; // Check the argument types. This should almost always be a no-op, except // that array-to-pointer decay is applied to string literals. Expr *ConvArgs[2]; for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { ExprResult InputInit = PerformCopyInitialization( InitializedEntity::InitializeParameter(Context, FD->getParamDecl(ArgIdx)), SourceLocation(), Args[ArgIdx]); if (InputInit.isInvalid()) return true; ConvArgs[ArgIdx] = InputInit.get(); } QualType ResultTy = FD->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); UserDefinedLiteral *UDL = UserDefinedLiteral::Create( Context, Fn.get(), llvm::makeArrayRef(ConvArgs, Args.size()), ResultTy, VK, LitEndLoc, UDSuffixLoc); if (CheckCallReturnType(FD->getReturnType(), UDSuffixLoc, UDL, FD)) return ExprError(); if (CheckFunctionCall(FD, UDL, nullptr)) return ExprError(); return MaybeBindToTemporary(UDL); } /// Build a call to 'begin' or 'end' for a C++11 for-range statement. If the /// given LookupResult is non-empty, it is assumed to describe a member which /// will be invoked. Otherwise, the function will be found via argument /// dependent lookup. /// CallExpr is set to a valid expression and FRS_Success returned on success, /// otherwise CallExpr is set to ExprError() and some non-success value /// is returned. Sema::ForRangeStatus Sema::BuildForRangeBeginEndCall(SourceLocation Loc, SourceLocation RangeLoc, const DeclarationNameInfo &NameInfo, LookupResult &MemberLookup, OverloadCandidateSet *CandidateSet, Expr *Range, ExprResult *CallExpr) { Scope *S = nullptr; CandidateSet->clear(OverloadCandidateSet::CSK_Normal); if (!MemberLookup.empty()) { ExprResult MemberRef = BuildMemberReferenceExpr(Range, Range->getType(), Loc, /*IsPtr=*/false, CXXScopeSpec(), /*TemplateKWLoc=*/SourceLocation(), /*FirstQualifierInScope=*/nullptr, MemberLookup, /*TemplateArgs=*/nullptr, S); if (MemberRef.isInvalid()) { *CallExpr = ExprError(); return FRS_DiagnosticIssued; } *CallExpr = BuildCallExpr(S, MemberRef.get(), Loc, None, Loc, nullptr); if (CallExpr->isInvalid()) { *CallExpr = ExprError(); return FRS_DiagnosticIssued; } } else { UnresolvedSet<0> FoundNames; UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create(Context, /*NamingClass=*/nullptr, NestedNameSpecifierLoc(), NameInfo, /*NeedsADL=*/true, /*Overloaded=*/false, FoundNames.begin(), FoundNames.end()); bool CandidateSetError = buildOverloadedCallSet(S, Fn, Fn, Range, Loc, CandidateSet, CallExpr); if (CandidateSet->empty() || CandidateSetError) { *CallExpr = ExprError(); return FRS_NoViableFunction; } OverloadCandidateSet::iterator Best; OverloadingResult OverloadResult = CandidateSet->BestViableFunction(*this, Fn->getBeginLoc(), Best); if (OverloadResult == OR_No_Viable_Function) { *CallExpr = ExprError(); return FRS_NoViableFunction; } *CallExpr = FinishOverloadedCallExpr(*this, S, Fn, Fn, Loc, Range, Loc, nullptr, CandidateSet, &Best, OverloadResult, /*AllowTypoCorrection=*/false); if (CallExpr->isInvalid() || OverloadResult != OR_Success) { *CallExpr = ExprError(); return FRS_DiagnosticIssued; } } return FRS_Success; } /// FixOverloadedFunctionReference - E is an expression that refers to /// a C++ overloaded function (possibly with some parentheses and /// perhaps a '&' around it). We have resolved the overloaded function /// to the function declaration Fn, so patch up the expression E to /// refer (possibly indirectly) to Fn. Returns the new expr. Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, FunctionDecl *Fn) { if (ParenExpr *PE = dyn_cast(E)) { Expr *SubExpr = FixOverloadedFunctionReference(PE->getSubExpr(), Found, Fn); if (SubExpr == PE->getSubExpr()) return PE; return new (Context) ParenExpr(PE->getLParen(), PE->getRParen(), SubExpr); } if (ImplicitCastExpr *ICE = dyn_cast(E)) { Expr *SubExpr = FixOverloadedFunctionReference(ICE->getSubExpr(), Found, Fn); assert(Context.hasSameType(ICE->getSubExpr()->getType(), SubExpr->getType()) && "Implicit cast type cannot be determined from overload"); assert(ICE->path_empty() && "fixing up hierarchy conversion?"); if (SubExpr == ICE->getSubExpr()) return ICE; return ImplicitCastExpr::Create(Context, ICE->getType(), ICE->getCastKind(), SubExpr, nullptr, ICE->getValueKind()); } if (auto *GSE = dyn_cast(E)) { if (!GSE->isResultDependent()) { Expr *SubExpr = FixOverloadedFunctionReference(GSE->getResultExpr(), Found, Fn); if (SubExpr == GSE->getResultExpr()) return GSE; // Replace the resulting type information before rebuilding the generic // selection expression. ArrayRef A = GSE->getAssocExprs(); SmallVector AssocExprs(A.begin(), A.end()); unsigned ResultIdx = GSE->getResultIndex(); AssocExprs[ResultIdx] = SubExpr; return GenericSelectionExpr::Create( Context, GSE->getGenericLoc(), GSE->getControllingExpr(), GSE->getAssocTypeSourceInfos(), AssocExprs, GSE->getDefaultLoc(), GSE->getRParenLoc(), GSE->containsUnexpandedParameterPack(), ResultIdx); } // Rather than fall through to the unreachable, return the original generic // selection expression. return GSE; } if (UnaryOperator *UnOp = dyn_cast(E)) { assert(UnOp->getOpcode() == UO_AddrOf && "Can only take the address of an overloaded function"); if (CXXMethodDecl *Method = dyn_cast(Fn)) { if (Method->isStatic()) { // Do nothing: static member functions aren't any different // from non-member functions. } else { // Fix the subexpression, which really has to be an // UnresolvedLookupExpr holding an overloaded member function // or template. Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Found, Fn); if (SubExpr == UnOp->getSubExpr()) return UnOp; assert(isa(SubExpr) && "fixed to something other than a decl ref"); assert(cast(SubExpr)->getQualifier() && "fixed to a member ref with no nested name qualifier"); // We have taken the address of a pointer to member // function. Perform the computation here so that we get the // appropriate pointer to member type. QualType ClassType = Context.getTypeDeclType(cast(Method->getDeclContext())); QualType MemPtrType = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr()); // Under the MS ABI, lock down the inheritance model now. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) (void)isCompleteType(UnOp->getOperatorLoc(), MemPtrType); return new (Context) UnaryOperator(SubExpr, UO_AddrOf, MemPtrType, VK_RValue, OK_Ordinary, UnOp->getOperatorLoc(), false); } } Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Found, Fn); if (SubExpr == UnOp->getSubExpr()) return UnOp; return new (Context) UnaryOperator(SubExpr, UO_AddrOf, Context.getPointerType(SubExpr->getType()), VK_RValue, OK_Ordinary, UnOp->getOperatorLoc(), false); } if (UnresolvedLookupExpr *ULE = dyn_cast(E)) { // FIXME: avoid copy. TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr; if (ULE->hasExplicitTemplateArgs()) { ULE->copyTemplateArgumentsInto(TemplateArgsBuffer); TemplateArgs = &TemplateArgsBuffer; } DeclRefExpr *DRE = BuildDeclRefExpr(Fn, Fn->getType(), VK_LValue, ULE->getNameInfo(), ULE->getQualifierLoc(), Found.getDecl(), ULE->getTemplateKeywordLoc(), TemplateArgs); DRE->setHadMultipleCandidates(ULE->getNumDecls() > 1); return DRE; } if (UnresolvedMemberExpr *MemExpr = dyn_cast(E)) { // FIXME: avoid copy. TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr; if (MemExpr->hasExplicitTemplateArgs()) { MemExpr->copyTemplateArgumentsInto(TemplateArgsBuffer); TemplateArgs = &TemplateArgsBuffer; } Expr *Base; // If we're filling in a static method where we used to have an // implicit member access, rewrite to a simple decl ref. if (MemExpr->isImplicitAccess()) { if (cast(Fn)->isStatic()) { DeclRefExpr *DRE = BuildDeclRefExpr( Fn, Fn->getType(), VK_LValue, MemExpr->getNameInfo(), MemExpr->getQualifierLoc(), Found.getDecl(), MemExpr->getTemplateKeywordLoc(), TemplateArgs); DRE->setHadMultipleCandidates(MemExpr->getNumDecls() > 1); return DRE; } else { SourceLocation Loc = MemExpr->getMemberLoc(); if (MemExpr->getQualifier()) Loc = MemExpr->getQualifierLoc().getBeginLoc(); Base = BuildCXXThisExpr(Loc, MemExpr->getBaseType(), /*IsImplicit=*/true); } } else Base = MemExpr->getBase(); ExprValueKind valueKind; QualType type; if (cast(Fn)->isStatic()) { valueKind = VK_LValue; type = Fn->getType(); } else { valueKind = VK_RValue; type = Context.BoundMemberTy; } return BuildMemberExpr( Base, MemExpr->isArrow(), MemExpr->getOperatorLoc(), MemExpr->getQualifierLoc(), MemExpr->getTemplateKeywordLoc(), Fn, Found, /*HadMultipleCandidates=*/true, MemExpr->getMemberNameInfo(), type, valueKind, OK_Ordinary, TemplateArgs); } llvm_unreachable("Invalid reference to overloaded function"); } ExprResult Sema::FixOverloadedFunctionReference(ExprResult E, DeclAccessPair Found, FunctionDecl *Fn) { return FixOverloadedFunctionReference(E.get(), Found, Fn); } Index: stable/12 =================================================================== --- stable/12 (revision 363091) +++ stable/12 (revision 363092) Property changes on: stable/12 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r363013