https://github.com/IvyXu420 updated 
https://github.com/llvm/llvm-project/pull/235265

>From 8c565c58747c72691a15110575d147a27b84fb90 Mon Sep 17 00:00:00 2001
From: Ivy Xu <[email protected]>
Date: Sat, 24 Oct 2026 15:40:04 +0800
Subject: [PATCH 1/4] Fix `IsStructurallyEquivalent` for constexpr BitField

---
 clang/lib/AST/ASTStructuralEquivalence.cpp | 11 ++++++-----
 clang/test/C/C23/n3037.c                   | 13 +++++++++++++
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 029e33ae0db760..f6fa067810550f 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1664,13 +1664,13 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
     return false;
   }
 
-  if ((Field1->isBitField() || Field2->isBitField()) &&
-      !IsStructurallyEquivalent(Context, Field1->getBitWidth(),
-                                Field2->getBitWidth())) {
+  if ((Field1->isBitField() || Field2->isBitField())) {
     // Two bit-fields can be structurally unequivalent but still be okay for
     // the purposes of C where they simply need to have the same values, not
     // the same token sequences.
-    bool Diagnose = true;
+    bool Diagnose = false;
+    if (!IsStructurallyEquivalent(Context, Field1->getBitWidth(), 
Field2->getBitWidth()))
+        Diagnose = true;
     if (Context.LangOpts.C23 && Field1->isBitField() && Field2->isBitField())
       Diagnose = Field1->getBitWidthValue() != Field2->getBitWidthValue();
 
@@ -1695,7 +1695,8 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
       DiagNote(Field2, &StructuralEquivalenceContext::Diag2);
       DiagNote(Field1, &StructuralEquivalenceContext::Diag1);
     }
-    return false;
+    if (Diagnose)
+      return false;
   }
 
   return true;
diff --git a/clang/test/C/C23/n3037.c b/clang/test/C/C23/n3037.c
index 8dd46ef69b4146..97320820a3eeba 100644
--- a/clang/test/C/C23/n3037.c
+++ b/clang/test/C/C23/n3037.c
@@ -948,3 +948,16 @@ struct GH199417_3 {
     // it would be better to print the original type.
   } a;                                 // c23-note {{field 'a' has type 'int' 
here}}
 };
+
+#if __STDC_VERSION__ >= 202311L
+constexpr int n = 1;
+constexpr int m = 2;
+struct GH232748 {
+  struct S { int i : n; } s1; // c23-note {{bit-field 'i' has bit-width 1 
here}}
+  struct S { int i : m; } s2; // c23-error {{type 'struct S' has incompatible 
definitions}}
+                              // c23-note@-1 {{bit-field 'i' has bit-width 2 
here}}
+
+  struct M { int i : n; } m1;
+  struct M { int i : n; } m2;
+};
+#endif

>From 1795d565c43e96c79a783e5722f9014499827e98 Mon Sep 17 00:00:00 2001
From: Ivy Xu <[email protected]>
Date: Sat, 24 Oct 2026 17:06:31 +0800
Subject: [PATCH 2/4] Fix code formatting

---
 clang/lib/AST/ASTStructuralEquivalence.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index f6fa067810550f..cd0b03c5cc356d 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1669,8 +1669,9 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
     // the purposes of C where they simply need to have the same values, not
     // the same token sequences.
     bool Diagnose = false;
-    if (!IsStructurallyEquivalent(Context, Field1->getBitWidth(), 
Field2->getBitWidth()))
-        Diagnose = true;
+    if (!IsStructurallyEquivalent(Context, Field1->getBitWidth(),
+                                  Field2->getBitWidth()))
+      Diagnose = true;
     if (Context.LangOpts.C23 && Field1->isBitField() && Field2->isBitField())
       Diagnose = Field1->getBitWidthValue() != Field2->getBitWidthValue();
 

>From 45563115edda1d2ea93670c4f244b481908d4ca6 Mon Sep 17 00:00:00 2001
From: Ivy Xu <[email protected]>
Date: Sun, 25 Oct 2026 22:15:08 +0800
Subject: [PATCH 3/4] Add release note

---
 clang/docs/ReleaseNotes.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3f0c48cf36644d..bd588fef3eee6b 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -733,6 +733,7 @@ features cannot lower the translation-unit ABI level;
 - Fixed assertion failures caused by stale linkage information when an extern 
variable or function declaration is merged with a preceding static declaration. 
(#GH204759, #GH204754)
 - Fixed a crash due to typo correction mishandling custom keywords 
`_virtual_inheritance` and `_multiple_inheritance` in `-fms-compatibility` 
mode. (#GH228003)
 - Clang no longer treats a file-scope `thread_local` declaration without an 
initializer as a tentative definition in C23 mode. As specified by C23 6.9.3, 
such a declaration is a definition, so declaring the same variable more that 
once is now diagnosed as a redefinition. (#GH217636)
+- Fixed acceptance of redefinition of a struct with different bit-field width 
in C23 mode. (#GH232748)
 - Fixed an assertion failure on use of an uninitialized token in dependency 
directives lexing in clang-scan-deps.
 - Fixed auto type inference being rejected when the initializer is a 
bit-field. (#GH226280)
 - Fixed failed assertion when creating a compound literal with erroneous 
initializer at file scope. (#GH229888)

>From 57166096c1ff702255c352fef927dd5a220a1d13 Mon Sep 17 00:00:00 2001
From: Ivy Xu <[email protected]>
Date: Mon, 26 Oct 2026 21:53:23 +0800
Subject: [PATCH 4/4] address review

---
 clang/test/C/C23/n3037.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/clang/test/C/C23/n3037.c b/clang/test/C/C23/n3037.c
index 97320820a3eeba..73b5ec79559ec2 100644
--- a/clang/test/C/C23/n3037.c
+++ b/clang/test/C/C23/n3037.c
@@ -949,15 +949,17 @@ struct GH199417_3 {
   } a;                                 // c23-note {{field 'a' has type 'int' 
here}}
 };
 
-#if __STDC_VERSION__ >= 202311L
-constexpr int n = 1;
-constexpr int m = 2;
+constexpr int n = 1; // c17-error {{unknown type name 'constexpr'}}
+constexpr int o = 1; // c17-error {{unknown type name 'constexpr'}}
+constexpr int m = 2; // c17-error {{unknown type name 'constexpr'}}
 struct GH232748 {
   struct S { int i : n; } s1; // c23-note {{bit-field 'i' has bit-width 1 
here}}
+                              // c17-note@-1 {{previous definition is here}}
   struct S { int i : m; } s2; // c23-error {{type 'struct S' has incompatible 
definitions}}
                               // c23-note@-1 {{bit-field 'i' has bit-width 2 
here}}
-
-  struct M { int i : n; } m1;
-  struct M { int i : n; } m2;
+                              // c17-error@-2 {{redefinition of 'S'}}
+  struct M { int i : n; } m2; // c17-note {{previous definition is here}}
+  struct M { int i : n; } m1; // c17-error {{redefinition of 'M'}}
+  struct N { int i : o; } n1; // c17-note {{previous definition is here}}
+  struct N { int i : n; } n2; // c17-error {{redefinition of 'N}}
 };
-#endif

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

Reply via email to