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,