llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-libcxx Author: Michael Buch (Michael137) <details> <summary>Changes</summary> 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. --- Full diff: https://github.com/llvm/llvm-project/pull/201102.diff 2 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4) - (modified) libcxx/test/libcxx/atomics/builtin_clear_padding.pass.cpp (+20) ``````````diff 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); `````````` </details> https://github.com/llvm/llvm-project/pull/201102 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
