Note how the symbol gets properly hidden without datasections. The first version is causing conflicts on arm64 when I have multiple files with a @“$u3” or @0 symbol.
(Compiler Explorer)
Is there a workaronud for this? Is this a bug at all?
I’m not sure there’s a bug here, I think it depends on what it means to “properly hide” a symbol. In this case, LLVM is essentially treating private globals as if they were internal linkage globals. This is necessary because in order to create a comdat section for every global, it must have a symbol in the symbol table. A private label (one with the .L prefix) won’t work. You can try changing the assembly to add one, and observe the assembler errors.
However, nobody can link against these symbols, they are not external (no .globl directive). They persist in the object file and may be carried over into debug info, but they are mostly harmless aside from some ambiguity and perhaps information leakage.
See this example here showing how private acts like internal with data sections: Compiler Explorer
Thanks! I’ll dig some more tomorrow. I am getting duplicate symbols from lld (only on arm64/windows) for symbols like this. Seems i was looking in the wrong place.
Perhaps LLVM is wrong to use the “one_only” selection kind for private / internal comdat data sections. Maybe we should be using “any” instead. I would check what MSVC does for static global variables when data sections are enabled (/Gw).
That hint did help me. Internal linkage works. I’ll dig further to see if I can find where the cause of private not working, but at least we can move on! Thanks