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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits