r213201 - When list-initializing an object of class type, if we pick an initializer list
Richard Smith
richard-llvm at metafoo.co.uk
Wed Jul 16 14:33:43 PDT 2014
Author: rsmith
Date: Wed Jul 16 16:33:43 2014
New Revision: 213201
URL: http://llvm.org/viewvc/llvm-project?rev=213201&view=rev
Log:
When list-initializing an object of class type, if we pick an initializer list
constructor (and pass it an implicitly-generated std::initializer_list object),
be sure to mark the resulting construction as list-initialization. This fixes
an assert in template instantiation where we previously thought we'd got direct
non-list initialization without any parentheses.
Modified:
cfe/trunk/include/clang/Sema/Initialization.h
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
Modified: cfe/trunk/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=213201&r1=213200&r2=213201&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Initialization.h (original)
+++ cfe/trunk/include/clang/Sema/Initialization.h Wed Jul 16 16:33:43 2014
@@ -669,9 +669,9 @@ public:
SK_ConversionSequence,
/// \brief Perform an implicit conversion sequence without narrowing.
SK_ConversionSequenceNoNarrowing,
- /// \brief Perform list-initialization without a constructor
+ /// \brief Perform list-initialization without a constructor.
SK_ListInitialization,
- /// \brief Perform list-initialization with a constructor.
+ /// \brief Perform list-initialization with an initializer list constructor.
SK_ListConstructorCall,
/// \brief Unwrap the single-element initializer list for a reference.
SK_UnwrapInitList,
@@ -679,6 +679,9 @@ public:
SK_RewrapInitList,
/// \brief Perform initialization via a constructor.
SK_ConstructorInitialization,
+ /// \brief Perform initialization via a constructor, taking arguments from
+ /// a single InitListExpr.
+ SK_ConstructorInitializationFromList,
/// \brief Zero-initialize the object
SK_ZeroInitialization,
/// \brief C assignment
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=213201&r1=213200&r2=213201&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Wed Jul 16 16:33:43 2014
@@ -2764,6 +2764,7 @@ void InitializationSequence::Step::Destr
case SK_UnwrapInitList:
case SK_RewrapInitList:
case SK_ConstructorInitialization:
+ case SK_ConstructorInitializationFromList:
case SK_ZeroInitialization:
case SK_CAssignment:
case SK_StringInit:
@@ -2944,8 +2945,9 @@ InitializationSequence
bool HadMultipleCandidates,
bool FromInitList, bool AsInitList) {
Step S;
- S.Kind = FromInitList && !AsInitList ? SK_ListConstructorCall
- : SK_ConstructorInitialization;
+ S.Kind = FromInitList ? AsInitList ? SK_ListConstructorCall
+ : SK_ConstructorInitializationFromList
+ : SK_ConstructorInitialization;
S.Type = T;
S.Function.HadMultipleCandidates = HadMultipleCandidates;
S.Function.Function = Constructor;
@@ -5781,6 +5783,7 @@ InitializationSequence::Perform(Sema &S,
}
case SK_ConstructorInitialization:
+ case SK_ConstructorInitializationFromList:
case SK_ListConstructorCall:
case SK_ZeroInitialization:
break;
@@ -6109,7 +6112,7 @@ InitializationSequence::Perform(Sema &S,
break;
}
- case SK_ListConstructorCall: {
+ case SK_ConstructorInitializationFromList: {
// When an initializer list is passed for a parameter of type "reference
// to object", we don't get an EK_Temporary entity, but instead an
// EK_Parameter entity with reference type.
@@ -6128,7 +6131,7 @@ InitializationSequence::Perform(Sema &S,
Entity,
Kind, Arg, *Step,
ConstructorInitRequiresZeroInit,
- /*IsListInitialization*/ true,
+ /*IsListInitialization*/true,
InitList->getLBraceLoc(),
InitList->getRBraceLoc());
break;
@@ -6150,7 +6153,8 @@ InitializationSequence::Perform(Sema &S,
break;
}
- case SK_ConstructorInitialization: {
+ case SK_ConstructorInitialization:
+ case SK_ListConstructorCall: {
// When an initializer list is passed for a parameter of type "reference
// to object", we don't get an EK_Temporary entity, but instead an
// EK_Parameter entity with reference type.
@@ -6160,13 +6164,12 @@ InitializationSequence::Perform(Sema &S,
InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(
Entity.getType().getNonReferenceType());
bool UseTemporary = Entity.getType()->isReferenceType();
- CurInit = PerformConstructorInitialization(S, UseTemporary ? TempEntity
- : Entity,
- Kind, Args, *Step,
- ConstructorInitRequiresZeroInit,
- /*IsListInitialization*/ false,
- /*LBraceLoc*/ SourceLocation(),
- /*RBraceLoc*/ SourceLocation());
+ CurInit = PerformConstructorInitialization(
+ S, UseTemporary ? TempEntity : Entity, Kind, Args, *Step,
+ ConstructorInitRequiresZeroInit,
+ /*IsListInitialization*/Step->Kind == SK_ListConstructorCall,
+ /*LBraceLoc*/SourceLocation(),
+ /*RBraceLoc*/SourceLocation());
break;
}
@@ -6175,7 +6178,7 @@ InitializationSequence::Perform(Sema &S,
++NextStep;
if (NextStep != StepEnd &&
(NextStep->Kind == SK_ConstructorInitialization ||
- NextStep->Kind == SK_ListConstructorCall)) {
+ NextStep->Kind == SK_ConstructorInitializationFromList)) {
// The need for zero-initialization is recorded directly into
// the call to the object's constructor within the next step.
ConstructorInitRequiresZeroInit = true;
@@ -7011,10 +7014,6 @@ void InitializationSequence::dump(raw_os
OS << "list aggregate initialization";
break;
- case SK_ListConstructorCall:
- OS << "list initialization via constructor";
- break;
-
case SK_UnwrapInitList:
OS << "unwrap reference initializer list";
break;
@@ -7027,6 +7026,14 @@ void InitializationSequence::dump(raw_os
OS << "constructor initialization";
break;
+ case SK_ConstructorInitializationFromList:
+ OS << "list initialization via constructor";
+ break;
+
+ case SK_ListConstructorCall:
+ OS << "list initialization via initializer list constructor";
+ break;
+
case SK_ZeroInitialization:
OS << "zero initialization";
break;
Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=213201&r1=213200&r2=213201&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Wed Jul 16 16:33:43 2014
@@ -238,3 +238,19 @@ namespace DR1070 {
S s[3] = { {1, 2, 3}, {4, 5} }; // ok
S *p = new S[3] { {1, 2, 3}, {4, 5} }; // ok
}
+
+namespace ListInitInstantiate {
+ struct A {
+ A(std::initializer_list<A>);
+ };
+ struct B : A {
+ B(int);
+ };
+ template<typename T> struct X {
+ X();
+ A a;
+ };
+ template<typename T> X<T>::X() : a{B{0}, B{1}} {}
+
+ X<int> x;
+}
More information about the cfe-commits
mailing list