https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79937
--- Comment #17 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Jason Merrill from comment #16) > (In reply to Jakub Jelinek from comment #13) > > E.g. could we walk into TARGET_EXPRs that have TARGET_EXPR_INITIAL > > AGGR_INIT_EXPR, but avoid those that have TARGET_EXPR_INITIAL a CONSTRUCTOR, > > or a CONSTRUCTOR with certain flags, or have some flags on TARGET_EXPRs? > > No, the form of the TARGET_EXPR isn't sufficient to distinguish. Here's a > complete testcase: > > struct X { > unsigned i; > unsigned n = i; > }; > > X bar(X x) { > return x; > } > > struct Y > { > static Y bar(Y y) { return y; } > unsigned i; > unsigned n = bar(Y{2,i}).n; > }; > > int main() > { > X x { 1, bar(X{2}).n }; > if (x.n != 2) > __builtin_abort(); > > Y y { 1 }; > if (y.n != 1) > __builtin_abort(); > } > > Here, the initializers for x and y end up looking equivalent within > store_init_value, but the PLACEHOLDER_EXPRs are meant to refer to different > objects. There's no way for replace_placeholders to tell the difference. > > I think to handle this we'll need to change process_init_constructor_record > to either not expose PLACEHOLDER_EXPRs, or adjust them to indicate better > which CONSTRUCTOR they refer to. Ah, ok, that indeed fails with my patch. Couldn't we mark somewhere using a new lang flag the CONSTRUCTORs that are supposed to be boundaries for the PLACEHOLDER_EXPRs (in the above testcase on {.i=1, .n=(TARGET_EXPR <D.2450, bar (TARGET_EXPR <D.2449, {.i=2, .n=(&<PLACEHOLDER_EXPR struct X>)->i}>)>).n} it would be the {.i=2, .n=(&<PLACEHOLDER_EXPR struct X>)->i} CONSTRUCTOR and on {.i=1, .n=(TARGET_EXPR <D.2452, Y::bar (TARGET_EXPR <D.2453, {.i=2, .n=(&<PLACEHOLDER_EXPR struct Y>)->i}>)>).n} it wouldn't mark any)? Is it the case that PLACEHOLDER_EXPRs should always bind to some containing CONSTRUCTOR and can't be intermixed (say one PLACEHOLDER_EXPR binding to inner CONSTRUCTOR and some other PLACEHOLDER_EXPR within the same CONSTRUCTOR binding to an outer CONSTRUCTOR? Or do you want the #c12 patch as a partial fix for GCC8 and come up with a real fix for GCC9? Or do nothing for now, something else?