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

- Fix variable typo/spellings, and add missing flag assignment and additional 
test to catch it.


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,15 @@
         }
       }
 
+      // 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 +2059,13 @@
       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;
@@ -2976,6 +2997,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) {
@@ -2999,6 +3021,7 @@
                                             D.getRBracketLoc()));
         InitExpressions.push_back(Index);
       }
+      HasArrayDesignator = true;
       break;
     }
 
@@ -3042,6 +3065,7 @@
           InitExpressions.push_back(EndIndex);
         }
       }
+      HasArrayDesignator = true;
       break;
     }
     }
@@ -3060,8 +3084,11 @@
                                  Init.getAs<Expr>());
 
   if (!getLangOpts().C99)
-    Diag(DIE->getBeginLoc(), diag::ext_designated_init)
-        << DIE->getSourceRange();
+    // 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