The HSA GPU drivers can't cope with binaries that have the same symbol defined multiple times, even though the names are not exported. This happens whenever there are file-scope static variables with matching names. I believe it's also an issue with switch tables.
This is a bug, but outside our control, so we must work around it when multiple translation units have the same symbol defined. Therefore, we've implemented name mangling via TARGET_MANGLE_DECL_ASSEMBLER_NAME, but found some places where the middle-end assumes that the decl name matches the name in the source. This patch fixes up those cases by falling back to comparing the unmangled name, when a lookup fails. 2018-09-05 Julian Brown <jul...@codesourcery.com> gcc/ * cgraphunit.c (handle_alias_pairs): Scan for aliases by DECL_NAME if decl assembler name doesn't match. gcc/c-family/ * c-pragma.c (maye_apply_pending_pragma_weaks): Scan for aliases with DECL_NAME if decl assembler name doesn't match. --- gcc/c-family/c-pragma.c | 14 ++++++++++++++ gcc/cgraphunit.c | 15 +++++++++++++++ 2 files changed, 29 insertions(+)
diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index 84e4341..1c0be0c 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -323,6 +323,20 @@ maybe_apply_pending_pragma_weaks (void) continue; target = symtab_node::get_for_asmname (id); + + /* Try again if ID didn't match an assembler name by looking through + decl names. */ + if (!target) + { + symtab_node *node; + FOR_EACH_SYMBOL (node) + if (strcmp (IDENTIFIER_POINTER (id), node->name ()) == 0) + { + target = node; + break; + } + } + decl = build_decl (UNKNOWN_LOCATION, target ? TREE_CODE (target->decl) : FUNCTION_DECL, alias_id, default_function_type); diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index ec490d7..fc3f34e 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1393,6 +1393,21 @@ handle_alias_pairs (void) { symtab_node *target_node = symtab_node::get_for_asmname (p->target); + /* If the alias target didn't match a symbol's assembler name (e.g. + because it has been mangled by TARGET_MANGLE_DECL_ASSEMBLER_NAME), + try again with the unmangled decl name. */ + if (!target_node) + { + symtab_node *node; + FOR_EACH_SYMBOL (node) + if (strcmp (IDENTIFIER_POINTER (p->target), + node->name ()) == 0) + { + target_node = node; + break; + } + } + /* Weakrefs with target not defined in current unit are easy to handle: they behave just as external variables except we need to note the alias flag to later output the weakref pseudo op into asm file. */