]> granicus.if.org Git - clang/commitdiff
Fix handling of braced-init-list as reference initializer within aggregate
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 31 May 2013 02:56:17 +0000 (02:56 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 31 May 2013 02:56:17 +0000 (02:56 +0000)
initialization. Previously we would incorrectly require an extra set of braces
around such initializers.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182983 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaInit.cpp
test/SemaCXX/cxx0x-initializer-references.cpp
test/SemaCXX/cxx98-compat.cpp
test/SemaCXX/decl-init-ref.cpp

index fdb8777d41e6a58ea760da3e5827353f586e4512..2e11bc98acbdb738bd517ff027fd2ff24e1e5049 100644 (file)
@@ -821,6 +821,11 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
                                           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::CheckSubElementType(const InitializedEntity &Entity,
     // 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
index 283c32ac2efca8d3c0f4aa8cfd2dca6eda985ee5..48236fdf76f03fbd2e83aa61b160d52f584d50d3 100644 (file)
@@ -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}}
+}
index 7d36770f5d20f6ab51bddb605ffd73bab29c2515..51a59fd6fc70c86c95a1b2a48016d33e408438fc 100644 (file)
@@ -73,7 +73,7 @@ int InitList(int i = {}) { // expected-warning {{generalized initializer lists a
   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 {
index 4c635c1a244781aaeb7a7eb5a7538a3dc8eaa332..6802e0c52c5929b3131fe039fb68aadc3a479651 100644 (file)
@@ -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'}}