A constructor template cannot be instantiated to a copy
constructor. Make sure that such declarations can never be formed.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88718 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index fa31cc5..30d046f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3909,6 +3909,9 @@
         << 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 3948b22..70b080e 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2237,7 +2237,9 @@
     // argument doesn't participate in overload resolution.
   }
 
-  if (!CandidateSet.isNewCandidate(Function))
+  // 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())
     return;
     
   // Add this candidate
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index fa45806..17b4e5f 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -1247,7 +1247,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 47d2701..0e42bd6 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -658,6 +658,12 @@
                                                     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))
@@ -709,14 +715,6 @@
       Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
   }
 
-  if (FunctionTemplate && !TemplateParams) {
-    // Record this function template specialization.
-    Function->setFunctionTemplateSpecialization(SemaRef.Context,
-                                                FunctionTemplate,
-                                                &TemplateArgs.getInnermost(),
-                                                InsertPos);
-  }
-
   return Function;
 }
 
@@ -811,9 +809,17 @@
     if (D->isOutOfLine())
       FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext());
     Method->setDescribedFunctionTemplate(FunctionTemplate);
-  } else if (!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.
     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.
@@ -825,6 +831,20 @@
     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();
 
@@ -843,13 +863,6 @@
       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,