[clang] [clang][CGRecordLayout] Remove dependency on isZeroSize (PR #96422)

Michael Buch via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 18 16:11:36 PDT 2024


Michael137 wrote:

> This change leads to a crash in `ConstStructBuilder::Build()` for the following program:
> 
> ```
> struct S {
> };
> 
> union U {
>     struct S s;
>     int x;
> };
> 
> void foo() {
>     union U bar = {};
> }
> ```
> 
> `isEmptyRecordForLayout` returns false for `union U` because the recursive call for `U::x` returns false. This means we call `Init->HasSideEffects()` despite `Init` being null (because `ILE->getNumInits()` is `0`).

Thanks for reporting. It looks like this is only happening when compiling with `C`. A slightly more condensed reproducer:
```
union U {
    struct S {} s;
};

void foo() {
    // union U bar = {{}}; // WORKS
    union U bar = {}; // CRASHES
}
```

Looks like when the brace initializer is empty, in C, `ILE->getNumInits()` returns `0` (not entirely sure off the top why this is the case). Previously, `isZeroSize` would never have been true for fields in C, so this wasn't an issue. Now we do hit this code-path and blindly dereference a null `Init`. I think we can probably just add a nullptr check here: https://github.com/llvm/llvm-project/blob/38752ffd417103621232e6ba6ba70e970e0d6356/clang/lib/CodeGen/CGExprConstant.cpp#L741

Though would like to understand the C vs. C++ significance here first.

https://github.com/llvm/llvm-project/pull/96422


More information about the cfe-commits mailing list