diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-04-01 19:54:59 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-04-01 19:54:59 +0000 |
commit | 70e24fccc8ef4aa8be03a778e9655bfcfa79dd14 (patch) | |
tree | 6efa1d81ce9377e7d4ecf8d481b665d76976c1a9 /lib/Sema/SemaInit.cpp | |
parent | 4a5f724538cbc275370c9504e8169ce92503256c (diff) |
Properly handle explicit constructors in list-initialization. Fixes PR12120.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153849 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 125149edc2..f748db943a 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2465,6 +2465,7 @@ bool InitializationSequence::isAmbiguous() const { case FK_VariableLengthArrayHasInitializer: case FK_PlaceholderType: case FK_InitListElementCopyFailure: + case FK_ExplicitConstructor: return false; case FK_ReferenceInitOverloadFailed: @@ -2896,7 +2897,7 @@ static void TryConstructorInitialization(Sema &S, // Determine whether we are allowed to call explicit constructors or // explicit conversion operators. - bool AllowExplicit = Kind.AllowExplicit(); + bool AllowExplicit = Kind.AllowExplicit() || InitListSyntax; bool CopyInitialization = Kind.getKind() == InitializationKind::IK_Copy; // - Otherwise, if T is a class type, constructors are considered. The @@ -2961,10 +2962,18 @@ static void TryConstructorInitialization(Sema &S, return; } + // C++11 [over.match.list]p1: + // In copy-list-initialization, if an explicit constructor is chosen, the + // initializer is ill-formed. + CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function); + if (InitListSyntax && !Kind.AllowExplicit() && CtorDecl->isExplicit()) { + Sequence.SetFailed(InitializationSequence::FK_ExplicitConstructor); + return; + } + // Add the constructor initialization step. Any cv-qualification conversion is // subsumed by the initialization. bool HadMultipleCandidates = (CandidateSet.size() > 1); - CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function); Sequence.AddConstructorInitializationStep(CtorDecl, Best->FoundDecl.getAccess(), DestType, HadMultipleCandidates, @@ -5729,6 +5738,18 @@ bool InitializationSequence::Diagnose(Sema &S, } break; } + + case FK_ExplicitConstructor: { + S.Diag(Kind.getLocation(), diag::err_selected_explicit_constructor) + << Args[0]->getSourceRange(); + OverloadCandidateSet::iterator Best; + OverloadingResult Ovl + = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); + assert(Ovl == OR_Success && "Inconsistent overload resolution"); + CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function); + S.Diag(CtorDecl->getLocation(), diag::note_constructor_declared_here); + break; + } } PrintInitLocationNote(S, Entity); @@ -5843,6 +5864,10 @@ void InitializationSequence::dump(raw_ostream &OS) const { case FK_InitListElementCopyFailure: OS << "copy construction of initializer list element failed"; break; + + case FK_ExplicitConstructor: + OS << "list copy initialization chose explicit constructor"; + break; } OS << '\n'; return; |