﻿id	summary	reporter	owner	description	type	status	priority	component	version	resolution	keywords	cc
250	Incorrect address calculation of polymorphc object on clean-up	Thierry Delisle	Thierry Delisle <tdelisle@…>	"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."	defect	closed	blocker	cfa-cc	1.0	fixed		
