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/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index e325a25..69a577f 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.
- const LValueReferenceType *ParamRefType =
- Param->getType()->getAs<LValueReferenceType>();
- if (!ParamRefType)
- return false;
+ CanQualType PointeeType = Context.getCanonicalType(Param->getType());
+ if (CanQual<LValueReferenceType> ParamRefType =
+ PointeeType->getAs<LValueReferenceType>())
+ PointeeType = ParamRefType->getPointeeType();
- // Is it a reference to our class type?
- CanQualType PointeeType
- = Context.getCanonicalType(ParamRefType->getPointeeType());
+ // Do we have our class type?
CanQualType ClassTy
= Context.getCanonicalType(Context.getTagDeclType(getParent()));
if (PointeeType.getUnqualifiedType() != ClassTy)