<p>It seems broke -Asserts builds.</p>
<div class="gmail_quote">2012/07/07 17:37 "Richard Smith" <<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>>:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: rsmith<br>
Date: Sat Jul 7 03:35:56 2012<br>
New Revision: 159896<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=159896&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=159896&view=rev</a><br>
Log:<br>
PR12670: Support for initializing an array of non-aggregate class type from an<br>
initializer list. Patch by Olivier Goffart, with extra testcases by Meador Inge<br>
and Daniel Lunow.<br>
<br>
Added:<br>
cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp<br>
cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp<br>
Modified:<br>
cfe/trunk/lib/Sema/SemaInit.cpp<br>
cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp<br>
cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaInit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=159896&r1=159895&r2=159896&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=159896&r1=159895&r2=159896&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sat Jul 7 03:35:56 2012<br>
@@ -687,22 +687,21 @@<br>
} else if (DeclType->isVectorType()) {<br>
CheckVectorType(Entity, IList, DeclType, Index,<br>
StructuredList, StructuredIndex);<br>
- } else if (DeclType->isAggregateType()) {<br>
- if (DeclType->isRecordType()) {<br>
- RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();<br>
- CheckStructUnionTypes(Entity, IList, DeclType, RD->field_begin(),<br>
- SubobjectIsDesignatorContext, Index,<br>
- StructuredList, StructuredIndex,<br>
- TopLevelObject);<br>
- } else if (DeclType->isArrayType()) {<br>
- llvm::APSInt Zero(<br>
- SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()),<br>
- false);<br>
- CheckArrayType(Entity, IList, DeclType, Zero,<br>
- SubobjectIsDesignatorContext, Index,<br>
- StructuredList, StructuredIndex);<br>
- } else<br>
- llvm_unreachable("Aggregate that isn't a structure or array?!");<br>
+ } else if (DeclType->isRecordType()) {<br>
+ assert(DeclType->isAggregateType() &&<br>
+ "non-aggregate records should be handed in CheckSubElementType");<br>
+ RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();<br>
+ CheckStructUnionTypes(Entity, IList, DeclType, RD->field_begin(),<br>
+ SubobjectIsDesignatorContext, Index,<br>
+ StructuredList, StructuredIndex,<br>
+ TopLevelObject);<br>
+ } else if (DeclType->isArrayType()) {<br>
+ llvm::APSInt Zero(<br>
+ SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()),<br>
+ false);<br>
+ CheckArrayType(Entity, IList, DeclType, Zero,<br>
+ SubobjectIsDesignatorContext, Index,<br>
+ StructuredList, StructuredIndex);<br>
} else if (DeclType->isVoidType() || DeclType->isFunctionType()) {<br>
// This type is invalid, issue a diagnostic.<br>
++Index;<br>
@@ -710,19 +709,6 @@<br>
SemaRef.Diag(IList->getLocStart(), diag::err_illegal_initializer_type)<br>
<< DeclType;<br>
hadError = true;<br>
- } else if (DeclType->isRecordType()) {<br>
- // C++ [dcl.init]p14:<br>
- // [...] If the class is an aggregate (8.5.1), and the initializer<br>
- // is a brace-enclosed list, see 8.5.1.<br>
- //<br>
- // Note: 8.5.1 is handled below; here, we diagnose the case where<br>
- // we have an initializer list and a destination type that is not<br>
- // an aggregate.<br>
- // FIXME: In C++0x, this is yet another form of initialization.<br>
- if (!VerifyOnly)<br>
- SemaRef.Diag(IList->getLocStart(), diag::err_init_non_aggr_init_list)<br>
- << DeclType << IList->getSourceRange();<br>
- hadError = true;<br>
} else if (DeclType->isReferenceType()) {<br>
CheckReferenceType(Entity, IList, DeclType, Index,<br>
StructuredList, StructuredIndex);<br>
@@ -747,18 +733,25 @@<br>
unsigned &StructuredIndex) {<br>
Expr *expr = IList->getInit(Index);<br>
if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {<br>
- unsigned newIndex = 0;<br>
- unsigned newStructuredIndex = 0;<br>
- InitListExpr *newStructuredList<br>
- = getStructuredSubobjectInit(IList, Index, ElemType,<br>
- StructuredList, StructuredIndex,<br>
- SubInitList->getSourceRange());<br>
- CheckExplicitInitList(Entity, SubInitList, ElemType, newIndex,<br>
- newStructuredList, newStructuredIndex);<br>
- ++StructuredIndex;<br>
- ++Index;<br>
- return;<br>
- } else if (ElemType->isScalarType()) {<br>
+ if (!ElemType->isRecordType() || ElemType->isAggregateType()) {<br>
+ unsigned newIndex = 0;<br>
+ unsigned newStructuredIndex = 0;<br>
+ InitListExpr *newStructuredList<br>
+ = getStructuredSubobjectInit(IList, Index, ElemType,<br>
+ StructuredList, StructuredIndex,<br>
+ SubInitList->getSourceRange());<br>
+ CheckExplicitInitList(Entity, SubInitList, ElemType, newIndex,<br>
+ newStructuredList, newStructuredIndex);<br>
+ ++StructuredIndex;<br>
+ ++Index;<br>
+ return;<br>
+ }<br>
+ assert(SemaRef.getLangOpts().CPlusPlus &&<br>
+ "non-aggregate records are only possible in C++");<br>
+ // C++ initialization is handled later.<br>
+ }<br>
+<br>
+ if (ElemType->isScalarType()) {<br>
return CheckScalarType(Entity, IList, ElemType, Index,<br>
StructuredList, StructuredIndex);<br>
} else if (ElemType->isReferenceType()) {<br>
<br>
Added: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp?rev=159896&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp?rev=159896&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp (added)<br>
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp Sat Jul 7 03:35:56 2012<br>
@@ -0,0 +1,113 @@<br>
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s<br>
+<br>
+namespace std {<br>
+ typedef decltype(sizeof(int)) size_t;<br>
+<br>
+ template <typename E><br>
+ struct initializer_list<br>
+ {<br>
+ const E *p;<br>
+ size_t n;<br>
+ initializer_list(const E *p, size_t n) : p(p), n(n) {}<br>
+ };<br>
+<br>
+ struct string {<br>
+ string(const char *);<br>
+ };<br>
+<br>
+ template<typename A, typename B><br>
+ struct pair {<br>
+ pair(const A&, const B&);<br>
+ };<br>
+}<br>
+<br>
+namespace bullet2 {<br>
+ double ad[] = { 1, 2.0 };<br>
+ int ai[] = { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}<br>
+<br>
+ struct S2 {<br>
+ int m1;<br>
+ double m2, m3;<br>
+ };<br>
+<br>
+ S2 s21 = { 1, 2, 3.0 };<br>
+ S2 s22 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}<br>
+ S2 s23 { };<br>
+}<br>
+<br>
+namespace bullet4_example1 {<br>
+ struct S {<br>
+ S(std::initializer_list<double> d) {}<br>
+ S(std::initializer_list<int> i) {}<br>
+ S() {}<br>
+ };<br>
+<br>
+ S s1 = { 1.0, 2.0, 3.0 };<br>
+ S s2 = { 1, 2, 3 };<br>
+ S s3 = { };<br>
+}<br>
+<br>
+namespace bullet4_example2 {<br>
+ struct Map {<br>
+ Map(std::initializer_list<std::pair<std::string,int>>) {}<br>
+ };<br>
+<br>
+ Map ship = {{"Sophie",14}, {"Surprise",28}};<br>
+}<br>
+<br>
+namespace bullet4_example3 {<br>
+ struct S {<br>
+ S(int, double, double) {}<br>
+ S() {}<br>
+ };<br>
+<br>
+ S s1 = { 1, 2, 3.0 };<br>
+ // FIXME: This is an ill-formed narrowing initialization.<br>
+ S s2 { 1.0, 2, 3 };<br>
+ S s3 {};<br>
+}<br>
+<br>
+namespace bullet5 {<br>
+ struct S {<br>
+ S(std::initializer_list<double>) {}<br>
+ S(const std::string &) {}<br>
+ };<br>
+<br>
+ const S& r1 = { 1, 2, 3.0 };<br>
+ const S& r2 = { "Spinach" };<br>
+ S& r3 = { 1, 2, 3 }; // expected-error {{non-const lvalue reference to type 'bullet5::S' cannot bind to an initializer list temporary}}<br>
+ const int& i1 = { 1 };<br>
+ const int& i2 = { 1.1 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}}<br>
+ const int (&iar)[2] = { 1, 2 };<br>
+}<br>
+<br>
+namespace bullet6 {<br>
+ int x1 {2};<br>
+ int x2 {2.0}; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}<br>
+}<br>
+<br>
+namespace bullet7 {<br>
+ int** pp {};<br>
+}<br>
+<br>
+namespace bullet8 {<br>
+ struct A { int i; int j; };<br>
+ A a1 { 1, 2 };<br>
+ A a2 { 1.2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}}<br>
+<br>
+ struct B {<br>
+ B(std::initializer_list<int> i) {}<br>
+ };<br>
+ B b1 { 1, 2 };<br>
+ B b2 { 1, 2.0 };<br>
+<br>
+ struct C {<br>
+ C(int i, double j) {}<br>
+ };<br>
+ C c1 = { 1, 2.2 };<br>
+ // FIXME: This is an ill-formed narrowing initialization.<br>
+ C c2 = { 1.1, 2 }; // expected-warning {{implicit conversion}}<br>
+<br>
+ int j { 1 };<br>
+ int k { };<br>
+}<br>
<br>
Added: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp?rev=159896&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp?rev=159896&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp (added)<br>
+++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-constructors.cpp Sat Jul 7 03:35:56 2012<br>
@@ -0,0 +1,37 @@<br>
+// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s<br>
+<br>
+struct S {<br>
+ S(int x) { }<br>
+ S(int x, double y, double z) { }<br>
+};<br>
+<br>
+void fn1() {<br>
+ // CHECK: define void @_Z3fn1v<br>
+ S s { 1 };<br>
+ // CHECK: alloca %struct.S, align 1<br>
+ // CHECK: call void @_ZN1SC1Ei(%struct.S* %s, i32 1)<br>
+}<br>
+<br>
+void fn2() {<br>
+ // CHECK: define void @_Z3fn2v<br>
+ S s { 1, 2.0, 3.0 };<br>
+ // CHECK: alloca %struct.S, align 1<br>
+ // CHECK: call void @_ZN1SC1Eidd(%struct.S* %s, i32 1, double 2.000000e+00, double 3.000000e+00)<br>
+}<br>
+<br>
+void fn3() {<br>
+ // CHECK: define void @_Z3fn3v<br>
+ S sa[] { { 1 }, { 2 }, { 3 } };<br>
+ // CHECK: alloca [3 x %struct.S], align 1<br>
+ // CHECK: call void @_ZN1SC1Ei(%struct.S* %arrayinit.begin, i32 1)<br>
+ // CHECK: call void @_ZN1SC1Ei(%struct.S* %arrayinit.element, i32 2)<br>
+ // CHECK: call void @_ZN1SC1Ei(%struct.S* %arrayinit.element1, i32 3)<br>
+}<br>
+<br>
+void fn4() {<br>
+ // CHECK: define void @_Z3fn4v<br>
+ S sa[] { { 1, 2.0, 3.0 }, { 4, 5.0, 6.0 } };<br>
+ // CHECK: alloca [2 x %struct.S], align 1<br>
+ // CHECK: call void @_ZN1SC1Eidd(%struct.S* %arrayinit.begin, i32 1, double 2.000000e+00, double 3.000000e+00)<br>
+ // CHECK: call void @_ZN1SC1Eidd(%struct.S* %arrayinit.element, i32 4, double 5.000000e+00, double 6.000000e+00)<br>
+}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=159896&r1=159895&r2=159896&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=159896&r1=159895&r2=159896&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Sat Jul 7 03:35:56 2012<br>
@@ -1318,3 +1318,15 @@<br>
// actually call it.<br>
static_assert(S{}.t == 0, "");<br>
}<br>
+<br>
+namespace PR12670 {<br>
+ struct S {<br>
+ constexpr S(int a0) : m(a0) {}<br>
+ constexpr S() : m(6) {}<br>
+ int m;<br>
+ };<br>
+ constexpr S x[3] = { {4}, 5 };<br>
+ static_assert(x[0].m == 4, "");<br>
+ static_assert(x[1].m == 5, "");<br>
+ static_assert(x[2].m == 6, "");<br>
+}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp?rev=159896&r1=159895&r2=159896&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp?rev=159896&r1=159895&r2=159896&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp Sat Jul 7 03:35:56 2012<br>
@@ -87,3 +87,32 @@<br>
(void)test4{{{1}}}; // expected-note {{in instantiation of template class 'array_explicit_conversion::A<-1>' requested here}}<br>
}<br>
}<br>
+<br>
+namespace sub_constructor {<br>
+ struct DefaultConstructor { // expected-note 2 {{not viable}}<br>
+ DefaultConstructor(); // expected-note {{not viable}}<br>
+ int x;<br>
+ };<br>
+ struct NoDefaultConstructor1 { // expected-note 2 {{not viable}}<br>
+ NoDefaultConstructor1(int); // expected-note {{not viable}}<br>
+ int x;<br>
+ };<br>
+ struct NoDefaultConstructor2 { // expected-note 4 {{not viable}}<br>
+ NoDefaultConstructor2(int,int); // expected-note 2 {{not viable}}<br>
+ int x;<br>
+ };<br>
+<br>
+ struct Aggr {<br>
+ DefaultConstructor a;<br>
+ NoDefaultConstructor1 b;<br>
+ NoDefaultConstructor2 c;<br>
+ };<br>
+<br>
+ Aggr ok1 { {}, {0} , {0,0} };<br>
+ Aggr ok2 = { {}, {0} , {0,0} };<br>
+ Aggr too_many { {0} , {0} , {0,0} }; // expected-error {{no matching constructor for initialization}}<br>
+ Aggr too_few { {} , {0} , {0} }; // expected-error {{no matching constructor for initialization}}<br>
+ Aggr invalid { {} , {&ok1} , {0,0} }; // expected-error {{no matching constructor for initialization}}<br>
+ NoDefaultConstructor2 array_ok[] = { {0,0} , {0,1} };<br>
+ NoDefaultConstructor2 array_error[] = { {0,0} , {0} }; // expected-error {{no matching constructor for initialization}}<br>
+}<br>
\ No newline at end of file<br>
<br>
Modified: cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp?rev=159896&r1=159895&r2=159896&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp?rev=159896&r1=159895&r2=159896&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp Sat Jul 7 03:35:56 2012<br>
@@ -15,7 +15,7 @@<br>
};<br>
NonAggregate non_aggregate_test = { 1, 2 }; // expected-error{{non-aggregate type 'NonAggregate' cannot be initialized with an initializer list}}<br>
<br>
-NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error 2 {{initialization of non-aggregate type 'NonAggregate' with an initializer list}}<br>
+NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error 2 {{non-aggregate type 'NonAggregate' cannot be initialized with an initializer list}}<br>
<br>
<br>
// C++ [dcl.init.aggr]p3<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>