c++: Fix cp_genericize_target_expr for TARGET_EXPRs created for global initialization [PR104031]
The following patch is miscompiled, cp_genericize_target_expr expects that for the constant part split_nonconstant_init will emit an INIT_EXPR that will initialize it, but that doesn't happen and instead we get DECL_INITIAL on the TARGET_EXPR_SLOT that isn't initialized anywhere in the IL. The problem is that the TARGET_EXPR has been created while current_function_decl was NULL, it is inside a global var initializer. That means the build_local_temp created VAR_DECL has NULL DECL_CONTEXT. Later on when genericizing the ssdf (current_function_decl is already non-NULL), the new cp_genericize_target_expr is called and during split_nonconstant_init it checks is_local_temp, but that due to the NULL DECL_CONTEXT returns false. DECL_CONTEXT is set only later on during gimplification. The following patch fixes it by setting DECL_CONTEXT also inside of cp_genericize_target_expr, which fixes the testcase. But if there are better spots to do that, please let me know... 2022-01-17 Jakub Jelinek <jakub@redhat.com> PR c++/104031 * cp-gimplify.c (cp_genericize_target_expr): Set DECL_CONTEXT of TARGET_EXPR_SLOT to current_function_decl if it was NULL. * g++.dg/cpp1y/pr104031.C: New test.
This commit is contained in:
parent
d3a5799335
commit
aeca44768d
@ -930,9 +930,14 @@ cp_genericize_init_expr (tree *stmt_p)
|
||||
static void
|
||||
cp_genericize_target_expr (tree *stmt_p)
|
||||
{
|
||||
tree slot = TARGET_EXPR_SLOT (*stmt_p);
|
||||
/* If TARGET_EXPR is created for some global var initializer, the slot
|
||||
will have NULL and so is_local_temp will return false for it. If
|
||||
this is a ssdf, set DECL_CONTEXT now. */
|
||||
if (DECL_CONTEXT (slot) == NULL_TREE)
|
||||
DECL_CONTEXT (slot) = current_function_decl;
|
||||
cp_genericize_init (&TARGET_EXPR_INITIAL (*stmt_p),
|
||||
TARGET_EXPR_INITIAL (*stmt_p),
|
||||
TARGET_EXPR_SLOT (*stmt_p));
|
||||
TARGET_EXPR_INITIAL (*stmt_p), slot);
|
||||
}
|
||||
|
||||
/* Genericization context. */
|
||||
|
23
gcc/testsuite/g++.dg/cpp1y/pr104031.C
Normal file
23
gcc/testsuite/g++.dg/cpp1y/pr104031.C
Normal file
@ -0,0 +1,23 @@
|
||||
// PR c++/104031
|
||||
// { dg-do run { target c++14 } }
|
||||
// { dg-options "-O2" }
|
||||
|
||||
struct A {
|
||||
A () {}
|
||||
~A () {}
|
||||
};
|
||||
struct B {
|
||||
A a;
|
||||
int b = 0;
|
||||
};
|
||||
struct C
|
||||
{
|
||||
[[gnu::noipa]]
|
||||
C (B x) { if (x.b != 42) __builtin_abort (); }
|
||||
};
|
||||
static C c ({ .a = A{}, .b = 42 });
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user