Skip to content

ImportC: wrong static function called after linking when static functions in different C imports have same name #21241

@drpriver

Description

@drpriver
// a.c
enum {aValue=1};
int puts(const char*);
static int foo(void){
    puts(__FILE__);
    return aValue;
}

int getA(void){
    return foo();
}
// b.c
enum {bValue=2};
int puts(const char*);
static int foo(void){
    puts(__FILE__);
    return bValue;
}

int getB(void){
    return foo();
}
// c.d
import a;
import b;

void main(){
    int x = a.getA();
    assert(x==a.aValue);
    x = b.getB();
    assert(x==b.bValue);
}

If you compile the C files separately, and run the resulting program the assertions in main pass and you’ll see:

a.c
b.c

and the process exits with a 0 exit code.

However, if you compile it with dmd c.d a.c b.c or a similar command with -i, you’ll see:

a.c
a.c
src/rt/dwarfeh.d:346: uncaught exception reached top of stack
This might happen if you're missing a top level catch in your fiber or signal handler
[email protected](10): Assertion failure

which indicates it is using the definition of foo from a.c.


Discovered this trying to compile sqlite3 with ImportC. Their shell.c example has a different static function named appendText than the one in sqlite3.c so when compiling them together you’d get weird memory corruption.

I also experimented and found that the right function gets called at CTFE. Behavior can be seen both with dmd and current ldc, so I don’t believe the issue is in the backend.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions