aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaInit.cpp
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
commit6493cc50b66c2d097b3e22514bbe303048c4a8ff (patch)
tree95cab209c6d292e458dc8122e498550f837233da /lib/Sema/SemaInit.cpp
parent67e40d4a8627b951e98ad92fd927433f325a1c30 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118418 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r--lib/Sema/SemaInit.cpp38
1 files changed, 30 insertions, 8 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index f45893df86..e601a7d328 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/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;