hintonda updated this revision to Diff 192233.
hintonda added a comment.

- Missed one set of braces.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59754/new/

https://reviews.llvm.org/D59754

Files:
  clang/lib/Sema/SemaInit.cpp
  clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp

Index: clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
===================================================================
--- clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
+++ clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a %s -verify
+// RUN: %clang_cc1 -std=c++2a %s -verify -pedantic
 
 namespace class_with_ctor {
   struct A { // expected-note 6{{candidate}}
@@ -21,3 +21,21 @@
   C c1 = {{}, {}}; // ok, call default ctor twice
   C c2 = {{1, 2}, {3, 4}}; // expected-error 2{{no matching constructor}}
 }
+
+namespace designator {
+struct A { int x, y; };
+struct B { A a; };
+
+// out of order designators
+A a1 = {.y = 1, .x = 2}; // expected-warning {{designated initializers are a C99 feature}}
+
+// array designator
+int arr[3] = {[1] = 5}; // expected-warning {{designated initializers are a C99 feature}}
+
+// nested designator
+B b = {.a.x = 0}; // expected-warning {{designated initializers are a C99 feature}}
+
+// mixed designator and non-designator
+A a2 = {.x = 1, 2}; // expected-warning {{designated initializers are a C99 feature}}
+A a3 = {1, .y = 2}; // expected-warning {{designated initializers are a C99 feature}}
+}
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -1999,6 +1999,7 @@
   bool CheckForMissingFields =
     !IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts());
   bool HasDesignatedInit = false;
+  bool HasNonDesignatedInit = false;
 
   while (Index < IList->getNumInits()) {
     Expr *Init = IList->getInit(Index);
@@ -2013,6 +2014,10 @@
 
       HasDesignatedInit = true;
 
+      auto LastIdx = Field != FieldEnd
+                         ? Field->getFieldIndex()
+                         : std::distance(RD->field_begin(), RD->field_end());
+
       // Handle this designated initializer. Field will be updated to
       // the next field that we'll be initializing.
       if (CheckDesignatedInitializer(Entity, IList, DIE, 0,
@@ -2032,6 +2037,16 @@
         }
       }
 
+      // Warn on out of order and mixed designators in C++20.
+      auto NextIdx = Field != FieldEnd
+                         ? Field->getFieldIndex()
+                         : std::distance(RD->field_begin(), RD->field_end());
+      if (!VerifyOnly && (LastIdx >= NextIdx || HasNonDesignatedInit) &&
+          SemaRef.getLangOpts().CPlusPlus2a) {
+        SemaRef.Diag(Init->getBeginLoc(), diag::ext_designated_init)
+            << Init->getSourceRange();
+      }
+
       InitializedSomething = true;
 
       // Disable check for missing fields when designators are used.
@@ -2045,6 +2060,14 @@
       break;
     }
 
+    HasNonDesignatedInit = true;
+
+    // Warn on mixed designators in C++20.
+    if (!VerifyOnly && HasDesignatedInit && SemaRef.getLangOpts().CPlusPlus2a) {
+      SemaRef.Diag(Init->getBeginLoc(), diag::ext_designated_init)
+          << Init->getSourceRange();
+    }
+
     // We've already initialized a member of a union. We're done.
     if (InitializedSomething && DeclType->isUnionType())
       break;
@@ -2980,6 +3003,7 @@
   bool Invalid = false;
   SmallVector<ASTDesignator, 32> Designators;
   SmallVector<Expr *, 32> InitExpressions;
+  bool HasArrayDesignator = false;
 
   // Build designators and check array designator expressions.
   for (unsigned Idx = 0; Idx < Desig.getNumDesignators(); ++Idx) {
@@ -3003,6 +3027,7 @@
                                             D.getRBracketLoc()));
         InitExpressions.push_back(Index);
       }
+      HasArrayDesignator = true;
       break;
     }
 
@@ -3046,6 +3071,7 @@
           InitExpressions.push_back(EndIndex);
         }
       }
+      HasArrayDesignator = true;
       break;
     }
     }
@@ -3063,9 +3089,14 @@
                                  InitExpressions, Loc, GNUSyntax,
                                  Init.getAs<Expr>());
 
-  if (!getLangOpts().C99)
-    Diag(DIE->getBeginLoc(), diag::ext_designated_init)
-        << DIE->getSourceRange();
+  if (!getLangOpts().C99) {
+    // Warn on nested and array designators in C++20.
+    if (!getLangOpts().CPlusPlus2a || Desig.getNumDesignators() > 1 ||
+        HasArrayDesignator) {
+      Diag(DIE->getBeginLoc(), diag::ext_designated_init)
+          << DIE->getSourceRange();
+    }
+  }
 
   return DIE;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to