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->getBitWidth(), Field2->getBitWidth())` returning true when both `Field1->getBitWidth()` and `Field2->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
