From: Richard Smith Date: Sat, 25 Feb 2012 06:24:24 +0000 (+0000) Subject: Fix a regression from r151117: ADL requires that we attempt to complete any X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f5cd5cc9a7ec114ef1a4c08491a37d2327697c4a;p=clang Fix a regression from r151117: ADL requires that we attempt to complete any associated classes, since it can find friend functions declared within them, but overload resolution does not otherwise require argument types to be complete. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151434 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 875b021f96..a3a5d4ea03 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1568,7 +1568,7 @@ public: Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet); void AddArgumentDependentLookupCandidates(DeclarationName Name, - bool Operator, + bool Operator, SourceLocation Loc, Expr **Args, unsigned NumArgs, TemplateArgumentListInfo *ExplicitTemplateArgs, OverloadCandidateSet& CandidateSet, @@ -1814,6 +1814,7 @@ public: CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); void ArgumentDependentLookup(DeclarationName Name, bool Operator, + SourceLocation Loc, Expr **Args, unsigned NumArgs, ADLResult &Functions, bool StdNamespaceIsAssociated = false); diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 5507c5770d..44181b141d 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -2558,6 +2558,7 @@ void ADLResult::insert(NamedDecl *New) { } void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator, + SourceLocation Loc, Expr **Args, unsigned NumArgs, ADLResult &Result, bool StdNamespaceIsAssociated) { @@ -2578,6 +2579,13 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator, T2 = Args[1]->getType(); } + // Try to complete all associated classes, in case they contain a + // declaration of a friend function. + for (AssociatedClassSet::iterator C = AssociatedClasses.begin(), + CEnd = AssociatedClasses.end(); + C != CEnd; ++C) + RequireCompleteType(Loc, Context.getRecordType(*C), 0); + // C++ [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 diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index c7f3394343..1a27dbf962 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -740,8 +740,6 @@ namespace { /// Return true on unrecoverable error. static bool checkPlaceholderForOverload(Sema &S, Expr *&E, UnbridgedCastsSet *unbridgedCasts = 0) { - S.RequireCompleteType(E->getExprLoc(), E->getType(), 0); - if (const BuiltinType *placeholder = E->getType()->getAsPlaceholderType()) { // We can't handle overloaded expressions here because overload // resolution might reasonably tweak them. @@ -7448,7 +7446,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, /// candidate set (C++ [basic.lookup.argdep]). void Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, - bool Operator, + bool Operator, SourceLocation Loc, Expr **Args, unsigned NumArgs, TemplateArgumentListInfo *ExplicitTemplateArgs, OverloadCandidateSet& CandidateSet, @@ -7464,7 +7462,7 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, // we supposed to consider on ADL candidates, anyway? // FIXME: Pass in the explicit template arguments? - ArgumentDependentLookup(Name, Operator, Args, NumArgs, Fns, + ArgumentDependentLookup(Name, Operator, Loc, Args, NumArgs, Fns, StdNamespaceIsAssociated); // Erase all of the candidates we already knew about. @@ -9223,6 +9221,7 @@ void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE, if (ULE->requiresADL()) AddArgumentDependentLookupCandidates(ULE->getName(), /*Operator*/ false, + ULE->getExprLoc(), Args, NumArgs, ExplicitTemplateArgs, CandidateSet, @@ -9665,7 +9664,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, // Add candidates from ADL. AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true, - Args, NumArgs, + OpLoc, Args, NumArgs, /*ExplicitTemplateArgs*/ 0, CandidateSet); @@ -9886,7 +9885,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // Add candidates from ADL. AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true, - Args, 2, + OpLoc, Args, 2, /*ExplicitTemplateArgs*/ 0, CandidateSet); diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp index 501e2d6fb2..913d13f99b 100644 --- a/test/SemaCXX/overload-call.cpp +++ b/test/SemaCXX/overload-call.cpp @@ -536,10 +536,30 @@ namespace rdar9803316 { } namespace IncompleteArg { - // Ensure that overload resolution attempts to complete argument types. + // Ensure that overload resolution attempts to complete argument types when + // performing ADL. template struct S { friend int f(const S&); }; extern S s; int k = f(s); + + template struct Op { + friend bool operator==(const Op &, const Op &); + }; + extern Op op; + bool b = op == op; + + // ... and not in other cases! Nothing here requires U to be complete. + // (Note that instantiating U will fail.) + template struct U { + T t; + }; + struct Consumer { + template + int operator()(const U &); + }; + template U &make(); + Consumer c; + int n = sizeof(c(make())); }