https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/201102
>From 3e92fcb13a46c26f32f974fc088ccb3212231a41 Mon Sep 17 00:00:00 2001 From: Michael Buch <[email protected]> Date: Tue, 2 Jun 2026 12:55:03 +0100 Subject: [PATCH 1/2] [clang] Treat unnamed bitfields as padding in `__builtin_clear_padding` Currently Clang's implementation of `__builtin_clear_padding` diverges from GCC in its treatment of unnamed bitfields. GCC treats them as padding (which seems correct since they can't be named and wouldn't be part of the value representation of an object, though I'm not sure what the standard has to say about this). [Gobdolt](https://godbolt.org/z/e9Mo91dhh) GCC trunk: ``` pre-clear bytes: ff ff ff ff post-clear bytes: 01 00 00 80 b1 = 1, b2 = 1 ``` Clang trunk: ``` pre-clear bytes: ff ff ff ff post-clear bytes: ff ff ff ff b1 = 1, b2 = 1 ``` Note how we cleared the padding with GCC. This patch skips marking unnamed bitfields as "occupied". The rest of the machinery works out-of-the-box. --- clang/lib/CodeGen/CGBuiltin.cpp | 4 ++++ .../atomics/builtin_clear_padding.pass.cpp | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 50d34889d8dc1..40c6da27718bb 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2836,6 +2836,10 @@ struct PaddingClearer { } for (auto *Field : R->fields()) { + // Treat unnamed bitfields as padding. + if (Field->isUnnamedBitField()) + continue; + auto FieldOffset = ASTLayout.getFieldOffset(Field->getFieldIndex()); if (Field->isBitField()) { OccuppiedIntervals.push_back(BitInterval{ diff --git a/libcxx/test/libcxx/atomics/builtin_clear_padding.pass.cpp b/libcxx/test/libcxx/atomics/builtin_clear_padding.pass.cpp index 32bcd376cdcf9..6b10e7bea5751 100644 --- a/libcxx/test/libcxx/atomics/builtin_clear_padding.pass.cpp +++ b/libcxx/test/libcxx/atomics/builtin_clear_padding.pass.cpp @@ -656,6 +656,26 @@ void structTests() { assert(memcmp(&s1, &s2, sizeof(S)) == 0); } + // unnamed bit fields + { + struct S { + unsigned int b1 : 1; + unsigned int : 30; + unsigned int b2 : 1; + }; + + S s1, s2; + memset(&s1, 0, sizeof(S)); + memset(&s2, 42, sizeof(S)); + + s1.b1 = 1; + s1.b2 = 1; + s2.b1 = 1; + s2.b2 = 1; + __builtin_clear_padding(&s2); + assert(memcmp(&s1, &s2, sizeof(S)) == 0); + } + testAllStructsForType<32, 16, char>(11, 22, 33, 44); testAllStructsForType<64, 32, char>(4, 5, 6, 7); testAllStructsForType<32, 16, volatile char>(11, 22, 33, 44); >From 6fbcd7c2c486498d12f5071323bc294d39ba166f Mon Sep 17 00:00:00 2001 From: Michael Buch <[email protected]> Date: Tue, 2 Jun 2026 13:13:25 +0100 Subject: [PATCH 2/2] fixup! clang-format --- libcxx/test/libcxx/atomics/builtin_clear_padding.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/libcxx/atomics/builtin_clear_padding.pass.cpp b/libcxx/test/libcxx/atomics/builtin_clear_padding.pass.cpp index 6b10e7bea5751..198686f4464c0 100644 --- a/libcxx/test/libcxx/atomics/builtin_clear_padding.pass.cpp +++ b/libcxx/test/libcxx/atomics/builtin_clear_padding.pass.cpp @@ -660,7 +660,7 @@ void structTests() { { struct S { unsigned int b1 : 1; - unsigned int : 30; + unsigned int : 30; unsigned int b2 : 1; }; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
