[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