The following makes sure to, at early debug generation time, mangle
symbols we eventually end up outputting during late finish.

[LTO] Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed
to trunk sofar.

Richard.

2020-08-24  Richard Biener  <rguent...@suse.de>

        PR debug/96690
        * dwarf2out.c (reference_to_unused): Make FUNCTION_DECL
        processing more consistent with respect to
        symtab->global_info_ready.
        (tree_add_const_value_attribute): Unconditionally call
        rtl_for_decl_init to do all mangling early but throw
        away the result if early_dwarf.

        * g++.dg/lto/pr96690_0.C: New testcase.
---
 gcc/dwarf2out.c                      | 15 +++++++--------
 gcc/testsuite/g++.dg/lto/pr96690_0.C | 17 +++++++++++++++++
 2 files changed, 24 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/lto/pr96690_0.C

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 9deca031fc2..6b03ff85f99 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -19756,7 +19756,7 @@ reference_to_unused (tree * tp, int * walk_subtrees,
   /* ???  The C++ FE emits debug information for using decls, so
      putting gcc_unreachable here falls over.  See PR31899.  For now
      be conservative.  */
-  else if (!symtab->global_info_ready && VAR_OR_FUNCTION_DECL_P (*tp))
+  else if (!symtab->global_info_ready && VAR_P (*tp))
     return *tp;
   else if (VAR_P (*tp))
     {
@@ -19771,7 +19771,7 @@ reference_to_unused (tree * tp, int * walk_subtrees,
          optimizing and gimplifying the CU by now.
         So if *TP has no call graph node associated
         to it, it means *TP will not be emitted.  */
-      if (!cgraph_node::get (*tp))
+      if (!symtab->global_info_ready || !cgraph_node::get (*tp))
        return *tp;
     }
   else if (TREE_CODE (*tp) == STRING_CST && !TREE_ASM_WRITTEN (*tp))
@@ -20295,12 +20295,11 @@ tree_add_const_value_attribute (dw_die_ref die, tree 
t)
          return true;
        }
     }
-  if (! early_dwarf)
-    {
-      rtl = rtl_for_decl_init (init, type);
-      if (rtl)
-       return add_const_value_attribute (die, rtl);
-    }
+  /* Generate the RTL even if early_dwarf to force mangling of all refered to
+     symbols.  */
+  rtl = rtl_for_decl_init (init, type);
+  if (rtl && !early_dwarf)
+    return add_const_value_attribute (die, rtl);
   /* If the host and target are sane, try harder.  */
   if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
       && initializer_constant_valid_p (init, type))
diff --git a/gcc/testsuite/g++.dg/lto/pr96690_0.C 
b/gcc/testsuite/g++.dg/lto/pr96690_0.C
new file mode 100644
index 00000000000..c49327720fc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr96690_0.C
@@ -0,0 +1,17 @@
+// { dg-lto-do assemble }
+// { dg-lto-options { { -flto -ffat-lto-objects -g } } }
+struct A { A (int); };
+template <class T> class B { T f; };
+unsigned char *foo (int *, bool *, const int &);
+template <typename, unsigned char *F (int *, bool *, const int &)> struct C {};
+struct D { B<C<unsigned char, foo> > d; };
+struct E { D e; };
+struct F {};
+struct G { static int bar (A, F, E, int); };
+
+void
+baz ()
+{
+  F f;
+  G::bar (0, f, E (), 0);
+}
-- 
2.26.2

Reply via email to