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