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?

Reply via email to