https://github.com/MythreyaK updated 
https://github.com/llvm/llvm-project/pull/173136

>From 4b5b1dcd3cfd26b0192905f8679ec29967e36f27 Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Thu, 18 Dec 2025 23:21:50 -0800
Subject: [PATCH 1/6] [clang] Add FixItHint for designated init order

---
 clang/lib/Sema/SemaInit.cpp | 59 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index cc6ddf568d346..3eb648506e758 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -31,8 +31,10 @@
 #include "clang/Sema/SemaHLSL.h"
 #include "clang/Sema/SemaObjC.h"
 #include "llvm/ADT/APInt.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -3092,6 +3094,60 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
         PrevField = *FI;
       }
 
+      const auto GenerateDesignatedInitReorderingFixit = [&]() -> FixItHint {
+        struct ReorderInfo {
+          int Pos{};
+          const Expr *InitExpr{};
+        };
+
+        llvm::SmallDenseMap<IdentifierInfo *, int> MemberNameInx{};
+        llvm::SmallVector<ReorderInfo, 16> ReorderedInitExprs{};
+
+        const auto *CxxRecord =
+            IList->getSemanticForm()->getType()->getAsCXXRecordDecl();
+
+        for (const auto &Field : CxxRecord->fields()) {
+          MemberNameInx[Field->getIdentifier()] = Field->getFieldIndex();
+        }
+
+        for (const auto *Init : IList->inits()) {
+          if (const auto *DI = dyn_cast_if_present<DesignatedInitExpr>(Init)) {
+            // We expect only one Designator
+            if (DI->size() != 1)
+              return {};
+
+            const auto *const FieldName = DI->getDesignator(0)->getFieldName();
+            // In case we have an unknown initializer in the source, not in the
+            // record
+            if (MemberNameInx.contains(FieldName))
+              ReorderedInitExprs.emplace_back(
+                  ReorderInfo{MemberNameInx.at(FieldName), Init});
+          }
+        }
+
+        llvm::sort(ReorderedInitExprs,
+                   [](const auto &A, const auto &B) { return A.Pos < B.Pos; });
+
+        // generate replacement
+        llvm::SmallString<128> FixedInitList{};
+        SourceManager &SM = SemaRef.getSourceManager();
+        const LangOptions &LangOpts = SemaRef.getLangOpts();
+
+        FixedInitList += "{";
+        for (const auto &Item : ReorderedInitExprs) {
+          CharSourceRange CharRange =
+              CharSourceRange::getTokenRange(Item.InitExpr->getSourceRange());
+          const auto InitText =
+              Lexer::getSourceText(CharRange, SM, LangOpts) + ", ";
+          FixedInitList += InitText.str();
+        }
+        FixedInitList.pop_back_n(2); // remove trailing comma
+        FixedInitList += "}";
+
+        return FixItHint::CreateReplacement(IList->getSourceRange(),
+                                            FixedInitList);
+      };
+
       if (PrevField &&
           PrevField->getFieldIndex() > KnownField->getFieldIndex()) {
         SemaRef.Diag(DIE->getInit()->getBeginLoc(),
@@ -3101,9 +3157,10 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
         unsigned OldIndex = StructuredIndex - 1;
         if (StructuredList && OldIndex <= StructuredList->getNumInits()) {
           if (Expr *PrevInit = StructuredList->getInit(OldIndex)) {
+            auto ReorderFixit = GenerateDesignatedInitReorderingFixit();
             SemaRef.Diag(PrevInit->getBeginLoc(),
                          diag::note_previous_field_init)
-                << PrevField << PrevInit->getSourceRange();
+                << PrevField << PrevInit->getSourceRange() << ReorderFixit;
           }
         }
       }

>From 69981c7cb03f5f0445eb3235643d029822d90f57 Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Thu, 18 Dec 2025 23:32:09 -0800
Subject: [PATCH 2/6] Replace exprs instead of regenerating everything

---
 clang/lib/Sema/SemaInit.cpp | 103 ++++++++++++++++++------------------
 1 file changed, 52 insertions(+), 51 deletions(-)

diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 3eb648506e758..46ca85bfa37a5 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3094,59 +3094,60 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
         PrevField = *FI;
       }
 
-      const auto GenerateDesignatedInitReorderingFixit = [&]() -> FixItHint {
-        struct ReorderInfo {
-          int Pos{};
-          const Expr *InitExpr{};
-        };
+      const auto GenerateDesignatedInitReorderingFixit =
+          [&](SemaBase::SemaDiagnosticBuilder &Diags) {
+            struct ReorderInfo {
+              int Pos{};
+              const Expr *InitExpr{};
+            };
 
-        llvm::SmallDenseMap<IdentifierInfo *, int> MemberNameInx{};
-        llvm::SmallVector<ReorderInfo, 16> ReorderedInitExprs{};
+            llvm::SmallDenseMap<IdentifierInfo *, int> MemberNameInx{};
+            llvm::SmallVector<ReorderInfo, 16> ReorderedInitExprs{};
 
-        const auto *CxxRecord =
-            IList->getSemanticForm()->getType()->getAsCXXRecordDecl();
+            const auto *CxxRecord =
+                IList->getSemanticForm()->getType()->getAsCXXRecordDecl();
 
-        for (const auto &Field : CxxRecord->fields()) {
-          MemberNameInx[Field->getIdentifier()] = Field->getFieldIndex();
-        }
+            for (const auto &Field : CxxRecord->fields()) {
+              MemberNameInx[Field->getIdentifier()] = Field->getFieldIndex();
+            }
 
-        for (const auto *Init : IList->inits()) {
-          if (const auto *DI = dyn_cast_if_present<DesignatedInitExpr>(Init)) {
-            // We expect only one Designator
-            if (DI->size() != 1)
-              return {};
-
-            const auto *const FieldName = DI->getDesignator(0)->getFieldName();
-            // In case we have an unknown initializer in the source, not in the
-            // record
-            if (MemberNameInx.contains(FieldName))
-              ReorderedInitExprs.emplace_back(
-                  ReorderInfo{MemberNameInx.at(FieldName), Init});
-          }
-        }
+            for (const auto *Init : IList->inits()) {
+              if (const auto *DI =
+                      dyn_cast_if_present<DesignatedInitExpr>(Init)) {
+                // We expect only one Designator
+                if (DI->size() != 1)
+                  return;
+
+                const auto *const FieldName =
+                    DI->getDesignator(0)->getFieldName();
+                // In case we have an unknown initializer in the source, not in
+                // the record
+                if (MemberNameInx.contains(FieldName))
+                  ReorderedInitExprs.emplace_back(
+                      ReorderInfo{MemberNameInx.at(FieldName), Init});
+              }
+            }
 
-        llvm::sort(ReorderedInitExprs,
-                   [](const auto &A, const auto &B) { return A.Pos < B.Pos; });
-
-        // generate replacement
-        llvm::SmallString<128> FixedInitList{};
-        SourceManager &SM = SemaRef.getSourceManager();
-        const LangOptions &LangOpts = SemaRef.getLangOpts();
-
-        FixedInitList += "{";
-        for (const auto &Item : ReorderedInitExprs) {
-          CharSourceRange CharRange =
-              CharSourceRange::getTokenRange(Item.InitExpr->getSourceRange());
-          const auto InitText =
-              Lexer::getSourceText(CharRange, SM, LangOpts) + ", ";
-          FixedInitList += InitText.str();
-        }
-        FixedInitList.pop_back_n(2); // remove trailing comma
-        FixedInitList += "}";
+            llvm::sort(ReorderedInitExprs, [](const auto &A, const auto &B) {
+              return A.Pos < B.Pos;
+            });
+
+            llvm::SmallString<128> FixedInitList{};
+            SourceManager &SM = SemaRef.getSourceManager();
+            const LangOptions &LangOpts = SemaRef.getLangOpts();
 
-        return FixItHint::CreateReplacement(IList->getSourceRange(),
-                                            FixedInitList);
-      };
+            // loop over each existing expression and apply replacement
+            for (const auto &[OrigExpr, Repl] :
+                 llvm::zip(IList->inits(), ReorderedInitExprs)) {
+              CharSourceRange CharRange = CharSourceRange::getTokenRange(
+                  Repl.InitExpr->getSourceRange());
+              const auto InitText =
+                  Lexer::getSourceText(CharRange, SM, LangOpts);
+
+              Diags << FixItHint::CreateReplacement(OrigExpr->getSourceRange(),
+                                                    InitText.str());
+            }
+          };
 
       if (PrevField &&
           PrevField->getFieldIndex() > KnownField->getFieldIndex()) {
@@ -3157,10 +3158,10 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
         unsigned OldIndex = StructuredIndex - 1;
         if (StructuredList && OldIndex <= StructuredList->getNumInits()) {
           if (Expr *PrevInit = StructuredList->getInit(OldIndex)) {
-            auto ReorderFixit = GenerateDesignatedInitReorderingFixit();
-            SemaRef.Diag(PrevInit->getBeginLoc(),
-                         diag::note_previous_field_init)
-                << PrevField << PrevInit->getSourceRange() << ReorderFixit;
+            auto Diags = SemaRef.Diag(PrevInit->getBeginLoc(),
+                                      diag::note_previous_field_init)
+                         << PrevField << PrevInit->getSourceRange();
+            GenerateDesignatedInitReorderingFixit(Diags);
           }
         }
       }

>From 0e34b77dcb06899dd29c17eaad4a32f24cbec60b Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Fri, 19 Dec 2025 02:21:22 -0800
Subject: [PATCH 3/6] fix reordering in derived records, add tests

---
 clang/lib/Sema/SemaInit.cpp                   |  8 ++-
 .../SemaCXX/cxx2a-initializer-aggregates.cpp  | 58 ++++++++++++++++++-
 2 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 46ca85bfa37a5..6decf0d809153 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3136,9 +3136,13 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
             SourceManager &SM = SemaRef.getSourceManager();
             const LangOptions &LangOpts = SemaRef.getLangOpts();
 
-            // loop over each existing expression and apply replacement
+            // In a derived Record, first n base-classes are initialized first.
+            // They do not use designated init, so skip them
+            const auto IListInits =
+                IList->inits().drop_front(CxxRecord->getNumBases());
+            // loop over each existing expressions and apply replacement
             for (const auto &[OrigExpr, Repl] :
-                 llvm::zip(IList->inits(), ReorderedInitExprs)) {
+                 llvm::zip(IListInits, ReorderedInitExprs)) {
               CharSourceRange CharRange = CharSourceRange::getTokenRange(
                   Repl.InitExpr->getSourceRange());
               const auto InitText =
diff --git a/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp 
b/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
index 1e9c5fa082d07..caadc84cf2e27 100644
--- a/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
+++ b/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
@@ -6,7 +6,7 @@
 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected -Wno-c99-designator 
-Wno-reorder-init-list -Wno-initializer-overrides
 // RUN: %clang_cc1 -std=c++20 %s 
-verify=cxx20,expected,wmissing,wmissing-designated 
-Wmissing-field-initializers -Wno-c99-designator -Wno-reorder-init-list 
-Wno-initializer-overrides
 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,wmissing 
-Wmissing-field-initializers -Wno-missing-designated-field-initializers 
-Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
-
+// RUN: %clang_cc1 -std=c++20 -Wreorder-init-list 
-fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 namespace class_with_ctor {
   struct A { // cxx20-note 6{{candidate}}
@@ -38,6 +38,8 @@ A a1 = {
   .y = 1, // reorder-note {{previous initialization for field 'y' is here}}
   .x = 2 // reorder-error {{ISO C++ requires field designators to be specified 
in declaration order; field 'y' will be initialized after field 'x'}}
 };
+// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:9}:".x = 2"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:9}:".y = 1"
 int arr[3] = {[1] = 5}; // pedantic-error {{array designators are a C99 
extension}}
 B b = {.a.x = 0}; // pedantic-error {{nested designators are a C99 extension}}
 A a2 = {
@@ -71,6 +73,12 @@ C c = {
   .x = 1, // reorder-error {{declaration order}} override-error {{overrides 
prior initialization}} override-note {{previous}}
   .x = 1, // override-error {{overrides prior initialization}}
 };
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".y = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".y = 1"
 
 struct Foo { int a, b; };
 
@@ -118,6 +126,8 @@ namespace overload_resolution {
   void i() {
     h({.x = 1, .y = 2});
     h({.y = 1, .x = 2}); // reorder-error {{declaration order}} reorder-note 
{{previous}}
+    // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:8-[[@LINE-1]]:14}:".x = 2"
+    // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:22}:".y = 1"
     h({.x = 1}); // expected-error {{ambiguous}}
   }
 
@@ -228,6 +238,16 @@ struct : public A, public B {
     .a = 1, // reorder-error {{field 'b' will be initialized after field 'a'}}
 };
 }
+// CHECK: fix-it:"{{.*}}":{[[@LINE-17]]:4-[[@LINE-17]]:8}:".x=2"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-15]]:4-[[@LINE-15]]:8}:".y=1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".z=0"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".a=4"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".b=3"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:5-[[@LINE-14]]:11}:".a = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-13]]:5-[[@LINE-13]]:11}:".b = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".c = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".d = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".e = 1"
 
 namespace GH63759 {
 struct C {
@@ -248,3 +268,39 @@ void foo() {
                            //
 }
 }
+
+namespace reorder_derived {
+struct col {
+  int r;
+  int g;
+  int b;
+};
+
+struct point {
+  float x;
+  float y;
+  float z;
+};
+
+struct lols : public col, public point {
+  int z2;
+  int z1;
+};
+
+void fosas() {
+  lols a {
+    {.b = 1, .g = 2, .r = 3}, 
+    { .z = 1, .y=2, .x =  3 }, 
+    .z1 = 1,
+    .z2 = 2, 
+  };
+}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:12}:".r = 3"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:14-[[@LINE-7]]:20}:".g = 2"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:22-[[@LINE-8]]:28}:".b = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:15-[[@LINE-8]]:19}:".y=2"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:21-[[@LINE-9]]:28}:".z = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:7-[[@LINE-10]]:13}:".x =  3"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:5-[[@LINE-10]]:12}:".z2 = 2"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:5-[[@LINE-10]]:12}:".z1 = 1"
+} // namespace reorder_derived

>From 71a65a33fba52f124f475ce5ecda4798d947f4cf Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Fri, 19 Dec 2025 02:21:22 -0800
Subject: [PATCH 4/6] simplify tests

---
 .../cxx20-designated-initializer-fixits.cpp   | 105 ++++++++++++++++++
 .../SemaCXX/cxx2a-initializer-aggregates.cpp  |  58 +---------
 2 files changed, 106 insertions(+), 57 deletions(-)
 create mode 100644 clang/test/SemaCXX/cxx20-designated-initializer-fixits.cpp

diff --git a/clang/test/SemaCXX/cxx20-designated-initializer-fixits.cpp 
b/clang/test/SemaCXX/cxx20-designated-initializer-fixits.cpp
new file mode 100644
index 0000000000000..7dfdd62df292f
--- /dev/null
+++ b/clang/test/SemaCXX/cxx20-designated-initializer-fixits.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -std=c++20 %s -Wreorder-init-list 
-fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+
+// These tests are from clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
+struct C { int :0, x, :0, y, :0; };
+C c = {
+  .x = 1,
+  .x = 1,
+  .y = 1,
+  .y = 1,
+  .x = 1,
+  .x = 1,
+};
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".y = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".y = 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,
+         
+         
+   .y=1, 
+         
+   .x=2}, 
+  {.b=3,  
+   .a=4}, 
+    .e = 1, 
+            
+    .d = 1, 
+            
+    .c = 1, 
+    .b = 1, 
+    .a = 1, 
+};
+}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-17]]:4-[[@LINE-17]]:8}:".x=2"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-15]]:4-[[@LINE-15]]:8}:".y=1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".z=0"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".a=4"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".b=3"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:5-[[@LINE-14]]:11}:".a = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-13]]:5-[[@LINE-13]]:11}:".b = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".c = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".d = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".e = 1"
+// END tests from clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
+
+namespace reorder_derived {
+struct col {
+  int r;
+  int g;
+  int b;
+};
+
+struct point {
+  float x;
+  float y;
+  float z;
+};
+
+struct derived : public col, public point {
+  int z2;
+  int z1;
+};
+
+void test() {
+  derived a {
+    {.b = 1, .g = 2, .r = 3}, 
+    { .z = 1, .y=2, .x =  3 },
+    .z1 = 1, 
+    .z2 = 2, 
+  };
+}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:12}:".r = 3"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:14-[[@LINE-7]]:20}:".g = 2"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:22-[[@LINE-8]]:28}:".b = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:15-[[@LINE-8]]:19}:".y=2"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:21-[[@LINE-9]]:28}:".z = 1"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:7-[[@LINE-10]]:13}:".x =  3"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:5-[[@LINE-10]]:12}:".z2 = 2"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:5-[[@LINE-10]]:12}:".z1 = 1"
+} // namespace reorder_derived
diff --git a/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp 
b/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
index caadc84cf2e27..1e9c5fa082d07 100644
--- a/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
+++ b/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
@@ -6,7 +6,7 @@
 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected -Wno-c99-designator 
-Wno-reorder-init-list -Wno-initializer-overrides
 // RUN: %clang_cc1 -std=c++20 %s 
-verify=cxx20,expected,wmissing,wmissing-designated 
-Wmissing-field-initializers -Wno-c99-designator -Wno-reorder-init-list 
-Wno-initializer-overrides
 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,wmissing 
-Wmissing-field-initializers -Wno-missing-designated-field-initializers 
-Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
-// RUN: %clang_cc1 -std=c++20 -Wreorder-init-list 
-fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
 
 namespace class_with_ctor {
   struct A { // cxx20-note 6{{candidate}}
@@ -38,8 +38,6 @@ A a1 = {
   .y = 1, // reorder-note {{previous initialization for field 'y' is here}}
   .x = 2 // reorder-error {{ISO C++ requires field designators to be specified 
in declaration order; field 'y' will be initialized after field 'x'}}
 };
-// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:9}:".x = 2"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:9}:".y = 1"
 int arr[3] = {[1] = 5}; // pedantic-error {{array designators are a C99 
extension}}
 B b = {.a.x = 0}; // pedantic-error {{nested designators are a C99 extension}}
 A a2 = {
@@ -73,12 +71,6 @@ C c = {
   .x = 1, // reorder-error {{declaration order}} override-error {{overrides 
prior initialization}} override-note {{previous}}
   .x = 1, // override-error {{overrides prior initialization}}
 };
-// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".x = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".y = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:3-[[@LINE-7]]:9}:".y = 1"
 
 struct Foo { int a, b; };
 
@@ -126,8 +118,6 @@ namespace overload_resolution {
   void i() {
     h({.x = 1, .y = 2});
     h({.y = 1, .x = 2}); // reorder-error {{declaration order}} reorder-note 
{{previous}}
-    // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:8-[[@LINE-1]]:14}:".x = 2"
-    // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:22}:".y = 1"
     h({.x = 1}); // expected-error {{ambiguous}}
   }
 
@@ -238,16 +228,6 @@ struct : public A, public B {
     .a = 1, // reorder-error {{field 'b' will be initialized after field 'a'}}
 };
 }
-// CHECK: fix-it:"{{.*}}":{[[@LINE-17]]:4-[[@LINE-17]]:8}:".x=2"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-15]]:4-[[@LINE-15]]:8}:".y=1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".z=0"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".a=4"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:4-[[@LINE-14]]:8}:".b=3"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-14]]:5-[[@LINE-14]]:11}:".a = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-13]]:5-[[@LINE-13]]:11}:".b = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".c = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".d = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:5-[[@LINE-12]]:11}:".e = 1"
 
 namespace GH63759 {
 struct C {
@@ -268,39 +248,3 @@ void foo() {
                            //
 }
 }
-
-namespace reorder_derived {
-struct col {
-  int r;
-  int g;
-  int b;
-};
-
-struct point {
-  float x;
-  float y;
-  float z;
-};
-
-struct lols : public col, public point {
-  int z2;
-  int z1;
-};
-
-void fosas() {
-  lols a {
-    {.b = 1, .g = 2, .r = 3}, 
-    { .z = 1, .y=2, .x =  3 }, 
-    .z1 = 1,
-    .z2 = 2, 
-  };
-}
-// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:12}:".r = 3"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:14-[[@LINE-7]]:20}:".g = 2"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:22-[[@LINE-8]]:28}:".b = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:15-[[@LINE-8]]:19}:".y=2"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:21-[[@LINE-9]]:28}:".z = 1"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:7-[[@LINE-10]]:13}:".x =  3"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:5-[[@LINE-10]]:12}:".z2 = 2"
-// CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:5-[[@LINE-10]]:12}:".z1 = 1"
-} // namespace reorder_derived

>From cb96231e700a8fa259c4172d17039985e76314e2 Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Fri, 19 Dec 2025 22:34:38 -0800
Subject: [PATCH 5/6] Update release notes

---
 clang/docs/ReleaseNotes.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 994ac444d4aa1..ba14a50c1f177 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -493,6 +493,9 @@ Improvements to Clang's diagnostics
   carries messages like 'In file included from ...' or 'In module ...'.
   Now the include/import locations are written into 
`sarif.run.result.relatedLocations`.
 
+- Clang now generates a fix-it for C++20 designated initializers when the 
+  initializers do not match the declaration order in the structure. 
+
 Improvements to Clang's time-trace
 ----------------------------------
 

>From ec3fa90c5fc3e8704fb19f9fb43326ae30c95b7f Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Sat, 20 Dec 2025 17:20:03 -0800
Subject: [PATCH 6/6] code review

---
 clang/lib/Sema/SemaInit.cpp | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 6decf0d809153..d6111d675a6f2 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3095,7 +3095,7 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
       }
 
       const auto GenerateDesignatedInitReorderingFixit =
-          [&](SemaBase::SemaDiagnosticBuilder &Diags) {
+          [&](SemaBase::SemaDiagnosticBuilder &Diag) {
             struct ReorderInfo {
               int Pos{};
               const Expr *InitExpr{};
@@ -3107,18 +3107,17 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
             const auto *CxxRecord =
                 IList->getSemanticForm()->getType()->getAsCXXRecordDecl();
 
-            for (const auto &Field : CxxRecord->fields()) {
+            for (const FieldDecl *Field : CxxRecord->fields())
               MemberNameInx[Field->getIdentifier()] = Field->getFieldIndex();
-            }
 
-            for (const auto *Init : IList->inits()) {
+            for (const Expr *Init : IList->inits()) {
               if (const auto *DI =
                       dyn_cast_if_present<DesignatedInitExpr>(Init)) {
                 // We expect only one Designator
                 if (DI->size() != 1)
                   return;
 
-                const auto *const FieldName =
+                const IdentifierInfo *const FieldName =
                     DI->getDesignator(0)->getFieldName();
                 // In case we have an unknown initializer in the source, not in
                 // the record
@@ -3128,9 +3127,10 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
               }
             }
 
-            llvm::sort(ReorderedInitExprs, [](const auto &A, const auto &B) {
-              return A.Pos < B.Pos;
-            });
+            llvm::sort(ReorderedInitExprs,
+                       [](const ReorderInfo &A, const ReorderInfo &B) {
+                         return A.Pos < B.Pos;
+                       });
 
             llvm::SmallString<128> FixedInitList{};
             SourceManager &SM = SemaRef.getSourceManager();
@@ -3138,18 +3138,18 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
 
             // In a derived Record, first n base-classes are initialized first.
             // They do not use designated init, so skip them
-            const auto IListInits =
+            const ArrayRef<clang::Expr *> IListInits =
                 IList->inits().drop_front(CxxRecord->getNumBases());
             // loop over each existing expressions and apply replacement
             for (const auto &[OrigExpr, Repl] :
                  llvm::zip(IListInits, ReorderedInitExprs)) {
               CharSourceRange CharRange = CharSourceRange::getTokenRange(
                   Repl.InitExpr->getSourceRange());
-              const auto InitText =
+              const StringRef InitText =
                   Lexer::getSourceText(CharRange, SM, LangOpts);
 
-              Diags << FixItHint::CreateReplacement(OrigExpr->getSourceRange(),
-                                                    InitText.str());
+              Diag << FixItHint::CreateReplacement(OrigExpr->getSourceRange(),
+                                                   InitText.str());
             }
           };
 
@@ -3162,10 +3162,11 @@ InitListChecker::CheckDesignatedInitializer(const 
InitializedEntity &Entity,
         unsigned OldIndex = StructuredIndex - 1;
         if (StructuredList && OldIndex <= StructuredList->getNumInits()) {
           if (Expr *PrevInit = StructuredList->getInit(OldIndex)) {
-            auto Diags = SemaRef.Diag(PrevInit->getBeginLoc(),
-                                      diag::note_previous_field_init)
-                         << PrevField << PrevInit->getSourceRange();
-            GenerateDesignatedInitReorderingFixit(Diags);
+            SemaBase::SemaDiagnosticBuilder Diag =
+                SemaRef.Diag(PrevInit->getBeginLoc(),
+                             diag::note_previous_field_init)
+                << PrevField << PrevInit->getSourceRange();
+            GenerateDesignatedInitReorderingFixit(Diag);
           }
         }
       }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to