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 875b021..a3a5d4e 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1568,7 +1568,7 @@
                                     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 @@
   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 5507c57..44181b1 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -2558,6 +2558,7 @@
 }
 
 void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
+                                   SourceLocation Loc,
                                    Expr **Args, unsigned NumArgs,
                                    ADLResult &Result,
                                    bool StdNamespaceIsAssociated) {
@@ -2578,6 +2579,13 @@
       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 c7f3394..1a27dbf 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -740,8 +740,6 @@
 /// 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 @@
 /// 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 @@
   // 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 @@
 
   if (ULE->requiresADL())
     AddArgumentDependentLookupCandidates(ULE->getName(), /*Operator*/ false,
+                                         ULE->getExprLoc(),
                                          Args, NumArgs,
                                          ExplicitTemplateArgs,
                                          CandidateSet,
@@ -9665,7 +9664,7 @@
 
   // Add candidates from ADL.
   AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
-                                       Args, NumArgs,
+                                       OpLoc, Args, NumArgs,
                                        /*ExplicitTemplateArgs*/ 0,
                                        CandidateSet);
 
@@ -9886,7 +9885,7 @@
 
   // 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 501e2d6..913d13f 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -536,10 +536,30 @@
 }
 
 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()>()));
 }