diff options
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 381 |
1 files changed, 219 insertions, 162 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 16fd28e461..529ba127cb 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -42,13 +42,15 @@ CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl, bool HadMultipleCandidates, SourceLocation Loc = SourceLocation(), const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){ + if (S.DiagnoseUseOfDecl(FoundDecl, Loc)) + return ExprError(); + DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(), VK_LValue, Loc, LocInfo); if (HadMultipleCandidates) DRE->setHadMultipleCandidates(true); S.MarkDeclRefReferenced(DRE); - S.DiagnoseUseOfDecl(FoundDecl, Loc); ExprResult E = S.Owned(DRE); E = S.DefaultFunctionArrayConversion(E.take()); @@ -920,7 +922,8 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old, // function templates hide function templates with different // return types or template parameter lists. bool UseMemberUsingDeclRules = - (OldIsUsingDecl || NewIsUsingDecl) && CurContext->isRecord(); + (OldIsUsingDecl || NewIsUsingDecl) && CurContext->isRecord() && + !New->getFriendObjectKind(); if (FunctionTemplateDecl *OldT = dyn_cast<FunctionTemplateDecl>(OldD)) { if (!IsOverload(New, OldT->getTemplatedDecl(), UseMemberUsingDeclRules)) { @@ -939,6 +942,9 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old, continue; } + if (!shouldLinkPossiblyHiddenDecl(*I, New)) + continue; + Match = *I; return Ovl_Match; } @@ -977,13 +983,8 @@ static bool canBeOverloaded(const FunctionDecl &D) { return true; } -bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, - bool UseUsingDeclRules) { - // If both of the functions are extern "C", then they are not - // overloads. - if (!canBeOverloaded(*Old) && !canBeOverloaded(*New)) - return false; - +static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl *Old, + bool UseUsingDeclRules) { FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate(); FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate(); @@ -994,8 +995,8 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, return true; // Is the function New an overload of the function Old? - QualType OldQType = Context.getCanonicalType(Old->getType()); - QualType NewQType = Context.getCanonicalType(New->getType()); + QualType OldQType = S.Context.getCanonicalType(Old->getType()); + QualType NewQType = S.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 @@ -1016,7 +1017,7 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, if (OldQType != NewQType && (OldType->getNumArgs() != NewType->getNumArgs() || OldType->isVariadic() != NewType->isVariadic() || - !FunctionArgTypesAreEqual(OldType, NewType))) + !S.FunctionArgTypesAreEqual(OldType, NewType))) return true; // C++ [temp.over.link]p4: @@ -1032,9 +1033,9 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, // However, we don't consider either of these when deciding whether // a member introduced by a shadow declaration is hidden. if (!UseUsingDeclRules && NewTemplate && - (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), - OldTemplate->getTemplateParameters(), - false, TPL_TemplateMatch) || + (!S.TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), + OldTemplate->getTemplateParameters(), + false, S.TPL_TemplateMatch) || OldType->getResultType() != NewType->getResultType())) return true; @@ -1060,9 +1061,9 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, // 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) + S.Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload) << NewMethod->getRefQualifier() << OldMethod->getRefQualifier(); - Diag(OldMethod->getLocation(), diag::note_previous_declaration); + S.Diag(OldMethod->getLocation(), diag::note_previous_declaration); } return true; } @@ -1082,6 +1083,19 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, return false; } +bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, + bool UseUsingDeclRules) { + if (!shouldTryToOverload(*this, New, Old, UseUsingDeclRules)) + return false; + + // If both of the functions are extern "C", then they are not + // overloads. + if (!canBeOverloaded(*Old) && !canBeOverloaded(*New)) + return false; + + return true; +} + /// \brief Checks availability of the function depending on the current /// function context. Inside an unavailable function, unavailability is ignored. /// @@ -1823,7 +1837,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { // conversion. using llvm::APSInt; if (From) - if (FieldDecl *MemberDecl = From->getBitField()) { + if (FieldDecl *MemberDecl = From->getSourceBitField()) { APSInt BitWidth; if (FromType->isIntegralType(Context) && MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) { @@ -3929,6 +3943,15 @@ CompareDerivedToBaseConversions(Sema &S, return ImplicitConversionSequence::Indistinguishable; } +/// \brief 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; +} + /// CompareReferenceRelationship - Compare the two types T1 and T2 to /// determine whether they are reference-related, /// reference-compatible, reference-compatible with added @@ -3962,7 +3985,8 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, if (UnqualT1 == UnqualT2) { // Nothing to do. } else if (!RequireCompleteType(Loc, OrigT2, 0) && - IsDerivedFrom(UnqualT2, UnqualT1)) + isTypeValid(UnqualT1) && isTypeValid(UnqualT2) && + IsDerivedFrom(UnqualT2, UnqualT1)) DerivedToBase = true; else if (UnqualT1->isObjCObjectOrInterfaceType() && UnqualT2->isObjCObjectOrInterfaceType() && @@ -5005,7 +5029,7 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, Expr::EvalResult Eval; Eval.Diag = &Notes; - if (!Result.get()->EvaluateAsRValue(Eval, Context)) { + if (!Result.get()->EvaluateAsRValue(Eval, Context) || !Eval.Val.isInt()) { // The expression can't be folded, so we can't keep it at this position in // the AST. Result = ExprError(); @@ -5454,7 +5478,7 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions) { NamedDecl *Decl = FoundDecl.getDecl(); @@ -5469,12 +5493,12 @@ void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, AddMethodTemplateCandidate(TD, FoundDecl, ActingContext, /*ExplicitArgs*/ 0, ObjectType, ObjectClassification, - llvm::makeArrayRef(Args, NumArgs), CandidateSet, + Args, CandidateSet, SuppressUserConversions); } else { AddMethodCandidate(cast<CXXMethodDecl>(Decl), FoundDecl, ActingContext, ObjectType, ObjectClassification, - llvm::makeArrayRef(Args, NumArgs), + Args, CandidateSet, SuppressUserConversions); } } @@ -5702,6 +5726,14 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, if (!CandidateSet.isNewCandidate(Conversion)) return; + // If the conversion function has an undeduced return type, trigger its + // deduction now. + if (getLangOpts().CPlusPlus1y && ConvType->isUndeducedType()) { + if (DeduceReturnType(Conversion, From->getExprLoc())) + return; + ConvType = Conversion->getConversionType().getNonReferenceType(); + } + // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); @@ -5781,7 +5813,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, // there are 0 arguments (i.e., nothing is allocated using ASTContext's // allocator). QualType CallResultType = ConversionType.getNonLValueExprType(Context); - CallExpr Call(Context, &ConversionFn, MultiExprArg(), CallResultType, VK, + CallExpr Call(Context, &ConversionFn, None, CallResultType, VK, From->getLocStart()); ImplicitConversionSequence ICS = TryCopyInitialization(*this, &Call, ToType, @@ -5944,7 +5976,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, // Determine the implicit conversion sequences for each of the // arguments. - for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { if (ArgIdx < NumArgsInProto) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence @@ -5981,7 +6013,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, /// [over.match.oper]). void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, SourceLocation OpLoc, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, SourceRange OpRange) { DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); @@ -5996,13 +6028,15 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, // constructed as follows: QualType T1 = Args[0]->getType(); - // -- If T1 is a class type, 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 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<RecordType>()) { - // Complete the type if it can be completed. Otherwise, we're done. - if (RequireCompleteType(OpLoc, T1, 0)) + // Complete the type if it can be completed. + RequireCompleteType(OpLoc, T1, 0); + // If the type is neither complete nor being defined, bail out now. + if (!T1Rec->getDecl()->getDefinition()) return; LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName); @@ -6014,7 +6048,8 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, Oper != OperEnd; ++Oper) AddMethodCandidate(Oper.getPair(), Args[0]->getType(), - Args[0]->Classify(Context), Args + 1, NumArgs - 1, + Args[0]->Classify(Context), + Args.slice(1), CandidateSet, /* SuppressUserConversions = */ false); } @@ -6029,7 +6064,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, /// (at the beginning of the argument list) that will be contextually /// converted to bool. void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool IsAssignmentOperator, unsigned NumContextualBoolArguments) { @@ -6037,20 +6072,20 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys, EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); // Add this candidate - OverloadCandidate &Candidate = CandidateSet.addCandidate(NumArgs); + OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); Candidate.FoundDecl = DeclAccessPair::make(0, AS_none); Candidate.Function = 0; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.BuiltinTypes.ResultTy = ResultTy; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) Candidate.BuiltinTypes.ParamTypes[ArgIdx] = ParamTys[ArgIdx]; // Determine the implicit conversion sequences for each of the // arguments. Candidate.Viable = true; - Candidate.ExplicitCallArguments = NumArgs; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) { + 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: @@ -6376,15 +6411,14 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty, /// given type to the candidate set. static void AddBuiltinAssignmentOperatorCandidates(Sema &S, QualType T, - Expr **Args, - unsigned NumArgs, + ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet) { QualType ParamTypes[2]; // T& operator=(T&, T) ParamTypes[0] = S.Context.getLValueReferenceType(T); ParamTypes[1] = T; - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); if (!S.Context.getCanonicalType(T).isVolatileQualified()) { @@ -6392,7 +6426,7 @@ static void AddBuiltinAssignmentOperatorCandidates(Sema &S, ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(T)); ParamTypes[1] = T; - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); } } @@ -6463,8 +6497,7 @@ namespace { class BuiltinOperatorOverloadBuilder { // Common instance state available to all overload candidate addition methods. Sema &S; - Expr **Args; - unsigned NumArgs; + ArrayRef<Expr *> Args; Qualifiers VisibleTypeConversionsQuals; bool HasArithmeticOrEnumeralCandidateType; SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes; @@ -6587,10 +6620,10 @@ class BuiltinOperatorOverloadBuilder { }; // Non-volatile version. - if (NumArgs == 1) - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet); + if (Args.size() == 1) + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); else - S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(CandidateTy, 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. @@ -6598,10 +6631,10 @@ class BuiltinOperatorOverloadBuilder { ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getVolatileType(CandidateTy)); - if (NumArgs == 1) - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet); + if (Args.size() == 1) + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); else - S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet); } // Add restrict version only if there are conversions to a restrict type @@ -6611,10 +6644,10 @@ class BuiltinOperatorOverloadBuilder { ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getCVRQualifiedType(CandidateTy, Qualifiers::Restrict)); - if (NumArgs == 1) - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet); + if (Args.size() == 1) + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); else - S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet); if (HasVolatile) { ParamTypes[0] @@ -6622,11 +6655,10 @@ class BuiltinOperatorOverloadBuilder { S.Context.getCVRQualifiedType(CandidateTy, (Qualifiers::Volatile | Qualifiers::Restrict))); - if (NumArgs == 1) - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, - CandidateSet); + if (Args.size() == 1) + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); else - S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet); } } @@ -6634,12 +6666,12 @@ class BuiltinOperatorOverloadBuilder { public: BuiltinOperatorOverloadBuilder( - Sema &S, Expr **Args, unsigned NumArgs, + Sema &S, ArrayRef<Expr *> Args, Qualifiers VisibleTypeConversionsQuals, bool HasArithmeticOrEnumeralCandidateType, SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes, OverloadCandidateSet &CandidateSet) - : S(S), Args(Args), NumArgs(NumArgs), + : S(S), Args(Args), VisibleTypeConversionsQuals(VisibleTypeConversionsQuals), HasArithmeticOrEnumeralCandidateType( HasArithmeticOrEnumeralCandidateType), @@ -6741,7 +6773,7 @@ public: continue; S.AddBuiltinCandidate(S.Context.getLValueReferenceType(PointeeTy), - &ParamTy, Args, 1, CandidateSet); + &ParamTy, Args, CandidateSet); } } @@ -6758,7 +6790,7 @@ public: for (unsigned Arith = FirstPromotedArithmeticType; Arith < LastPromotedArithmeticType; ++Arith) { QualType ArithTy = getArithmeticType(Arith); - S.AddBuiltinCandidate(ArithTy, &ArithTy, Args, 1, CandidateSet); + S.AddBuiltinCandidate(ArithTy, &ArithTy, Args, CandidateSet); } // Extension: We also add these operators for vector types. @@ -6767,7 +6799,7 @@ public: VecEnd = CandidateTypes[0].vector_end(); Vec != VecEnd; ++Vec) { QualType VecTy = *Vec; - S.AddBuiltinCandidate(VecTy, &VecTy, Args, 1, CandidateSet); + S.AddBuiltinCandidate(VecTy, &VecTy, Args, CandidateSet); } } @@ -6782,7 +6814,7 @@ public: PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType ParamTy = *Ptr; - S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, 1, CandidateSet); + S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, CandidateSet); } } @@ -6798,7 +6830,7 @@ public: for (unsigned Int = FirstPromotedIntegralType; Int < LastPromotedIntegralType; ++Int) { QualType IntTy = getArithmeticType(Int); - S.AddBuiltinCandidate(IntTy, &IntTy, Args, 1, CandidateSet); + S.AddBuiltinCandidate(IntTy, &IntTy, Args, CandidateSet); } // Extension: We also add this operator for vector types. @@ -6807,7 +6839,7 @@ public: VecEnd = CandidateTypes[0].vector_end(); Vec != VecEnd; ++Vec) { QualType VecTy = *Vec; - S.AddBuiltinCandidate(VecTy, &VecTy, Args, 1, CandidateSet); + S.AddBuiltinCandidate(VecTy, &VecTy, Args, CandidateSet); } } @@ -6821,7 +6853,7 @@ public: /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet<QualType, 8> AddedTypes; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) { + 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(); @@ -6832,8 +6864,7 @@ public: continue; QualType ParamTypes[2] = { *MemPtr, *MemPtr }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, - CandidateSet); + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet); } } } @@ -6865,7 +6896,7 @@ public: llvm::DenseSet<std::pair<CanQualType, CanQualType> > UserDefinedBinaryOperators; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) { + 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(), @@ -6898,7 +6929,7 @@ public: /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet<QualType, 8> AddedTypes; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) { + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[ArgIdx].pointer_begin(), PtrEnd = CandidateTypes[ArgIdx].pointer_end(); @@ -6908,8 +6939,7 @@ public: continue; QualType ParamTypes[2] = { *Ptr, *Ptr }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, - CandidateSet); + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator Enum = CandidateTypes[ArgIdx].enumeration_begin(), @@ -6925,17 +6955,16 @@ public: continue; QualType ParamTypes[2] = { *Enum, *Enum }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, - CandidateSet); + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet); } if (CandidateTypes[ArgIdx].hasNullPtrType()) { CanQualType NullPtrTy = S.Context.getCanonicalType(S.Context.NullPtrTy); if (AddedTypes.insert(NullPtrTy) && - !UserDefinedBinaryOperators.count(std::make_pair(NullPtrTy, + !UserDefinedBinaryOperators.count(std::make_pair(NullPtrTy, NullPtrTy))) { QualType ParamTypes[2] = { NullPtrTy, NullPtrTy }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet); } } @@ -6980,8 +7009,7 @@ public: if (Arg == 0 || Op == OO_Plus) { // operator+(T*, ptrdiff_t) or operator-(T*, ptrdiff_t) // T* operator+(ptrdiff_t, T*); - S.AddBuiltinCandidate(*Ptr, AsymetricParamTypes, Args, 2, - CandidateSet); + S.AddBuiltinCandidate(*Ptr, AsymetricParamTypes, Args, CandidateSet); } if (Op == OO_Minus) { // ptrdiff_t operator-(T, T); @@ -6990,7 +7018,7 @@ public: QualType ParamTypes[2] = { *Ptr, *Ptr }; S.AddBuiltinCandidate(S.Context.getPointerDiffType(), ParamTypes, - Args, 2, CandidateSet); + Args, CandidateSet); } } } @@ -7038,7 +7066,7 @@ public: QualType Result = isComparison ? S.Context.BoolTy : getUsualArithmeticConversions(Left, Right); - S.AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet); + S.AddBuiltinCandidate(Result, LandR, Args, CandidateSet); } } @@ -7061,7 +7089,7 @@ public: Result = *Vec2; } - S.AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet); + S.AddBuiltinCandidate(Result, LandR, Args, CandidateSet); } } } @@ -7093,7 +7121,7 @@ public: QualType Result = (Op == OO_LessLess || Op == OO_GreaterGreater) ? LandR[0] : getUsualArithmeticConversions(Left, Right); - S.AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet); + S.AddBuiltinCandidate(Result, LandR, Args, CandidateSet); } } } @@ -7117,8 +7145,7 @@ public: if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum))) continue; - AddBuiltinAssignmentOperatorCandidates(S, *Enum, Args, 2, - CandidateSet); + AddBuiltinAssignmentOperatorCandidates(S, *Enum, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator @@ -7128,8 +7155,7 @@ public: if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr))) continue; - AddBuiltinAssignmentOperatorCandidates(S, *MemPtr, Args, 2, - CandidateSet); + AddBuiltinAssignmentOperatorCandidates(S, *MemPtr, Args, CandidateSet); } } } @@ -7169,7 +7195,7 @@ public: S.Context.getLValueReferenceType(*Ptr), isEqualOp ? *Ptr : S.Context.getPointerDiffType(), }; - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/ isEqualOp); bool NeedVolatile = !(*Ptr).isVolatileQualified() && @@ -7178,7 +7204,7 @@ public: // volatile version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); } @@ -7187,7 +7213,7 @@ public: // restrict version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); if (NeedVolatile) { @@ -7197,8 +7223,7 @@ public: S.Context.getCVRQualifiedType(*Ptr, (Qualifiers::Volatile | Qualifiers::Restrict))); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); } } @@ -7219,7 +7244,7 @@ public: }; // non-volatile version - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/true); bool NeedVolatile = !(*Ptr).isVolatileQualified() && @@ -7228,8 +7253,8 @@ public: // volatile version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, /*IsAssigmentOperator=*/true); + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, + /*IsAssigmentOperator=*/true); } if (!(*Ptr).isRestrictQualified() && @@ -7237,8 +7262,8 @@ public: // restrict version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, /*IsAssigmentOperator=*/true); + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, + /*IsAssigmentOperator=*/true); if (NeedVolatile) { // volatile restrict version @@ -7247,9 +7272,8 @@ public: S.Context.getCVRQualifiedType(*Ptr, (Qualifiers::Volatile | Qualifiers::Restrict))); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, /*IsAssigmentOperator=*/true); - + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, + /*IsAssigmentOperator=*/true); } } } @@ -7281,7 +7305,7 @@ public: // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(getArithmeticType(Left)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). @@ -7289,8 +7313,7 @@ public: ParamTypes[0] = S.Context.getVolatileType(getArithmeticType(Left)); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); } } @@ -7309,15 +7332,14 @@ public: ParamTypes[1] = *Vec2; // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(*Vec1); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/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[0], ParamTypes, Args, 2, - CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); } } @@ -7349,14 +7371,13 @@ public: // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(getArithmeticType(Left)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); if (VisibleTypeConversionsQuals.hasVolatile()) { // Add this built-in operator as a candidate (VQ is 'volatile'). ParamTypes[0] = getArithmeticType(Left); ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet); + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); } } } @@ -7371,13 +7392,13 @@ public: // bool operator||(bool, bool); void addExclaimOverload() { QualType ParamTy = S.Context.BoolTy; - S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, 1, CandidateSet, + S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, CandidateSet, /*IsAssignmentOperator=*/false, /*NumContextualBoolArguments=*/1); } void addAmpAmpOrPipePipeOverload() { QualType ParamTypes[2] = { S.Context.BoolTy, S.Context.BoolTy }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/false, /*NumContextualBoolArguments=*/2); } @@ -7405,7 +7426,7 @@ public: QualType ResultTy = S.Context.getLValueReferenceType(PointeeType); // T& operator[](T*, ptrdiff_t) - S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator @@ -7420,7 +7441,7 @@ public: QualType ResultTy = S.Context.getLValueReferenceType(PointeeType); // T& operator[](ptrdiff_t, T*) - S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, CandidateSet); } } @@ -7471,7 +7492,7 @@ public: continue; T = Q1.apply(S.Context, T); QualType ResultTy = S.Context.getLValueReferenceType(T); - S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, CandidateSet); } } } @@ -7499,7 +7520,7 @@ public: continue; QualType ParamTypes[2] = { *Ptr, *Ptr }; - S.AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(*Ptr, ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator @@ -7510,7 +7531,7 @@ public: continue; QualType ParamTypes[2] = { *MemPtr, *MemPtr }; - S.AddBuiltinCandidate(*MemPtr, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(*MemPtr, ParamTypes, Args, CandidateSet); } if (S.getLangOpts().CPlusPlus11) { @@ -7525,7 +7546,7 @@ public: continue; QualType ParamTypes[2] = { *Enum, *Enum }; - S.AddBuiltinCandidate(*Enum, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(*Enum, ParamTypes, Args, CandidateSet); } } } @@ -7542,7 +7563,7 @@ public: void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, SourceLocation OpLoc, - Expr **Args, unsigned NumArgs, + llvm::ArrayRef<Expr *> 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 @@ -7550,13 +7571,13 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, // candidate types or either arithmetic or enumeral candidate types. Qualifiers VisibleTypeConversionsQuals; VisibleTypeConversionsQuals.addConst(); - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) VisibleTypeConversionsQuals += CollectVRQualifiers(Context, Args[ArgIdx]); bool HasNonRecordCandidateType = false; bool HasArithmeticOrEnumeralCandidateType = false; SmallVector<BuiltinCandidateTypeSet, 2> CandidateTypes; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) { + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { CandidateTypes.push_back(BuiltinCandidateTypeSet(*this)); CandidateTypes[ArgIdx].AddTypesConvertedFrom(Args[ArgIdx]->getType(), OpLoc, @@ -7577,12 +7598,12 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, // // We can't exit early for !, ||, or &&, since there we have always have // 'bool' overloads. - if (!HasNonRecordCandidateType && + 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, NumArgs, + BuiltinOperatorOverloadBuilder OpBuilder(*this, Args, VisibleTypeConversionsQuals, HasArithmeticOrEnumeralCandidateType, CandidateTypes, CandidateSet); @@ -7609,12 +7630,12 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, break; case OO_Plus: // '+' is either unary or binary - if (NumArgs == 1) + if (Args.size() == 1) OpBuilder.addUnaryPlusPointerOverloads(); // Fall through. case OO_Minus: // '-' is either unary or binary - if (NumArgs == 1) { + if (Args.size() == 1) { OpBuilder.addUnaryPlusOrMinusArithmeticOverloads(); } else { OpBuilder.addBinaryPlusOrMinusPointerOverloads(Op); @@ -7623,7 +7644,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, break; case OO_Star: // '*' is either unary or binary - if (NumArgs == 1) + if (Args.size() == 1) OpBuilder.addUnaryStarPointerOverloads(); else OpBuilder.addGenericBinaryArithmeticOverloads(/*isComparison=*/false); @@ -7661,7 +7682,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, break; case OO_Amp: // '&' is either unary or binary - if (NumArgs == 1) + 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. @@ -8489,13 +8510,35 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, return; } - case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_NonDeducedMismatch: { // FIXME: Provide a source location to indicate what we couldn't match. + TemplateArgument FirstTA = *Cand->DeductionFailure.getFirstArg(); + TemplateArgument SecondTA = *Cand->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(Fn->getLocation(), + diag::note_ovl_candidate_non_deduced_mismatch_qualified) + << FirstTN.getAsTemplateDecl() << SecondTN.getAsTemplateDecl(); + return; + } + } + } S.Diag(Fn->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch) - << *Cand->DeductionFailure.getFirstArg() - << *Cand->DeductionFailure.getSecondArg(); + << FirstTA << SecondTA; return; - + } // TODO: diagnose these individually, then kill off // note_ovl_candidate_bad_deduction, which is uselessly vague. case Sema::TDK_MiscellaneousDeductionFailure: @@ -9090,17 +9133,19 @@ private: = S.DeduceTemplateArguments(FunctionTemplate, &OvlExplicitTemplateArgs, TargetFunctionType, Specialization, - Info)) { + Info, /*InOverloadResolution=*/true)) { // FIXME: make a note of the failed deduction for diagnostics. (void)Result; return false; } - // Template argument deduction ensures that we have an exact match. + // 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. Specialization = cast<FunctionDecl>(Specialization->getCanonicalDecl()); - assert(TargetFunctionType - == Context.getCanonicalType(Specialization->getType())); + assert(S.isSameOrCompatibleFunctionType( + Context.getCanonicalType(Specialization->getType()), + Context.getCanonicalType(TargetFunctionType))); Matches.push_back(std::make_pair(CurAccessFunPair, Specialization)); return true; } @@ -9122,6 +9167,13 @@ private: if (S.CheckCUDATarget(Caller, FunDecl)) return false; + // If any candidate has a placeholder return type, trigger its deduction + // now. + if (S.getLangOpts().CPlusPlus1y && + FunDecl->getResultType()->isUndeducedType() && + S.DeduceReturnType(FunDecl, SourceExpr->getLocStart(), Complain)) + return false; + QualType ResultTy; if (Context.hasSameUnqualifiedType(TargetFunctionType, FunDecl->getType()) || @@ -9365,7 +9417,8 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, TemplateDeductionInfo Info(ovl->getNameLoc()); if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs, - Specialization, Info)) { + Specialization, Info, + /*InOverloadResolution=*/true)) { // FIXME: make a note of the failed deduction for diagnostics. (void)Result; continue; @@ -9387,6 +9440,11 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, if (FoundResult) *FoundResult = I.getPair(); } + if (Matched && getLangOpts().CPlusPlus1y && + Matched->getResultType()->isUndeducedType() && + DeduceReturnType(Matched, ovl->getExprLoc(), Complain)) + return 0; + return Matched; } @@ -9913,7 +9971,8 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, case OR_Success: { FunctionDecl *FDecl = (*Best)->Function; SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl); - SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc()); + if (SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc())) + return ExprError(); Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl); return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs, RParenLoc, ExecConfig); @@ -10046,6 +10105,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, NumArgs = 2; } + ArrayRef<Expr *> ArgsArray(Args, NumArgs); + if (Input->isTypeDependent()) { if (Fns.empty()) return Owned(new (Context) UnaryOperator(Input, @@ -10060,8 +10121,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); - return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, - llvm::makeArrayRef(Args, NumArgs), + return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, ArgsArray, Context.DependentTy, VK_RValue, OpLoc, false)); @@ -10071,20 +10131,18 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, OverloadCandidateSet CandidateSet(OpLoc); // Add the candidates from the given function set. - AddFunctionCandidates(Fns, llvm::makeArrayRef(Args, NumArgs), CandidateSet, - false); + AddFunctionCandidates(Fns, ArgsArray, CandidateSet, false); // Add operator candidates that are member functions. - AddMemberOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet); + AddMemberOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); // Add candidates from ADL. - AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true, - OpLoc, llvm::makeArrayRef(Args, NumArgs), - /*ExplicitTemplateArgs*/ 0, + AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true, OpLoc, + ArgsArray, /*ExplicitTemplateArgs*/ 0, CandidateSet); // Add builtin operator candidates. - AddBuiltinOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet); + AddBuiltinOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -10135,8 +10193,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, Args[0] = Input; CallExpr *TheCall = - new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), - llvm::makeArrayRef(Args, NumArgs), + new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), ArgsArray, ResultTy, VK, OpLoc, false); if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, @@ -10162,8 +10219,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, // 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, - llvm::makeArrayRef(Args, NumArgs))) + if (DiagnoseTwoPhaseOperatorLookup(*this, Op, OpLoc, ArgsArray)) // FIXME: Recover by calling the found function. return ExprError(); @@ -10176,8 +10232,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, << UnaryOperator::getOpcodeStr(Opc) << Input->getType() << Input->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, - llvm::makeArrayRef(Args, NumArgs), + CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); @@ -10187,8 +10242,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, << UnaryOperator::getOpcodeStr(Opc) << getDeletedOrUnavailableSuffix(Best->Function) << Input->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, - llvm::makeArrayRef(Args, NumArgs), + CandidateSet.NoteCandidates(*this, OCD_AllCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); } @@ -10296,7 +10350,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, AddFunctionCandidates(Fns, Args, CandidateSet, false); // Add operator candidates that are member functions. - AddMemberOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet); + AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet); // Add candidates from ADL. AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true, @@ -10305,7 +10359,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, CandidateSet); // Add builtin operator candidates. - AddBuiltinOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet); + AddBuiltinOperatorCandidates(Op, OpLoc, Args, CandidateSet); bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -10526,10 +10580,10 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, // Subscript can only be overloaded as a member function. // Add operator candidates that are member functions. - AddMemberOperatorCandidates(OO_Subscript, LLoc, Args, 2, CandidateSet); + AddMemberOperatorCandidates(OO_Subscript, LLoc, Args, CandidateSet); // Add builtin operator candidates. - AddBuiltinOperatorCandidates(OO_Subscript, LLoc, Args, 2, CandidateSet); + AddBuiltinOperatorCandidates(OO_Subscript, LLoc, Args, CandidateSet); bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -10796,7 +10850,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, Method = cast<CXXMethodDecl>(Best->Function); FoundDecl = Best->FoundDecl; CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl); - DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc()); + if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc())) + return ExprError(); break; case OR_No_Viable_Function: @@ -10937,7 +10992,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Object.get()->getType(), - Object.get()->Classify(Context), Args, NumArgs, CandidateSet, + Object.get()->Classify(Context), + llvm::makeArrayRef(Args, NumArgs), CandidateSet, /*SuppressUserConversions=*/ false); } @@ -11047,7 +11103,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, Best->Conversions[0].UserDefined.ConversionFunction); CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl); - DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc); + if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc)) + return ExprError(); // We selected one of the surrogate functions that converts the // object parameter to a function pointer. Perform the conversion @@ -11229,7 +11286,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) { for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Base->getType(), Base->Classify(Context), - 0, 0, CandidateSet, /*SuppressUserConversions=*/false); + None, CandidateSet, /*SuppressUserConversions=*/false); } bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -11344,7 +11401,7 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R, // 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; ArgIdx != Args.size(); ++ArgIdx) { + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { ExprResult InputInit = PerformCopyInitialization( InitializedEntity::InitializeParameter(Context, FD->getParamDecl(ArgIdx)), SourceLocation(), Args[ArgIdx]); @@ -11401,7 +11458,7 @@ Sema::BuildForRangeBeginEndCall(Scope *S, SourceLocation Loc, << RangeLoc << BEF << Range->getType(); return FRS_DiagnosticIssued; } - *CallExpr = ActOnCallExpr(S, MemberRef.get(), Loc, MultiExprArg(), Loc, 0); + *CallExpr = ActOnCallExpr(S, MemberRef.get(), Loc, None, Loc, 0); if (CallExpr->isInvalid()) { *CallExpr = ExprError(); Diag(Range->getLocStart(), diag::note_in_for_range) |