From: Richard Biener Date: Tue, 27 Jan 2026 10:29:27 +0000 (+0100) Subject: debug/123376 - mangle decls referenced in initializers early X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b227c79c4331acdf1f1928b7a01ba3c03e00e6cb;p=thirdparty%2Fgcc.git debug/123376 - mangle decls referenced in initializers early The following makes sure to mangle decls referenced in initializers, even when of aggregate type, during the early debug phase since later we eventually leave stray supposedly unused CV qualified types as their own main variant which confuses C++ mangling. The comment that refers to rtl_for_decl_init punting might be accurate, but loc_list_from_tree_1 will happily see to cst_pool_loc_descr where constant pool lookup will eventually create DECL_RTL of referenced symbols, triggering mangling. PR debug/123376 * dwarf2out.cc (tree_add_const_value_attribute): Walk all initializers for early mangling of referenced decls. (mangle_referenced_decls): Also walk subtrees of CONSTRUCTORS. * g++.dg/lto/pr123376_0.C: New testcase. --- diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index 8c6bab4bdb5..345b12134dd 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -21350,7 +21350,9 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p) static tree mangle_referenced_decls (tree *tp, int *walk_subtrees, void *) { - if (! EXPR_P (*tp) && ! CONSTANT_CLASS_P (*tp)) + if (! EXPR_P (*tp) + && ! CONSTANT_CLASS_P (*tp) + && TREE_CODE (*tp) != CONSTRUCTOR) *walk_subtrees = 0; if (VAR_OR_FUNCTION_DECL_P (*tp)) @@ -21398,13 +21400,7 @@ tree_add_const_value_attribute (dw_die_ref die, tree t) /* 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)) + if (initializer_constant_valid_p (initializer, type)) walk_tree (&initializer, mangle_referenced_decls, NULL, NULL); } /* If the host and target are sane, try harder. */ diff --git a/gcc/testsuite/g++.dg/lto/pr123376_0.C b/gcc/testsuite/g++.dg/lto/pr123376_0.C new file mode 100644 index 00000000000..cf892d753ab --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr123376_0.C @@ -0,0 +1,19 @@ +// { dg-lto-do assemble } +// { dg-lto-options { { -flto -ffat-lto-objects -g } } } + +template void foo (void *, void *) { new T; } +using C = void (*) (void *, void *); +template struct D { static constexpr C foo = ::foo ; }; +struct E { void (*bar) (void *, void *); }; +constexpr bool v = false; +template void baz () { E { D::foo }; } +template struct F; +template struct F { static void qux () { baz (); } }; +template void corge () { (F ::qux (), ...); } +template struct G { long long val = 0; }; +struct H { + virtual void garply (); + void plugh (const int &); + G <&H::plugh> h; +}; +void fred () { corge (); }