[cfe-commits] r142147 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaInit.cpp test/SemaCXX/cxx0x-initializer-aggregates.cpp test/SemaCXX/generalized-initializers.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Sun Oct 16 11:19:28 PDT 2011


Author: cornedbee
Date: Sun Oct 16 13:19:28 2011
New Revision: 142147

URL: http://llvm.org/viewvc/llvm-project?rev=142147&view=rev
Log:
Diagnose when omitting braces in direct list-initialization in C++0x.

This also applies to C99-style aggregate literals, should they be used in C++11, since they are effectively identical to constructor call list-initialization syntax.

Added:
    cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/SemaCXX/generalized-initializers.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=142147&r1=142146&r2=142147&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Oct 16 13:19:28 2011
@@ -2798,6 +2798,9 @@
 def warn_missing_braces : Warning<
   "suggest braces around initialization of subobject">,
   InGroup<DiagGroup<"missing-braces">>, DefaultIgnore;
+def err_missing_braces : Error<
+  "cannot omit braces around initialization of subobject when using direct "
+  "list-initialization">;
 
 def err_redefinition_of_label : Error<"redefinition of label %0">;
 def err_undeclared_label_use : Error<"use of undeclared label %0">;

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=142147&r1=142146&r2=142147&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sun Oct 16 13:19:28 2011
@@ -170,6 +170,7 @@
   Sema &SemaRef;
   bool hadError;
   bool VerifyOnly; // no diagnostics, no structure building
+  bool AllowBraceElision;
   std::map<InitListExpr *, InitListExpr *> SyntacticToSemantic;
   InitListExpr *FullyStructuredList;
 
@@ -260,7 +261,8 @@
 
 public:
   InitListChecker(Sema &S, const InitializedEntity &Entity,
-                  InitListExpr *IL, QualType &T, bool VerifyOnly);
+                  InitListExpr *IL, QualType &T, bool VerifyOnly,
+                  bool AllowBraceElision);
   bool HadError() { return hadError; }
 
   // @brief Retrieves the fully-structured initializer list used for
@@ -466,8 +468,8 @@
 
 InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity,
                                  InitListExpr *IL, QualType &T,
-                                 bool VerifyOnly)
-  : SemaRef(S), VerifyOnly(VerifyOnly) {
+                                 bool VerifyOnly, bool AllowBraceElision)
+  : SemaRef(S), VerifyOnly(VerifyOnly), AllowBraceElision(AllowBraceElision) {
   hadError = false;
 
   unsigned newIndex = 0;
@@ -551,10 +553,14 @@
                         /*SubobjectIsDesignatorContext=*/false, Index,
                         StructuredSubobjectInitList,
                         StructuredSubobjectInitIndex);
-  unsigned EndIndex = (Index == StartIndex? StartIndex : Index - 1);
-  if (!VerifyOnly) {
+
+  if (VerifyOnly) {
+    if (!AllowBraceElision && (T->isArrayType() || T->isRecordType()))
+      hadError = true;
+  } else {
     StructuredSubobjectInitList->setType(T);
 
+    unsigned EndIndex = (Index == StartIndex? StartIndex : Index - 1);
     // Update the structured sub-object initializer so that it's ending
     // range corresponds with the end of the last initializer it used.
     if (EndIndex < ParentIList->getNumInits()) {
@@ -563,10 +569,11 @@
       StructuredSubobjectInitList->setRBraceLoc(EndLoc);
     }
 
-    // Warn about missing braces.
+    // Complain about missing braces.
     if (T->isArrayType() || T->isRecordType()) {
       SemaRef.Diag(StructuredSubobjectInitList->getLocStart(),
-                   diag::warn_missing_braces)
+                    AllowBraceElision ? diag::warn_missing_braces :
+                                        diag::err_missing_braces)
         << StructuredSubobjectInitList->getSourceRange()
         << FixItHint::CreateInsertion(
               StructuredSubobjectInitList->getLocStart(), "{")
@@ -574,6 +581,8 @@
               SemaRef.PP.getLocForEndOfToken(
                                       StructuredSubobjectInitList->getLocEnd()),
               "}");
+      if (!AllowBraceElision)
+        hadError = true;
     }
   }
 }
@@ -2808,7 +2817,9 @@
   }
 
   InitListChecker CheckInitList(S, Entity, InitList,
-          DestType, /*VerifyOnly=*/true);
+          DestType, /*VerifyOnly=*/true,
+          Kind.getKind() != InitializationKind::IK_Direct ||
+            !S.getLangOptions().CPlusPlus0x);
   if (CheckInitList.HadError()) {
     Sequence.SetFailed(InitializationSequence::FK_ListInitializationFailed);
     return;
@@ -4654,7 +4665,9 @@
       InitListExpr *InitList = cast<InitListExpr>(CurInit.get());
       QualType Ty = Step->Type;
       InitListChecker PerformInitList(S, Entity, InitList,
-          ResultType ? *ResultType : Ty, /*VerifyOnly=*/false);
+          ResultType ? *ResultType : Ty, /*VerifyOnly=*/false,
+          Kind.getKind() != InitializationKind::IK_Direct ||
+            !S.getLangOptions().CPlusPlus0x);
       if (PerformInitList.HadError())
         return ExprError();
 
@@ -5180,7 +5193,9 @@
     InitListExpr* InitList = cast<InitListExpr>(Args[0]);
     QualType DestType = Entity.getType();
     InitListChecker DiagnoseInitList(S, Entity, InitList,
-            DestType, /*VerifyOnly=*/false);
+            DestType, /*VerifyOnly=*/false,
+            Kind.getKind() != InitializationKind::IK_Direct ||
+              !S.getLangOptions().CPlusPlus0x);
     assert(DiagnoseInitList.HadError() &&
            "Inconsistent init list check result.");
     break;

Added: cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp?rev=142147&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp (added)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-aggregates.cpp Sun Oct 16 13:19:28 2011
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+namespace aggregate {
+  // Direct list initialization does NOT allow braces to be elided!
+  struct S {
+    int ar[2];
+    struct T {
+      int i1;
+      int i2;
+    } t;
+    struct U {
+      int i1;
+    } u[2];
+    struct V {
+      int var[2];
+    } v;
+  };
+
+  void test() {
+    S s1 = { 1, 2, 3 ,4, 5, 6, 7, 8 }; // no-error
+    S s2{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced
+    S s3{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}}
+    S s4{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}}
+    S s5{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}}
+  }
+}

Modified: cfe/trunk/test/SemaCXX/generalized-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/generalized-initializers.cpp?rev=142147&r1=142146&r2=142147&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/generalized-initializers.cpp (original)
+++ cfe/trunk/test/SemaCXX/generalized-initializers.cpp Sun Oct 16 13:19:28 2011
@@ -40,16 +40,6 @@
 
 namespace integral {
 
-  int function_call() {
-    void takes_int(int);
-    takes_int({1});
-  }
-
-  void inline_init() {
-    (void) int{1};
-    (void) new int{1};
-  }
-
   void initializer_list() {
     std::initializer_list<int> il = { 1, 2, 3 };
     std::initializer_list<double> dl = { 1.0, 2.0, 3 };
@@ -180,28 +170,3 @@
   B g({1, 2, 3});
 
 }
-
-namespace aggregate {
-  // Direct list initialization does NOT allow braces to be elided!
-  struct S {
-    int ar[2];
-    struct T {
-      int i1;
-      int i2;
-    } t;
-    struct U {
-      int i1;
-    } u[2];
-    struct V {
-      int var[2];
-    } v;
-  };
-
-  void test() {
-    S s1 = { 1, 2, 3 ,4, 5, 6, 7, 8 }; // no-error
-    S s2{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced
-    S s3{ 1, 2, 3, 4, 5, 6 }; // xpected-error
-    S s4{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // xpected-error
-    S s5{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // xpected-error
-  }
-}





More information about the cfe-commits mailing list