================
@@ -2122,8 +2122,21 @@ SVal 
RegionStoreManager::getBindingForField(RegionBindingsConstRef B,
   if (const std::optional<SVal> &V = B.getDirectBinding(R))
     return *V;
 
-  // If the containing record was initialized, try to get its constant value.
+  // UnnamedBitField is always Undefined unless using memory operation such
+  // as 'memset'.
+  // For example, for code
+  //    typedef struct {
+  //      int i  :2;
+  //      int    :30;  // unnamed bit-field
+  //    } A;
+  //    A a = {1};
+  // The bits of the unnamed bit-field in local variable a can be anything.
   const FieldDecl *FD = R->getDecl();
+  if (FD->isUnnamedBitField()) {
+      return UndefinedVal();
+  }
+
+  // If the containing record was initialized, try to get its constant value.
----------------
Tedlion wrote:

According to the c++ standard, "Unnamed bit-fields are **not members** and 
**cannot be initialized**(https://eel.is/c++draft/class.bit#2.sentence-2)", and 
"The implicitly-defined copy/move constructor for a non-union class X performs 
a **memberwise** copy/move of its bases and 
members(https://eel.is/c++draft/class.copy.ctor#14.sentence-1)". So strictly 
speaking, an unnamed bit-field can be anything, since the memberwise copy is 
not required for unnamed bits.

Consider the case:
```cpp
struct B {
    int i : 2;
    int : 30; 
};

void bitfield_B_init(void) {
    B b1;
    b1.i = 1; 
    memset(&b1, 0, sizeof(b1));
    B b2 = b1;   
}
```
The unnamed bits is set after the memset. So for the statement `B b2 = b1`, the 
unnamed bitfield in `b1 `is supposed to be `SymbolVal`, while the unnamed 
bitfields in `b2 `should be `UndefinedVal`.

Back to the code, neithor keeping nor removing the continue lines in 
`tryBindSmallStruct` make a perfect handling on unnamed bit-fields. A perfect 
rule maybe that _unnamed bit-fileds must be undefined after being 
implicitly-defined constructed_. Considering the stackframes I got before and 
the little benefit it could bring, implementing the rule seems to be 
compilicated and potentially harmful. So perhaps we should leave it unchanged?

https://github.com/llvm/llvm-project/pull/145066
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to