llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Ivy Xu (IvyXu420)

<details>
<summary>Changes</summary>

The bug comes from `IsStructurallyEquivalent(Context, Field1-&gt;getBitWidth(), 
Field2-&gt;getBitWidth())`
returning true when both `Field1-&gt;getBitWidth()` and 
`Field2-&gt;getBitWidth()` are ConstantExpr types. Two bit fields were treated 
as structurally equivalent even though their widths are different.

This PR makes sure that two bit-fields with different bit-field width are 
treated as structurally unequivalent under `-std=c23`.

Fixes #<!-- -->232748.



---
Full diff: https://github.com/llvm/llvm-project/pull/235265.diff


2 Files Affected:

- (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+6-5) 
- (modified) clang/test/C/C23/n3037.c (+13) 


``````````diff
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

``````````

</details>


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

Reply via email to