On 4/1/20 10:47 AM, Patrick Palka wrote:
On Wed, 1 Apr 2020, Jason Merrill wrote:
We represent 'this' in a default member initializer with a PLACEHOLDER_EXPR.
Normally in constexpr evaluation when we encounter one it refers to
ctx->ctor, but when we're creating a temporary of class type, that replaces
ctx->ctor, so a PLACEHOLDER_EXPR that refers to the type of the member being
initialized needs to be replaced before that happens.
This patch fixes the testcase below, but not the original testcase from the PR,
which is still broken due to PR94219.
Tested x86_64-pc-linux-gnu, applying to trunk and 9.
gcc/cp/ChangeLog
2020-03-31 Jason Merrill <ja...@redhat.com>
PR c++/94205
* constexpr.c (cxx_eval_constant_expression) [TARGET_EXPR]: Call
replace_placeholders.
* typeck2.c (store_init_value): Fix arguments to
fold_non_dependent_expr.
---
gcc/cp/constexpr.c | 6 ++++++
gcc/cp/tree.c | 2 +-
gcc/cp/typeck2.c | 2 +-
gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi2.C | 20 +++++++++++++++++++
gcc/testsuite/g++.dg/cpp1z/lambda-this4.C | 13 ++++++++++++
5 files changed, 41 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi2.C
create mode 100644 gcc/testsuite/g++.dg/cpp1z/lambda-this4.C
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index e85b3c113f0..91f0c3ba269 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -5553,6 +5553,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx,
tree t,
tree init = TARGET_EXPR_INITIAL (t);
if ((AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
{
+ if (ctx->object)
+ /* If the initializer contains any PLACEHOLDER_EXPR, we need to
+ resolve them before we create a new CONSTRUCTOR for the
+ temporary. */
+ init = replace_placeholders (init, ctx->object);
I think I'm running into an issue due to this call to replace_placeholders.
After this change, the following (compiled with -std=c++17) ICEs
struct S
{
int a = [this] { return 6; } ();
};
S
foo()
{
return {};
}
with
internal compiler error: in gimplify_var_or_parm_decl, at gimplify.c:2830
Unsharing 'init' before before doing replace_placeholders seems to fix
this ICE.
That sounds good, thanks.
Jason