diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-11-08 17:16:59 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-11-08 17:16:59 +0000 |
commit | 6493cc50b66c2d097b3e22514bbe303048c4a8ff (patch) | |
tree | 95cab209c6d292e458dc8122e498550f837233da /lib/Sema/SemaInit.cpp | |
parent | 67e40d4a8627b951e98ad92fd927433f325a1c30 (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.cpp | 38 |
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; |