]> granicus.if.org Git - clang/commitdiff
Fix a regression from r151117: ADL requires that we attempt to complete any
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 25 Feb 2012 06:24:24 +0000 (06:24 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 25 Feb 2012 06:24:24 +0000 (06:24 +0000)
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

include/clang/Sema/Sema.h
lib/Sema/SemaLookup.cpp
lib/Sema/SemaOverload.cpp
test/SemaCXX/overload-call.cpp

index 875b021f96971891829c1bd450cfa78ab5941fd8..a3a5d4ea0363b57ce5939fb91f85f5b433399b68 100644 (file)
@@ -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);
index 5507c5770dfd32459ee93ad2377c799799e80460..44181b141dd91fb4156d17edd4c0e8fd59694fab 100644 (file)
@@ -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
index c7f33943437b48b3f71a048233b3ac30b510f0a3..1a27dbf962b67fcdee3b0667483a0fd1e9d90867 100644 (file)
@@ -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);
 
index 501e2d6fb2f2dcd5a7a64f168bd66873f0f81129..913d13f99b8726c0b87c234ab5197a72a9c90163 100644 (file)
@@ -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<typename T> struct S {
     friend int f(const S&);
   };
   extern S<int> s;
   int k = f(s);
+
+  template<typename T> struct Op {
+    friend bool operator==(const Op &, const Op &);
+  };
+  extern Op<char> op;
+  bool b = op == op;
+
+  // ... and not in other cases! Nothing here requires U<int()> to be complete.
+  // (Note that instantiating U<int()> will fail.)
+  template<typename T> struct U {
+    T t;
+  };
+  struct Consumer {
+    template<typename T>
+    int operator()(const U<T> &);
+  };
+  template<typename T> U<T> &make();
+  Consumer c;
+  int n = sizeof(c(make<int()>()));
 }