[Bug c++/95677] undefined reference to `(anonymous namespace)::xx'

sujian.liu at huawei dot com gcc-bugzilla@gcc.gnu.org
Wed Sep 16 08:11:23 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95677

--- Comment #9 from liusujian <sujian.liu at huawei dot com> ---
After lto and as:

/home/lsj/dts/SDK_CPU_RISCV/output/hcc_riscv32/hcc_riscv32/bin/../lib/gcc/riscv32-unknown-elf/7.3.0/../../../../riscv32-unknown-elf/bin/as
-v --traditional-format -march=rv32imc -march=rv32imc -mabi=ilp32 -mabi=ilp32
-o extern2.exe.ltrans0.ltrans.o extern2.exe.ltrans0.s

We got the two symbols of _ZN12_GLOBAL__N_12xxE and _ZN12_GLOBAL__N_12xxE.lto:

./riscv32-unknown-elf-readelf -s extern2.exe.ltrans0.ltrans.o

Symbol table '.symtab' contains 21 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS <artificial>
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    4
     5: 00000000    20 FUNC    LOCAL  DEFAULT    1 _ZN12_GLOBAL__N_13fooEv
     6: 00000000     0 NOTYPE  LOCAL  DEFAULT    1 .L0
     7: 00000006     0 NOTYPE  LOCAL  DEFAULT    1 .L0
     8: 00000010     0 NOTYPE  LOCAL  DEFAULT    1 .L0
     9: 00000014     0 NOTYPE  LOCAL  DEFAULT    1 .L0
    10: 00000000     0 SECTION LOCAL  DEFAULT    5
    11: 00000000     4 OBJECT  LOCAL  DEFAULT    5 _ZN12_GLOBAL__N_12xxE.lto
    12: 00000014     0 NOTYPE  LOCAL  DEFAULT    1 .L0
    13: 0000001a     0 NOTYPE  LOCAL  DEFAULT    1 .L0
    14: 0000002a     0 NOTYPE  LOCAL  DEFAULT    1 .L0
    15: 0000002e     0 NOTYPE  LOCAL  DEFAULT    1 .L0
    16: 00000000     0 SECTION LOCAL  DEFAULT    6
    17: 00000000     0 SECTION LOCAL  DEFAULT    7
    18: 00000000     0 SECTION LOCAL  DEFAULT    9
    19: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _ZN12_GLOBAL__N_12xxE
    20: 00000014    26 FUNC    GLOBAL DEFAULT    1 main

We found that by GDB ,it renamed by the function of rename_statics in
gcc\lto\lto-partition.c. Here is the function body of rename_statics:
---------------------------------------------------------------------------
/* If NODE represents a static variable.  See if there are other variables
   of the same name in partition ENCODER (or in whole compilation unit if
   ENCODER is NULL) and if so, mangle the statics.  Always mangle all
   conflicting statics, so we reduce changes of silently miscompiling
   asm statements referring to them by symbol name.  */

static void
rename_statics (lto_symtab_encoder_t encoder, symtab_node *node)
{
  tree decl = node->decl;
  symtab_node *s;
  tree name = DECL_ASSEMBLER_NAME (decl);

  /* See if this is static symbol. */
  if (((node->externally_visible && !node->weakref)
      /* FIXME: externally_visible is somewhat illogically not set for
         external symbols (i.e. those not defined).  Remove this test
         once this is fixed.  */
        || DECL_EXTERNAL (node->decl)
        || !node->real_symbol_p ())
       && !may_need_named_section_p (encoder, node))
    return;

  /* Now walk symbols sharing the same name and see if there are any conflicts.
     (all types of symbols counts here, since we can not have static of the
     same name as external or public symbol.)  */
  for (s = symtab_node::get_for_asmname (name);
       s; s = s->next_sharing_asm_name)
    if ((s->real_symbol_p () || may_need_named_section_p (encoder, s))
        && s->decl != node->decl
        && (!encoder
            || lto_symtab_encoder_lookup (encoder, s) != LCC_NOT_FOUND))
       break;

  /* OK, no confict, so we have nothing to do.  */
  if (!s)
    return;

  if (symtab->dump_file)
    fprintf (symtab->dump_file,
            "Renaming statics with asm name: %s\n", node->name ());

  /* Assign every symbol in the set that shares the same ASM name an unique
     mangled name.  */
  for (s = symtab_node::get_for_asmname (name); s;)
    if ((!s->externally_visible || s->weakref)
        /* Transparent aliases having same name as target are renamed at a
           time their target gets new name.  Transparent aliases that use
           separate assembler name require the name to be unique.  */
        && (!s->transparent_alias || !s->definition || s->weakref
            || !symbol_table::assembler_names_equal_p
                 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (s->decl)),
                  IDENTIFIER_POINTER
                    (DECL_ASSEMBLER_NAME (s->get_alias_target()->decl))))
        && ((s->real_symbol_p ()
             && !DECL_EXTERNAL (s->decl)
             && !TREE_PUBLIC (s->decl))
            || may_need_named_section_p (encoder, s))
        && (!encoder
            || lto_symtab_encoder_lookup (encoder, s) != LCC_NOT_FOUND))
      {
        if (privatize_symbol_name (s))
          /* Re-start from beginning since we do not know how many
             symbols changed a name.  */
          s = symtab_node::get_for_asmname (name);
        else s = s->next_sharing_asm_name;
      }
    else s = s->next_sharing_asm_name;
}
---------------------------------------------------------------------------
The main problem of two symbols is whether it is externally_visible. It
determines whether the value of DECL_EXTERNAL (node->decl) is ture or false,
thereby determining whether to return this function.

Here is my patch to solve this problem:
---------------------------------------------------------------------------
diff -urpN a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
--- a/gcc/lto/lto-partition.c   2020-09-15 11:13:50.116566283 +0800
+++ b/gcc/lto/lto-partition.c   2020-09-15 17:10:36.951767726 +0800
@@ -1048,10 +1048,6 @@ rename_statics (lto_symtab_encoder_t enc

   /* See if this is static symbol. */
   if (((node->externally_visible && !node->weakref)
-      /* FIXME: externally_visible is somewhat illogically not set for
-        external symbols (i.e. those not defined).  Remove this test
-        once this is fixed.  */
-        || DECL_EXTERNAL (node->decl)
        || !node->real_symbol_p ())
        && !may_need_named_section_p (encoder, node))
     return;
@@ -1063,6 +1059,8 @@ rename_statics (lto_symtab_encoder_t enc
        s; s = s->next_sharing_asm_name)
     if ((s->real_symbol_p () || may_need_named_section_p (encoder, s))
        && s->decl != node->decl
+       && ((!DECL_EXTERNAL (s->decl) && !DECL_EXTERNAL (node->decl))
+           || (DECL_EXTERNAL (s->decl) && DECL_EXTERNAL (node->decl)))
        && (!encoder
            || lto_symtab_encoder_lookup (encoder, s) != LCC_NOT_FOUND))
        break;
---------------------------------------------------------------------------
what's your opinion about this?


More information about the Gcc-bugs mailing list