c++: Fix usage of CONSTRUCTOR_PLACEHOLDER_BOUNDARY inside array initializers [PR90996]
authorPatrick Palka <ppalka@redhat.com>
Mon, 6 Apr 2020 18:05:44 +0000 (14:05 -0400)
committerPatrick Palka <ppalka@redhat.com>
Tue, 7 Apr 2020 13:04:30 +0000 (09:04 -0400)
commit23f1f679141bbb4720ca195cb758605dc017b7fd
tree99de79d9c5b3ab3c5c00dfd98a2a480e6b2c94a2
parentd51af82b4cf4c95c4a7451df2180cc6ebb44856b
c++: Fix usage of CONSTRUCTOR_PLACEHOLDER_BOUNDARY inside array initializers [PR90996]

This PR reports that ever since the introduction of the
CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag, we are sometimes failing to resolve
PLACEHOLDER_EXPRs inside array initializers that refer to some inner
constructor.  In the testcase in the PR, we have as the initializer for "S c[];"
the following

  {{.a=(int &) &_ZGR1c_, .b={*(&<PLACEHOLDER_EXPR struct S>)->a}}}

where CONSTRUCTOR_PLACEHOLDER_BOUNDARY is set on the middle constructor.  When
calling replace_placeholders from store_init_value, we pass the entire
initializer to it, and as a result we fail to resolve the PLACEHOLDER_EXPR
within due to the CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag on the middle
constructor blocking replace_placeholders_r from reaching it.

To fix this, we could perhaps either call replace_placeholders in more places,
or we could change where we set CONSTRUCTOR_PLACEHOLDER_BOUNDARY.  This patch
takes this latter approach -- when building up an array initializer, we now
bubble any CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag from the element initializers
up to the array initializer so that the boundary doesn't later impede us when we
call replace_placeholders from store_init_value.

Besides fixing the kind of code like in the testcase, this shouldn't cause any
other differences in PLACEHOLDER_EXPR resolution because we don't create or use
PLACEHOLDER_EXPRs of array type in the frontend, as far as I can tell.

gcc/cp/ChangeLog:

PR c++/90996
* tree.c (replace_placeholders): Look through all handled components,
not just COMPONENT_REFs.
* typeck2.c (process_init_constructor_array): Propagate
CONSTRUCTOR_PLACEHOLDER_BOUNDARY up from each element initializer to
the array initializer.

gcc/testsuite/ChangeLog:

PR c++/90996
* g++.dg/cpp1y/pr90996.C: New test.
gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/pr90996.C [new file with mode: 0644]