https://gcc.gnu.org/g:b227c79c4331acdf1f1928b7a01ba3c03e00e6cb

commit r16-7070-gb227c79c4331acdf1f1928b7a01ba3c03e00e6cb
Author: Richard Biener <[email protected]>
Date:   Tue Jan 27 11:29:27 2026 +0100

    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:
---
 gcc/dwarf2out.cc                      | 12 ++++--------
 gcc/testsuite/g++.dg/lto/pr123376_0.C | 19 +++++++++++++++++++
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 8c6bab4bdb5e..345b12134dd6 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 000000000000..cf892d753ab6
--- /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 <typename T> void foo (void *, void *) { new T; }
+using C = void (*) (void *, void *);
+template <typename T> struct D { static constexpr C foo = ::foo <T>; };
+struct E { void (*bar) (void *, void *); };
+constexpr bool v = false;
+template <typename T, typename> void baz () { E { D<T>::foo }; }
+template <class, class, bool> struct F;
+template <class R, class E> struct F <R, E, false> { static void qux () { baz 
<R, E> (); } };
+template <typename... T> void corge () { (F <T, void, v>::qux (), ...); }
+template <auto S> struct G { long long val = 0; };
+struct H {
+  virtual void garply ();
+  void plugh (const int &);
+  G <&H::plugh> h;
+};
+void fred () { corge <H> (); }

Reply via email to