ldc-developers / ldc

The LLVM-based D Compiler.
http://wiki.dlang.org/LDC
Other
1.18k stars 255 forks source link

ICE: overlapping initializers for struct literal #4374

Open dkorpel opened 1 year ago

dkorpel commented 1 year ago

I ran into this when re-ordering fields in a union:

union U
{
    int x;
    int[1] arr;

    U setAll(int x)
    {
        arr[0] = x;
        return this;
    }

    enum zero = U.init.setAll(0);
}

void main()
{
    auto u = U.zero;
}
app.d(17): Error: ICE: overlapping initializers for struct literal

It works with dmd, and when the array comes first in the union, it also works with ldc.

kinke commented 1 year ago

A frontend issue IMO (IIRC, I've simplified the LDC implementation in this regard not too long ago when implementing the bitfields) - it really sets both initializers, for absolutely no good reason AFAICT. Here's the -vcg-ast output for 3 such enums:

enum zero = U.init.setAll(0); // U(0, [0])
enum U foo = {x: 0};          // U(0, );
enum U bla = {arr: [0]};      // U(, [0])
kinke commented 1 year ago

Oh right, I think I've simplified it (this is a v1.31 regression) because the user doing this explicitly has been an error for a while:

enum U bla = {x: 0, arr: 0}; // Error: overlapping initialization for field `x` and `arr`
kinke commented 1 year ago

U.init.setAll(1) is lowered to a U(0, [1])... and using arr[] = x; in setAll(), instead of setting the single element explicitly, makes the problematic x initializer vanish.