[clang] c9ef33e - [Clang] Fix crash when emitting diagnostic for out of order designated initializers in C++

Shafik Yaghmour via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 14 16:00:24 PDT 2023


Author: Shafik Yaghmour
Date: 2023-07-14T15:57:51-07:00
New Revision: c9ef33e1d8a8aeb68a18f24af6d9fc9ab4ecf257

URL: https://github.com/llvm/llvm-project/commit/c9ef33e1d8a8aeb68a18f24af6d9fc9ab4ecf257
DIFF: https://github.com/llvm/llvm-project/commit/c9ef33e1d8a8aeb68a18f24af6d9fc9ab4ecf257.diff

LOG: [Clang] Fix crash when emitting diagnostic for out of order designated initializers in C++

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

Differential Revision: https://reviews.llvm.org/D154675

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaInit.cpp
    clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d55757183d58e9..c501903815955d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -695,6 +695,9 @@ Bug Fixes to C++ Support
 - Fix handling of using-declarations in the init statements of for
   loop declarations.
   (`#63627 <https://github.com/llvm/llvm-project/issues/63627>`_)
+- Fix crash when emitting diagnostic for out of order designated initializers
+  in C++.
+  (`#63605 <https://github.com/llvm/llvm-project/issues/63605>`_)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 289643f690da4c..8e2177bce4fd79 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2847,7 +2847,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
         SemaRef.Diag(DIE->getBeginLoc(), diag::ext_designated_init_reordered)
             << KnownField << PrevField << DIE->getSourceRange();
 
-        unsigned OldIndex = NumBases + PrevField->getFieldIndex();
+        unsigned OldIndex = StructuredIndex - 1;
         if (StructuredList && OldIndex <= StructuredList->getNumInits()) {
           if (Expr *PrevInit = StructuredList->getInit(OldIndex)) {
             SemaRef.Diag(PrevInit->getBeginLoc(),
@@ -2951,8 +2951,12 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
     // If this the first designator, our caller will continue checking
     // the rest of this struct/class/union subobject.
     if (IsFirstDesignator) {
+      if (Field != RD->field_end() && Field->isUnnamedBitfield())
+        ++Field;
+
       if (NextField)
         *NextField = Field;
+
       StructuredIndex = FieldIndex;
       return false;
     }

diff  --git a/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp b/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
index 3cc3f9cf6dff4d..eaca12a5f5c0c0 100644
--- a/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
+++ b/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
@@ -63,7 +63,7 @@ C c = {
   .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,43 @@ namespace no_unwrap {
     h({.a = 1});
   }
 }
+
+namespace GH63605 {
+struct A  {
+  unsigned x;
+  unsigned y;
+  unsigned z;
+};
+
+struct B {
+  unsigned a;
+  unsigned b;
+};
+
+struct : public A, public B {
+  unsigned : 2;
+  unsigned a : 6;
+  unsigned : 1;
+  unsigned b : 6;
+  unsigned : 2;
+  unsigned c : 6;
+  unsigned d : 1;
+  unsigned e : 2;
+} data = {
+  {.z=0,
+         // pedantic-note at -1 {{first non-designated initializer is here}}
+         // reorder-note at -2 {{previous initialization for field 'z' is here}}
+   .y=1, // reorder-error {{field 'z' will be initialized after field 'y'}}
+         // reorder-note at -1 {{previous initialization for field 'y' is here}}
+   .x=2}, // reorder-error {{field 'y' will be initialized after field 'x'}}
+  {.b=3,  // reorder-note {{previous initialization for field 'b' is here}}
+   .a=4}, // reorder-error {{field 'b' will be initialized after field 'a'}}
+    .e = 1, // reorder-note {{previous initialization for field 'e' is here}}
+            // pedantic-error at -1 {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}}
+    .d = 1, // reorder-error {{field 'e' will be initialized after field 'd'}}
+            // reorder-note at -1 {{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 'b' is here}}
+    .a = 1, // reorder-error {{field 'b' will be initialized after field 'a'}}
+};
+}


        


More information about the cfe-commits mailing list