r182983 - Fix handling of braced-init-list as reference initializer within aggregate
Richard Smith
richard-llvm at metafoo.co.uk
Thu May 30 19:56:17 PDT 2013
Author: rsmith
Date: Thu May 30 21:56:17 2013
New Revision: 182983
URL: http://llvm.org/viewvc/llvm-project?rev=182983&view=rev
Log:
Fix handling of braced-init-list as reference initializer within aggregate
initialization. Previously we would incorrectly require an extra set of braces
around such initializers.
Modified:
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp
cfe/trunk/test/SemaCXX/cxx98-compat.cpp
cfe/trunk/test/SemaCXX/decl-init-ref.cpp
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=182983&r1=182982&r2=182983&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu May 30 21:56:17 2013
@@ -821,6 +821,11 @@ void InitListChecker::CheckSubElementTyp
InitListExpr *StructuredList,
unsigned &StructuredIndex) {
Expr *expr = IList->getInit(Index);
+
+ if (ElemType->isReferenceType())
+ return CheckReferenceType(Entity, IList, ElemType, Index,
+ StructuredList, StructuredIndex);
+
if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
if (!ElemType->isRecordType() || ElemType->isAggregateType()) {
unsigned newIndex = 0;
@@ -840,13 +845,9 @@ void InitListChecker::CheckSubElementTyp
// C++ initialization is handled later.
}
- if (ElemType->isScalarType()) {
+ if (ElemType->isScalarType())
return CheckScalarType(Entity, IList, ElemType, Index,
StructuredList, StructuredIndex);
- } else if (ElemType->isReferenceType()) {
- return CheckReferenceType(Entity, IList, ElemType, Index,
- StructuredList, StructuredIndex);
- }
if (const ArrayType *arrayType = SemaRef.Context.getAsArrayType(ElemType)) {
// arrayType can be incomplete if we're initializing a flexible
Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp?rev=182983&r1=182982&r2=182983&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp Thu May 30 21:56:17 2013
@@ -97,3 +97,24 @@ namespace b7891773 {
int g(const ptr &);
int k = g({ f<int> });
}
+
+namespace inner_init {
+ struct A { int n; };
+ struct B { A &&r; };
+ B b1 { 0 }; // expected-error {{reference to type 'inner_init::A' could not bind to an rvalue of type 'int'}}
+ B b2 { { 0 } };
+ B b3 { { { 0 } } }; // expected-warning {{braces around scalar init}}
+
+ struct C { C(int); };
+ struct D { C &&r; };
+ D d1 { 0 }; // ok, 0 implicitly converts to C
+ D d2 { { 0 } }; // ok, { 0 } calls C(0)
+ D d3 { { { 0 } } }; // ok, { { 0 } } calls C({ 0 })
+ D d4 { { { { 0 } } } }; // expected-warning {{braces around scalar init}}
+
+ struct E { explicit E(int); }; // expected-note 2{{here}}
+ struct F { E &&r; };
+ F f1 { 0 }; // expected-error {{could not bind to an rvalue of type 'int'}}
+ F f2 { { 0 } }; // expected-error {{chosen constructor is explicit}}
+ F f3 { { { 0 } } }; // expected-error {{chosen constructor is explicit}}
+}
Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=182983&r1=182982&r2=182983&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Thu May 30 21:56:17 2013
@@ -73,7 +73,7 @@ int InitList(int i = {}) { // expected-w
Ctor c2 = { 3.0, 4l }; // expected-warning {{constructor call from initializer list is incompatible with C++98}}
InitListCtor ilc = { true, false }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}}
const int &r = { 0 }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
- struct { int a; const int &r; } rr = { 0, {{0}} }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
+ struct { int a; const int &r; } rr = { 0, {0} }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}}
}
struct DelayedDefaultArgumentParseInitList {
Modified: cfe/trunk/test/SemaCXX/decl-init-ref.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decl-init-ref.cpp?rev=182983&r1=182982&r2=182983&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/decl-init-ref.cpp (original)
+++ cfe/trunk/test/SemaCXX/decl-init-ref.cpp Thu May 30 21:56:17 2013
@@ -26,4 +26,7 @@ int main() {
}
struct PR6139 { A (&x)[1]; };
-PR6139 x = {{A()}}; // expected-error{{non-const lvalue reference to type 'A [1]' cannot bind to a temporary of type 'A'}}
+PR6139 x = {{A()}}; // expected-error{{non-const lvalue reference to type 'A [1]' cannot bind to an initializer list temporary}}
+
+struct PR6139b { A (&x)[1]; };
+PR6139b y = {A()}; // expected-error{{non-const lvalue reference to type 'A [1]' cannot bind to a temporary of type 'A'}}
More information about the cfe-commits
mailing list