Skip to content

Commit

Permalink
fix Issue 22170 - interface thunk doesn't set EBX to GOT (#12950)
Browse files Browse the repository at this point in the history
* fix Issue 22170 - interface thunk doesn't set EBX to GOT

* dshell: Add dll tests for issue 10462
  • Loading branch information
ibuclaw committed Aug 3, 2021
1 parent e31759d commit d0406f3
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 23 deletions.
18 changes: 10 additions & 8 deletions src/dmd/backend/cod3.d
Original file line number Diff line number Diff line change
Expand Up @@ -4876,16 +4876,18 @@ void cod3_thunk(Symbol *sthunk,Symbol *sfunc,uint p,tym_t thisty,
}
else
{
static if (0)
{
localgot = null; // no local variables
code *c1 = load_localgot();
if (c1)
if (config.flags3 & CFG3pic)
{
assignaddrc(c1);
cdb.append(c1);
localgot = null; // no local variables
CodeBuilder cdbgot; cdbgot.ctor();
load_localgot(cdbgot); // load GOT in EBX
code *c1 = cdbgot.finish();
if (c1)
{
assignaddrc(c1);
cdb.append(c1);
}
}
}
cdb.gencs((LARGECODE ? 0xEA : 0xE9),0,FLfunc,sfunc); // JMP sfunc
cdb.last().Iflags |= LARGECODE ? (CFseg | CFoff) : (CFselfrel | CFoff);
}
Expand Down
9 changes: 4 additions & 5 deletions test/dshell/dll.d
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ int main()
version (Windows) if (Vars.MODEL == "32") // Avoid optlink
return DISABLED;

version (Posix) if (Vars.PIC_FLAG == "") // Segfaults without PIC
return DISABLED;

Vars.set(`SRC`, `$EXTRA_FILES/dll`);
Vars.set(`EXE_NAME`, `$OUTPUT_BASE/testdll$EXE`);
Vars.set(`DLL`, `$OUTPUT_BASE/mydll$SOEXT`);
Expand All @@ -19,8 +16,10 @@ int main()
}
else
{
enum dllExtra = `$PIC_FLAG`;
enum mainExtra = `$PIC_FLAG -L-L$OUTPUT_BASE -L$DLL`;
// Segfaults without PIC - using hardcoded -fPIC and not $PIC_FLAG as
// the latter can be set to an empty string.
enum dllExtra = `-fPIC`;
enum mainExtra = `-fPIC -L-L$OUTPUT_BASE -L$DLL`;
}

run(`$DMD -m$MODEL -shared -od=$OUTPUT_BASE -of=$DLL $SRC/mydll.d ` ~ dllExtra);
Expand Down
37 changes: 30 additions & 7 deletions test/dshell/extra-files/dll/mydll.d
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,45 @@ struct S
}
}

interface I
// https://issues.dlang.org/show_bug.cgi?id=9729
interface I9729
{
C foo(I);
C9729 foo(I9729);

export static C create()
export static C9729 create()
{
return new C();
return new C9729();
}
}

class C : I
class C9729 : I9729
{
int x, y;

export C foo(I i)
export C9729 foo(I9729 i)
{
return cast(C) i;
return cast(C9729) i;
}
}

// https://issues.dlang.org/show_bug.cgi?id=10462
void call10462(int delegate() dg)
{
assert(dg() == 7);
}

interface I10462
{
int opCall();
}

class C10462 : I10462
{
int opCall() { return 7; }
}

void test10462_dll()
{
I10462 i = new C10462;
call10462(&i.opCall);
}
29 changes: 26 additions & 3 deletions test/dshell/extra-files/dll/testdll.d
Original file line number Diff line number Diff line change
@@ -1,24 +1,47 @@
import mydll;

void main()
void test1()
{
int n1 = mydll.multiply10(2);
version (Windows) assert(mydll.saved_var == 2);
assert(n1 == 20);
}

void test2()
{
version (Windows) auto pvar = &mydll.saved_var;
auto funcptr = &mydll.multiply10;

int n2 = funcptr(4);
version (Windows) assert(mydll.saved_var == 4);
version (Windows) assert(*pvar == 4);
assert(n2 == 40);
}

void test3()
{
S s;
assert(s.add(2) == 2);
assert(s.add(2) == 4);
}

I i = I.create();
C c = i.foo(i);
void test9729()
{
I9729 i = I9729.create();
C9729 c = i.foo(i);
assert(c is i);
}

void test10462()
{
test10462_dll();
}

void main()
{
test1();
test2();
test3();
test9729();
test10462();
}

0 comments on commit d0406f3

Please sign in to comment.