[Issue 2318] New: flaw code generation building a function pointer table
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Wed Aug 27 05:22:22 PDT 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2318
Summary: flaw code generation building a function pointer table
Product: D
Version: 1.034
Platform: PC
OS/Version: Windows
Status: NEW
Severity: normal
Priority: P2
Component: DMD
AssignedTo: bugzilla at digitalmars.com
ReportedBy: enzo.petrelli at fastwebnet.it
/***************************
OS: Vista SP1
Compiler/linker: Digital Mars D Compiler v1.034
Tango/tangobos Lib: tango-0.99.7-bin-win32-dmd.1.033
Compiled with: dmd -g -debug epfuntbl.d
Debug version:
Trying to build a table of 5 function pointers out of
5 struct members, 1st and 3rd items are uncorrectly
asssigned values
Release version:
A similar but slightly different behaviour is shown.
Further, an "Access violation" is raised
***************************/
import std.cstream;
alias void function() FnPtr;
void initTTest(TTest * pTst)
{
// pTst.pVtbl = cast(void*) pTst.apFnc.ptr;
pTst.apFnc[0] = cast(FnPtr) &pTst.func0;
pTst.apFnc[1] = cast(FnPtr) &pTst.func1;
pTst.apFnc[2] = cast(FnPtr) &pTst.func2;
pTst.apFnc[3] = cast(FnPtr) &pTst.func3;
pTst.apFnc[4] = cast(FnPtr) &pTst.func4;
}
struct TTest
{
void * pVtbl;
FnPtr[5] apFnc;
void func0()
{
dout.writefln("func0");
}
void func1()
{
dout.writefln("func1");
}
void func2()
{
dout.writefln("func2");
}
void func3()
{
dout.writefln("func3");
}
void func4()
{
dout.writefln("func4");
}
}
void main()
{
TTest * pTst = new TTest;
initTTest(pTst);
for (int iIdx = 0; iIdx < pTst.apFnc.length; ++iIdx)
dout.writefln("item#%d:0x%08X", iIdx, cast(int)
pTst.apFnc[iIdx]);
pTst.apFnc[1]();
pTst.apFnc[3]();
pTst.apFnc[4]();
}
/*
execution produces:
item#0:0x019F3FE0
item#1:0x004020AC
item#2:0x019F3FE0
item#3:0x0040215C
item#4:0x004021B4
func1
func3
func4
*/
/*
disassembly shows that wrong code is generated for the 1st and 3rd
function pointer assignments:
function address is loaded into a register but the destination is
written from another one
5: void initTTest(TTest * pTst)
00402010 enter 4,0
00402014 push ebx
00402015 push esi
00402016 mov dword ptr [ebp-4],eax
6: {
7: // pTst.pVtbl = cast(void*) pTst.apFnc.ptr;
8: pTst.apFnc[0] = cast(FnPtr) &pTst.func0;
00402019 mov eax,dword ptr [pTst]
0040201C mov ecx,offset _D8epfuntbl5TTest5func0MFZv (00402054)
00402021 mov edx,dword ptr [pTst]
00402024 mov dword ptr [edx+4],eax
9: pTst.apFnc[1] = cast(FnPtr) &pTst.func1;
00402027 mov ebx,edx
00402029 mov ecx,offset _D8epfuntbl5TTest5func1MFZv (004020ac)
0040202E mov dword ptr [edx+8],ecx
10: pTst.apFnc[2] = cast(FnPtr) &pTst.func2;
00402031 mov eax,edx
00402033 mov ecx,offset _D8epfuntbl5TTest5func2MFZv (00402104)
00402038 mov dword ptr [edx+0Ch],eax
11: pTst.apFnc[3] = cast(FnPtr) &pTst.func3;
0040203B mov esi,edx
0040203D mov ecx,offset _D8epfuntbl5TTest5func3MFZv (0040215c)
00402042 mov dword ptr [edx+10h],ecx
12: pTst.apFnc[4] = cast(FnPtr) &pTst.func4;
00402045 mov ebx,edx
00402047 mov ecx,offset _D8epfuntbl5TTest5func4MFZv (004021b4)
0040204C mov dword ptr [edx+14h],ecx
13: }
0040204F pop esi
00402050 pop ebx
00402051 leave
00402052 ret
00402053 int 3
*/
--
More information about the Digitalmars-d-bugs
mailing list