[Issue 2318] New: flaw code generation building a function pointer table

Sivo Schilling sivo.schilling at web.de
Wed Sep 3 02:48:37 PDT 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 at 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 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