SYMPTOM: On AIX, TLS init elicits linker errors such as TLS init fuction for thread_local_seg_handler or __tls_init An example C++ program is $ cat a.cc #include <atomic> struct Test {std::atomic<int> x; }; thread_local Test t; $ cat main.cc #include <atomic> struct Test {std::atomic<int> x; }; extern thread_local Test t; int main () { return t.x.load(); } $ g++ -std=c++14 -pthread a.cc main.cc ld: 0711-317 ERROR: Undefined symbol: __tls_init BACKGROUND: AIX XCOFF symbol aliases do not function the same as ELF symbols aliases: XCOFF generates "hard aliases" (like hard links) with only one definition and the attributes are shared / overwritten, instead of a "symbolic" reference to the other definition with its own attributes. Because of this gcc/config/rs6000/xcoff.h defines: /* This is how we tell the assembler to equate two values. The semantic of AIX assembler's .set do not correspond to middle-end expectat ions. We output aliases as alternative symbols in the front of the definition via DECLARE_FUNCTION_NAME and DECLARE_OBJECT_NAME. We still need to define this macro to let middle-end know that aliases are supported. */ #define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) do { } while (0) Honza generously provided other AIX-specific code for function aliases that generate alternative labels in front of the definition. Because of this, GCC internals consider AIX as TARGET_SUPPORTS_ALIASES. Note that the above macro will not output anything for an alias. AIX also support TLS. These two features / behaviors collide for TLS init functions. gcc/cp/decl2.c get_tls_init_fn() and handle_tls_init() depend upon TARGET_SUPPORTS_ALIASES, e.g., if (TARGET_SUPPORTS_ALIASES && TREE_PUBLIC (var)) { tree single_init_fn = get_tls_init_fn (var); if (single_init_fn == NULL_TREE) continue; cgraph_node *alias = cgraph_node::get_create (fn)->create_same_body_alias (single_init_fn, fn); gcc_assert (alias != NULL); } Disabling TARGET_SUPPORTS_ALIASES within cp/decl2.c does not generate correct code (it switches from a mangled TLS init function to __tls_init). How can G++ be coerced to generate TLS init functions for AIX?
Confirmed.
One option is to force flag_extern_tls_init=0 as default for AIX, e.g., -fno-extern-tls-init. That works around the linking issue, but it assumes the limited semantics / assertion of that option always are correct.
Just wanted to echo that I hit this as well because gdb (I'm compiling 9.1) now uses `thread_local`: ld: 0711-317 ERROR: Undefined symbol: TLS init function for thread_local_segv_handler ld: 0711-317 ERROR: Undefined symbol: .TLS init function for thread_local_segv_handler Using `-fno-extern-tls-init` results in a successful build.
*** Bug 100641 has been marked as a duplicate of this bug. ***
*** Bug 109091 has been marked as a duplicate of this bug. ***