shafik created this revision.
shafik added reviewers: aaron.ballman, cor3ntin.
Herald added a project: All.
shafik requested review of this revision.

In C++ we are not allowed to use designated initializers to initialize fields 
out of order. In some cases when diagnosing this we are crashing because we are 
not indexing correctly and therefore going out of bounds.

This fixes: https://github.com/llvm/llvm-project/issues/63605


https://reviews.llvm.org/D154675

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
@@ -63,7 +63,7 @@
   .x = 1, // override-note {{previous}}
   .x = 1, // override-error {{overrides prior initialization}} override-note 
{{previous}}
   .y = 1, // override-note {{previous}}
-  .y = 1, // override-error {{overrides prior initialization}}
+  .y = 1, // override-error {{overrides prior initialization}} // reorder-note 
{{previous initialization for field 'y' is here}}
   .x = 1, // reorder-error {{declaration order}} override-error {{overrides 
prior initialization}} override-note {{previous}}
   .x = 1, // override-error {{overrides prior initialization}}
 };
@@ -177,3 +177,22 @@
     h({.a = 1});
   }
 }
+
+namespace GH63605 {
+struct {
+  unsigned : 2;
+  unsigned a : 6;
+  unsigned : 1;
+  unsigned b : 6;
+  unsigned : 2;
+  unsigned c : 6;
+  unsigned d : 1;
+  unsigned e : 2;
+} data = {
+    .e = 1, // reorder-note {{previous initialization for field 'e' is here}}
+    .d = 1, // reorder-error {{field 'e' will be initialized after field 'd'}} 
// reorder-note {{previous initialization for field 'd' is here}}
+    .c = 1, // reorder-error {{field 'd' will be initialized after field 'c'}} 
// reorder-note {{previous initialization for field 'c' is here}}
+    .b = 1, // reorder-error {{field 'c' will be initialized after field 'b'}} 
// reorder-note {{previous initialization for field 'e' is here}}
+    .a = 1, // reorder-error {{field 'e' will be initialized after field 'a'}}
+};
+}
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -2844,7 +2844,7 @@
         SemaRef.Diag(DIE->getBeginLoc(), diag::ext_designated_init_reordered)
             << KnownField << PrevField << DIE->getSourceRange();
 
-        unsigned OldIndex = NumBases + PrevField->getFieldIndex();
+        unsigned OldIndex = NumBases + StructuredIndex - 1;
         if (StructuredList && OldIndex <= StructuredList->getNumInits()) {
           if (Expr *PrevInit = StructuredList->getInit(OldIndex)) {
             SemaRef.Diag(PrevInit->getBeginLoc(),


Index: clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
===================================================================
--- clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
+++ clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
@@ -63,7 +63,7 @@
   .x = 1, // override-note {{previous}}
   .x = 1, // override-error {{overrides prior initialization}} override-note {{previous}}
   .y = 1, // override-note {{previous}}
-  .y = 1, // override-error {{overrides prior initialization}}
+  .y = 1, // override-error {{overrides prior initialization}} // reorder-note {{previous initialization for field 'y' is here}}
   .x = 1, // reorder-error {{declaration order}} override-error {{overrides prior initialization}} override-note {{previous}}
   .x = 1, // override-error {{overrides prior initialization}}
 };
@@ -177,3 +177,22 @@
     h({.a = 1});
   }
 }
+
+namespace GH63605 {
+struct {
+  unsigned : 2;
+  unsigned a : 6;
+  unsigned : 1;
+  unsigned b : 6;
+  unsigned : 2;
+  unsigned c : 6;
+  unsigned d : 1;
+  unsigned e : 2;
+} data = {
+    .e = 1, // reorder-note {{previous initialization for field 'e' is here}}
+    .d = 1, // reorder-error {{field 'e' will be initialized after field 'd'}} // reorder-note {{previous initialization for field 'd' is here}}
+    .c = 1, // reorder-error {{field 'd' will be initialized after field 'c'}} // reorder-note {{previous initialization for field 'c' is here}}
+    .b = 1, // reorder-error {{field 'c' will be initialized after field 'b'}} // reorder-note {{previous initialization for field 'e' is here}}
+    .a = 1, // reorder-error {{field 'e' will be initialized after field 'a'}}
+};
+}
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -2844,7 +2844,7 @@
         SemaRef.Diag(DIE->getBeginLoc(), diag::ext_designated_init_reordered)
             << KnownField << PrevField << DIE->getSourceRange();
 
-        unsigned OldIndex = NumBases + PrevField->getFieldIndex();
+        unsigned OldIndex = NumBases + StructuredIndex - 1;
         if (StructuredList && OldIndex <= StructuredList->getNumInits()) {
           if (Expr *PrevInit = StructuredList->getInit(OldIndex)) {
             SemaRef.Diag(PrevInit->getBeginLoc(),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to