Fix #21241 - ImportC: wrong static function called after linking (#21242)

Fixes https://github.com/dlang/dmd/issues/21241

C Static functions were being given the same externally mangled
name as their identifier, which caused only one to be picked
when linking with linkers that supported that.

Additionally, the dmd glue code was only outputting one of these
static functions as a workaround for a different linker issue.

Solve this by giving C static functions a unique name (by using D
mangling) and adding an `isStatic()` check to the dmd glue hack.
This commit is contained in:
drpriver 2025-04-15 19:13:50 -07:00 committed by GitHub
parent 5fd0d29211
commit 1244ef260b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 37 additions and 1 deletions

View file

@ -1339,7 +1339,11 @@ extern (D) const(char)[] externallyMangledIdentifier(Declaration d)
const par = d.toParent(); //toParent() skips over mixin templates
if (!par || par.isModule() || linkage == LINK.cpp ||
(linkage == LINK.c && d.isCsymbol() &&
(d.isFuncDeclaration() ||
// https://github.com/dlang/dmd/issues/21241
// Static check is so C static functions get a unique mangle so the linker
// won't merge them if compiling all-at-once.
// Non-static functions can use their ident as their mangle.
((d.isFuncDeclaration() && !d.isStatic()) ||
(d.isVarDeclaration() && d.isDataseg() && d.storage_class & STC.extern_))))
{
if (linkage != LINK.d && d.localNum)

View file

@ -356,6 +356,7 @@ Symbol* toSymbol(Dsymbol s)
mod.filetype == FileType.c && // a C file
fd.fbody && // a function definition
fd._linkage == LINK.c &&
!fd.isStatic() &&
!fd.skipCodegen) // code gen is desired
{
__gshared DsymbolTable Csymtab; // sorry about another global variable

View file

@ -0,0 +1,9 @@
// https://github.com/dlang/dmd/issues/21241
enum {aValue=1};
static int foo(void){
return aValue;
}
int getA(void){
return foo();
}

View file

@ -0,0 +1,9 @@
// https://github.com/dlang/dmd/issues/21241
enum {bValue=2};
static int foo(void){
return bValue;
}
int getB(void){
return foo();
}

View file

@ -0,0 +1,13 @@
/*
REQUIRED_ARGS: runnable/imports/imp21241a.c runnable/imports/imp21241b.c
*/
// https://github.com/dlang/dmd/issues/21241
import imp21241a;
import imp21241b;
void main(){
int x = getA();
assert(x==aValue);
x = getB();
assert(x==bValue);
}