https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95198
Bug ID: 95198 Summary: [D] extern(C) private final functions should use 'local' linker attribute Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: d Assignee: ibuclaw at gdcproject dot org Reporter: witold.baryluk+gcc at gmail dot com Target Milestone: --- ``` module t1; extern(C) private final int f() { return 5; } pragma(msg, f.mangleof); ``` `gdc -c t1.d -o t1.o` results in object with this symbols: 0000000000000000 D _D2t111__moduleRefZ 0000000000000000 D _D2t112__ModuleInfoZ U _d_dso_registry 0000000000000000 T f 0000000000000000 W gdc.dso_ctor 0000000000000000 W gdc.dso_dtor 0000000000000000 u gdc.dso_initialized 0000000000000000 u gdc.dso_slot 0000000000000016 t _GLOBAL__D_2t1 000000000000000b t _GLOBAL__I_2t1 U _GLOBAL_OFFSET_TABLE_ U __start_minfo U __stop_minfo Symbol, '0000000000000000 T f' should instead be '0000000000000000 t f' Additional when using optimizations, I would expect the f to not be emitted at all, but it is still there (unless compiler decides not to inline it or its address is not taken and passed around), even with `gdc -O3`. gcc for C does use LOCAL for static functions and variables in translation unit. Similarly probably for C++ symbols in anonymous namespaces. Example of linking issues: t1.d: ``` module t1; extern(C) private final int f() { return 5; } ``` t2.d: ``` module t2; extern(C) private final int f() { return 10; } ``` tm.d: ``` module tm; void main() { } ``` $ gdc -O0 -c t1.d -o t1.o $ gdc -O0 -c t2.d -o t2.o $ gdc t1.o t2.o tm.d -o t12 /usr/bin/ld: t2.o: in function `f': t2.d:(.text+0x0): multiple definition of `f'; t1.o:t1.d:(.text+0x0): first defined here collect2: error: ld returned 1 exit status $ This code should link, similar to equivalent code in C. The use case is local function that is passed in some other module function or method (or static module constructor for example), to C libraries or other modules as a callback or for variables a return value.