[libcxx-commits] [clang] [libcxx] [clang] Treat unnamed bitfields as padding in `__builtin_clear_padding` (PR #201102)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jun 2 05:05:48 PDT 2026


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


More information about the libcxx-commits mailing list