digitalmars.D.bugs - [Issue 2318] New: flaw code generation building a function pointer table
- d-bugmail puremagic.com (124/124) Aug 27 2008 http://d.puremagic.com/issues/show_bug.cgi?id=2318
- Sivo Schilling (4/147) Sep 03 2008 If you declare FnPtr as void delegate() then these issues are gone.
- d-bugmail puremagic.com (8/8) Apr 08 2009 http://d.puremagic.com/issues/show_bug.cgi?id=2318
- d-bugmail puremagic.com (17/17) Feb 01 2010 http://d.puremagic.com/issues/show_bug.cgi?id=2318
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 digitalmars.com
ReportedBy: enzo.petrelli 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)
pTst.apFnc[iIdx]);
pTst.apFnc[1]();
pTst.apFnc[3]();
pTst.apFnc[4]();
}
/*
execution produces:
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
*/
--
Aug 27 2008
If you declare FnPtr as void delegate() then these issues are gone.
This works with both DMD 1.034 and DMD 2.018 on Win XP SP3 but
using phobos instead of Tango/tangobos.
d-bugmail puremagic.com Wrote:
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 digitalmars.com
ReportedBy: enzo.petrelli 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)
pTst.apFnc[iIdx]);
pTst.apFnc[1]();
pTst.apFnc[3]();
pTst.apFnc[4]();
}
/*
execution produces:
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
*/
--
Sep 03 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2318
clugdbug yahoo.com.au changed:
What |Removed |Added
----------------------------------------------------------------------------
Severity|normal |critical
This also applies to D2.(DMD2.028).
--
Apr 08 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2318
Don <clugdbug yahoo.com.au> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
CC| |clugdbug yahoo.com.au
Resolution| |INVALID
This is invalid: the code creates delegates, then casts them to function
pointers.
To create the desired effect, this line:
pTst.apFnc[0] = cast(FnPtr) &pTst.func0;
should be changed to:
pTst.apFnc[0] = &TTest.func0;
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 01 2010









Sivo Schilling <sivo.schilling web.de> 