dwarf2out: Don't call expand_expr during early_dwarf [PR104407]
As mentioned in the PR, since PR96690 r11-2834 we call rtl_for_decl_init which can call expand_expr already during early_dwarf. The comment and PR explains it that the intent is to ensure the referenced vars and functions are properly mangled because free_lang_data doesn't cover everything, like template parameters etc. It doesn't work well though, because expand_expr can set DECL_RTLs e.g. on referenced vars and keep them there, and they can be created e.g. with different MEM_ALIGN compared to what they would be created with if they were emitted later. So, the following patch stops calling rtl_for_decl_init and instead for cases for which rtl_for_decl_init does anything at all walks the initializer and ensures referenced vars or functions are mangled. 2022-02-09 Jakub Jelinek <jakub@redhat.com> PR debug/104407 * dwarf2out.cc (mangle_referenced_decls): New function. (tree_add_const_value_attribute): Don't call rtl_for_decl_init if early_dwarf. Instead walk the initializer and try to mangle vars or functions referenced from it. * g++.dg/debug/dwarf2/pr104407.C: New test.
This commit is contained in:
parent
c6bb1db76b
commit
be9cd0ca8a
2 changed files with 49 additions and 7 deletions
|
@ -20431,7 +20431,10 @@ rtl_for_decl_init (tree init, tree type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Other aggregates, and complex values, could be represented using
|
/* Other aggregates, and complex values, could be represented using
|
||||||
CONCAT: FIXME! */
|
CONCAT: FIXME!
|
||||||
|
If this changes, please adjust tree_add_const_value_attribute
|
||||||
|
so that for early_dwarf it will for such initializers mangle referenced
|
||||||
|
decls. */
|
||||||
else if (AGGREGATE_TYPE_P (type)
|
else if (AGGREGATE_TYPE_P (type)
|
||||||
|| (TREE_CODE (init) == VIEW_CONVERT_EXPR
|
|| (TREE_CODE (init) == VIEW_CONVERT_EXPR
|
||||||
&& AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (init, 0))))
|
&& AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (init, 0))))
|
||||||
|
@ -20881,6 +20884,19 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p)
|
||||||
return tree_add_const_value_attribute_for_decl (die, decl);
|
return tree_add_const_value_attribute_for_decl (die, decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mangle referenced decls. */
|
||||||
|
static tree
|
||||||
|
mangle_referenced_decls (tree *tp, int *walk_subtrees, void *)
|
||||||
|
{
|
||||||
|
if (! EXPR_P (*tp) && ! CONSTANT_CLASS_P (*tp))
|
||||||
|
*walk_subtrees = 0;
|
||||||
|
|
||||||
|
if (VAR_OR_FUNCTION_DECL_P (*tp))
|
||||||
|
assign_assembler_name_if_needed (*tp);
|
||||||
|
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Attach a DW_AT_const_value attribute to DIE. The value of the
|
/* Attach a DW_AT_const_value attribute to DIE. The value of the
|
||||||
attribute is the const value T. */
|
attribute is the const value T. */
|
||||||
|
|
||||||
|
@ -20889,7 +20905,6 @@ tree_add_const_value_attribute (dw_die_ref die, tree t)
|
||||||
{
|
{
|
||||||
tree init;
|
tree init;
|
||||||
tree type = TREE_TYPE (t);
|
tree type = TREE_TYPE (t);
|
||||||
rtx rtl;
|
|
||||||
|
|
||||||
if (!t || !TREE_TYPE (t) || TREE_TYPE (t) == error_mark_node)
|
if (!t || !TREE_TYPE (t) || TREE_TYPE (t) == error_mark_node)
|
||||||
return false;
|
return false;
|
||||||
|
@ -20910,11 +20925,26 @@ tree_add_const_value_attribute (dw_die_ref die, tree t)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Generate the RTL even if early_dwarf to force mangling of all refered to
|
if (!early_dwarf)
|
||||||
symbols. */
|
{
|
||||||
rtl = rtl_for_decl_init (init, type);
|
rtx rtl = rtl_for_decl_init (init, type);
|
||||||
if (rtl && !early_dwarf)
|
if (rtl)
|
||||||
return add_const_value_attribute (die, TYPE_MODE (type), rtl);
|
return add_const_value_attribute (die, TYPE_MODE (type), rtl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For early_dwarf force mangling of all referenced symbols. */
|
||||||
|
tree initializer = init;
|
||||||
|
STRIP_NOPS (initializer);
|
||||||
|
/* rtl_for_decl_init punts on other aggregates, and complex values. */
|
||||||
|
if (AGGREGATE_TYPE_P (type)
|
||||||
|
|| (TREE_CODE (initializer) == VIEW_CONVERT_EXPR
|
||||||
|
&& AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (initializer, 0))))
|
||||||
|
|| TREE_CODE (type) == COMPLEX_TYPE)
|
||||||
|
;
|
||||||
|
else if (initializer_constant_valid_p (initializer, type))
|
||||||
|
walk_tree (&initializer, mangle_referenced_decls, NULL, NULL);
|
||||||
|
}
|
||||||
/* If the host and target are sane, try harder. */
|
/* If the host and target are sane, try harder. */
|
||||||
if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
|
if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
|
||||||
&& initializer_constant_valid_p (init, type))
|
&& initializer_constant_valid_p (init, type))
|
||||||
|
|
12
gcc/testsuite/g++.dg/debug/dwarf2/pr104407.C
Normal file
12
gcc/testsuite/g++.dg/debug/dwarf2/pr104407.C
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// PR debug/104407
|
||||||
|
// { dg-do compile { target c++17 } }
|
||||||
|
// { dg-options "-O1 -fcompare-debug" }
|
||||||
|
|
||||||
|
struct A { int i; long j; int k : 2; char l; } a;
|
||||||
|
|
||||||
|
auto [ aa, bb, cc, dd ] = a;
|
||||||
|
|
||||||
|
namespace N
|
||||||
|
{
|
||||||
|
auto & [ m, n, o, ppp ] = a;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue