Revert r88718, which does NOT solve the constructor-template-as-copy-constructor issue. Big thanks to John for finding this

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88724 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 69a577f..e325a25 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -707,23 +707,23 @@
   //   if its first parameter is of type X&, const X&, volatile X& or
   //   const volatile X&, and either there are no other parameters
   //   or else all other parameters have default arguments (8.3.6).
-  //
-  // Note that we also test cv 'X' as a copy constructor, even though it is
-  // ill-formed, because this helps enforce C++ [class.copy]p3.
   if ((getNumParams() < 1) ||
       (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
+      (getPrimaryTemplate() != 0) ||
       (getDescribedFunctionTemplate() != 0))
     return false;
 
   const ParmVarDecl *Param = getParamDecl(0);
 
   // Do we have a reference type? Rvalue references don't count.
-  CanQualType PointeeType = Context.getCanonicalType(Param->getType());
-  if (CanQual<LValueReferenceType> ParamRefType =
-                                     PointeeType->getAs<LValueReferenceType>())
-    PointeeType = ParamRefType->getPointeeType();
+  const LValueReferenceType *ParamRefType =
+    Param->getType()->getAs<LValueReferenceType>();
+  if (!ParamRefType)
+    return false;
 
-  // Do we have our class type?
+  // Is it a reference to our class type?
+  CanQualType PointeeType
+    = Context.getCanonicalType(ParamRefType->getPointeeType());
   CanQualType ClassTy 
     = Context.getCanonicalType(Context.getTagDeclType(getParent()));
   if (PointeeType.getUnqualifiedType() != ClassTy)
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 30d046f..fa31cc5 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3909,9 +3909,6 @@
         << FD->getNameAsCString() << "dllimport";
     }
   }
-  
-  assert(ExprTemporaries.empty() && "Leftover temporaries before starting");
-
   return DeclPtrTy::make(FD);
 }
 
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 70b080e..3948b22 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2237,9 +2237,7 @@
     // argument doesn't participate in overload resolution.
   }
 
-  // FIXME: It would be nice if it were safe to keep invalid methods in the
-  // overload set (but it isn't due to broken copy constructors).
-  if (!CandidateSet.isNewCandidate(Function) || Function->isInvalidDecl())
+  if (!CandidateSet.isNewCandidate(Function))
     return;
     
   // Add this candidate
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index fcec654..244bb37 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -1286,7 +1286,7 @@
   for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
     if (Deduced[I].isNull()) {
       Info.Param = makeTemplateParameter(
-                          const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+                            const_cast<NamedDecl *>(TemplateParams->getParam(I)));
       return TDK_Incomplete;
     }
 
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 0e42bd6..47d2701 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -658,12 +658,6 @@
                                                     TemplateParams, Function);
     Function->setDescribedFunctionTemplate(FunctionTemplate);
     FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext());
-  } else if (FunctionTemplate) {
-    // Record this function template specialization.
-    Function->setFunctionTemplateSpecialization(SemaRef.Context,
-                                                FunctionTemplate,
-                                                &TemplateArgs.getInnermost(),
-                                                InsertPos);
   }
     
   if (InitFunctionInstantiation(Function, D))
@@ -715,6 +709,14 @@
       Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
   }
 
+  if (FunctionTemplate && !TemplateParams) {
+    // Record this function template specialization.
+    Function->setFunctionTemplateSpecialization(SemaRef.Context,
+                                                FunctionTemplate,
+                                                &TemplateArgs.getInnermost(),
+                                                InsertPos);
+  }
+
   return Function;
 }
 
@@ -809,17 +811,9 @@
     if (D->isOutOfLine())
       FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext());
     Method->setDescribedFunctionTemplate(FunctionTemplate);
-  } else if (FunctionTemplate) {
-    // Record this function template specialization.
-    Method->setFunctionTemplateSpecialization(SemaRef.Context,
-                                              FunctionTemplate,
-                                              &TemplateArgs.getInnermost(),
-                                              InsertPos);
-  } else {
-    // Record this instantiation of a member function.
+  } else if (!FunctionTemplate)
     Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
-  }
-  
+
   // If we are instantiating a member function defined
   // out-of-line, the instantiation will have the same lexical
   // context (which will be a namespace scope) as the template.
@@ -831,20 +825,6 @@
     Params[P]->setOwningFunction(Method);
   Method->setParams(SemaRef.Context, Params.data(), Params.size());
 
-  if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Method)) {
-    // 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.
-    if (FunctionTemplate && !TemplateParams &&
-        Constructor->isCopyConstructor(SemaRef.Context)) {
-      SemaRef.Diag(Constructor->getLocation(), 
-                   diag::err_constructor_template_is_copy_constructor)
-        << Constructor;
-      Method->setInvalidDecl();
-      return Method;
-    }
-  }
-    
   if (InitMethodInstantiation(Method, D))
     Method->setInvalidDecl();
 
@@ -863,6 +843,13 @@
       PrevDecl = 0;
   }
 
+  if (FunctionTemplate && !TemplateParams)
+    // Record this function template specialization.
+    Method->setFunctionTemplateSpecialization(SemaRef.Context,
+                                              FunctionTemplate,
+                                              &TemplateArgs.getInnermost(),
+                                              InsertPos);
+
   bool Redeclaration = false;
   bool OverloadableAttrRequired = false;
   SemaRef.CheckFunctionDeclaration(Method, PrevDecl, false, Redeclaration,