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:
Jakub Jelinek 2022-02-09 15:17:52 +01:00
parent c6bb1db76b
commit be9cd0ca8a
2 changed files with 49 additions and 7 deletions

View file

@ -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))

View 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;
}