Opened 3 years ago

Closed 3 years ago

#250 closed defect (fixed)

Incorrect address calculation of polymorphc object on clean-up

Reported by: Thierry Delisle Owned by: Thierry Delisle <tdelisle@…>
Priority: blocker Component: cfa-cc
Version: 1.0 Keywords:
Cc:

Description (last modified by Thierry Delisle)

Given the following code. The handling of destructors is broken unless the 'sized' assertion is removed.

trait trt(L & | sized(L)) {};

forall(L & | trt(L))
struct object {
	L * f2;
};

forall(L & | trt(L))
void bar(L * ) {
	object(L) obj;
}

Without the size assertion, the generated code is fairly simple since the compiler correctly detects that the layout of the object is indenpendent of 'L'.

void _X3barQ1_0_0_0__Fv_PBD0__1(__attribute__ ((unused)) void *__anonymous_object2142){
    void __cleanup_dtor17(struct object *_dst){
        {
            ((void)_X11_destructorQ1_0_0_0__Fv_S6object_BD0__autogen___1(_dst));
        }

    }
    __attribute__ ((cleanup(__cleanup_dtor17))) struct object _X3objS6object_Y1L__2;
    {
        ((void)_X12_constructorQ1_0_0_0__Fv_S6object_BD0__autogen___1((&_X3objS6object_Y1L__2)));
    }
}

Note the use of __attribute__((cleanup())).

When adding the 'sized' assertion the code generations changes to use a char array rather than a static struct:

void _X3barQ1_0_0_0__Fv_PBD0__1(__attribute__ ((unused)) unsigned long int _sizeof_Y1L, __attribute__ ((unused)) unsigned long int _alignof_Y1L, __attribute__ ((unused)) void *__anonymous_object2142){
    void __cleanup_dtor17(void *_dst){
        {
            ((void)_X11_destructorQ1_0_0_0__Fv_S6object_BD0__autogen___1(_sizeof_Y1L, _alignof_Y1L, ((void *)_dst)));
        }

    }
    unsigned long int _sizeof_S6object_Y1L_;
    unsigned long int _alignof_S6object_Y1L_;
    unsigned long int _offsetof_S6object_Y1L_[1];
    ((void)_layoutof_object((&_sizeof_S6object_Y1L_), (&_alignof_S6object_Y1L_), _offsetof_S6object_Y1L_, _sizeof_Y1L, _alignof_Y1L));
    __attribute__ ((aligned(8))) char _buf32[_sizeof_S6object_Y1L_];
    __attribute__ ((cleanup(__cleanup_dtor17))) void *_X3objS6object_Y1L__2 = _buf32;
    {
        ((void)_X12_constructorQ1_0_0_0__Fv_S6object_BD0__autogen___1(_sizeof_Y1L, _alignof_Y1L, ((void *)_X3objS6object_Y1L__2)));
    }

}

Note that the cleanup is on the pointer rather than the buffer therefore the correct address is the value of _X3objS6object_Y1L__2 not its address.

This is incorrect because __cleanup_dtor17 will be passed the address of _X3objS6object_Y1L__2 and it does not dereference it.

Change History (2)

comment:1 Changed 3 years ago by Thierry Delisle

Description: modified (diff)

comment:2 Changed 3 years ago by Thierry Delisle <tdelisle@…>

Owner: set to Thierry Delisle <tdelisle@…>
Resolution: fixed
Status: newclosed

In 6312b1c:

In box pass that creates pointer + VLA for generics:
I now move the attribute cleanup from the pointer to the buffer.
fixed #250?

Note: See TracTickets for help on using tickets.