summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-11-08 17:16:59 +0000
committerDouglas Gregor <dgregor@apple.com>2010-11-08 17:16:59 +0000
commitbd6b17f4efb44b1b002600e67c28454f05ff8665 (patch)
tree927788525c6463a06aea9c7b8b46481ae421868d /clang/lib
parent2cd1fd4a828812e3b45b5144ae8cb7ce950792cd (diff)
downloadbcm5719-llvm-bd6b17f4efb44b1b002600e67c28454f05ff8665.tar.gz
bcm5719-llvm-bd6b17f4efb44b1b002600e67c28454f05ff8665.zip
Improve our handling of C++ [class.copy]p3, which specifies that a
constructor template will not be used to copy a class object to a value of its own type. We were eliminating all constructor templates whose specializations look like a copy constructor, which eliminated important candidates. Fixes PR8182. llvm-svn: 118418
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/DeclCXX.cpp8
-rw-r--r--clang/lib/Sema/SemaInit.cpp38
-rw-r--r--clang/lib/Sema/SemaOverload.cpp2
3 files changed, 32 insertions, 16 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 17f2dfda648..bcb47baa24f 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -1176,7 +1176,7 @@ bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {
(getNumParams() > 1 && getParamDecl(1)->hasDefaultArg());
}
-bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const {
+bool CXXConstructorDecl::isSpecializationCopyingObject() const {
if ((getNumParams() < 1) ||
(getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
(getPrimaryTemplate() == 0) ||
@@ -1188,12 +1188,6 @@ bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const {
ASTContext &Context = getASTContext();
CanQualType ParamType = Context.getCanonicalType(Param->getType());
- // Strip off the lvalue reference, if any.
- if (CanQual<LValueReferenceType> ParamRefType
- = ParamType->getAs<LValueReferenceType>())
- ParamType = ParamRefType->getPointeeType();
-
-
// Is it the same as our our class type?
CanQualType ClassTy
= Context.getCanonicalType(Context.getTagDeclType(getParent()));
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index f45893df86d..e601a7d328c 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3391,17 +3391,39 @@ static ExprResult CopyObject(Sema &S,
OverloadCandidateSet CandidateSet(Loc);
for (llvm::tie(Con, ConEnd) = S.LookupConstructors(Class);
Con != ConEnd; ++Con) {
- // Only consider copy constructors.
- CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(*Con);
- if (!Constructor || Constructor->isInvalidDecl() ||
- !Constructor->isCopyConstructor() ||
- !Constructor->isConvertingConstructor(/*AllowExplicit=*/false))
+ // Only consider copy constructors and constructor templates.
+ CXXConstructorDecl *Constructor = 0;
+
+ if ((Constructor = dyn_cast<CXXConstructorDecl>(*Con))) {
+ // Handle copy constructors, only.
+ if (!Constructor || Constructor->isInvalidDecl() ||
+ !Constructor->isCopyConstructor() ||
+ !Constructor->isConvertingConstructor(/*AllowExplicit=*/false))
+ continue;
+
+ DeclAccessPair FoundDecl
+ = DeclAccessPair::make(Constructor, Constructor->getAccess());
+ S.AddOverloadCandidate(Constructor, FoundDecl,
+ &CurInitExpr, 1, CandidateSet);
+ continue;
+ }
+
+ // Handle constructor templates.
+ FunctionTemplateDecl *ConstructorTmpl = cast<FunctionTemplateDecl>(*Con);
+ if (ConstructorTmpl->isInvalidDecl())
+ continue;
+
+ Constructor = cast<CXXConstructorDecl>(
+ ConstructorTmpl->getTemplatedDecl());
+ if (!Constructor->isConvertingConstructor(/*AllowExplicit=*/false))
continue;
+ // FIXME: Do we need to limit this to copy-constructor-like
+ // candidates?
DeclAccessPair FoundDecl
- = DeclAccessPair::make(Constructor, Constructor->getAccess());
- S.AddOverloadCandidate(Constructor, FoundDecl,
- &CurInitExpr, 1, CandidateSet);
+ = DeclAccessPair::make(ConstructorTmpl, ConstructorTmpl->getAccess());
+ S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, 0,
+ &CurInitExpr, 1, CandidateSet, true);
}
OverloadCandidateSet::iterator Best;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 3ed79fd4613..440f5acdbc2 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -3457,7 +3457,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
// of a class object to an object of its class type.
QualType ClassType = Context.getTypeDeclType(Constructor->getParent());
if (NumArgs == 1 &&
- Constructor->isCopyConstructorLikeSpecialization() &&
+ Constructor->isSpecializationCopyingObject() &&
(Context.hasSameUnqualifiedType(ClassType, Args[0]->getType()) ||
IsDerivedFrom(Args[0]->getType(), ClassType)))
return;
OpenPOWER on IntegriCloud