c++: Refrain from using replace_placeholders in constexpr evaluation [PR94205]
authorPatrick Palka <ppalka@redhat.com>
Thu, 2 Apr 2020 20:03:18 +0000 (16:03 -0400)
committerPatrick Palka <ppalka@redhat.com>
Sat, 4 Apr 2020 16:15:15 +0000 (12:15 -0400)
commit49a86fce1a879a206fb4b27f097910005d968fda
tree12bed14c9db0a934c281b3c82703588d322faf56
parent37244b217a7329792f4ec48027f63cf5010b0ea8
c++: Refrain from using replace_placeholders in constexpr evaluation [PR94205]

This removes the use of replace_placeholders in cxx_eval_constant_expression
(which is causing the new test lambda-this6.C to ICE due to replace_placeholders
mutating the shared TARGET_EXPR_INITIAL tree which then trips up the
gimplifier).

In its place, this patch adds a 'parent' field to constexpr_ctx which is used to
store a pointer to an outer constexpr_ctx that refers to another object under
construction.  With this new field, we can beef up lookup_placeholder to resolve
PLACEHOLDER_EXPRs which refer to former objects under construction, which fixes
PR94205 without needing to do replace_placeholders.  Also we can now respect the
CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag when resolving PLACEHOLDER_EXPRs, and
doing so fixes the constexpr analogue of PR79937.

gcc/cp/ChangeLog:

PR c++/94205
PR c++/79937
* constexpr.c (struct constexpr_ctx): New field 'parent'.
(cxx_eval_bare_aggregate): Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY
flag from the original constructor to the reduced constructor.
(lookup_placeholder): Prefer to return the outermost matching object
by recursively calling lookup_placeholder on the 'parent' context,
but don't cross CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors.
(cxx_eval_constant_expression): Link the 'ctx' context to the 'new_ctx'
context via 'new_ctx.parent' when being expanded without an explicit
target.  Don't call replace_placeholders.
(cxx_eval_outermost_constant_expr): Initialize 'ctx.parent' to NULL.

gcc/testsuite/ChangeLog:

PR c++/94205
PR c++/79937
* g++.dg/cpp1y/pr79937-5.C: New test.
* g++.dg/cpp1z/lambda-this6.C: New test.
gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/pr79937-5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/lambda-this6.C [new file with mode: 0644]