Opened 4 years ago
Closed 4 years ago
#250 closed defect (fixed)
Incorrect address calculation of polymorphc object on clean-up
| Reported by: | Thierry Delisle | Owned by: | |
|---|---|---|---|
| Priority: | blocker | Component: | cfa-cc |
| Version: | 1.0 | Keywords: | |
| Cc: |
Description (last modified by )
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 by , 4 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 4 years ago
| Owner: | set to |
|---|---|
| Resolution: | → fixed |
| Status: | new → closed |
In 6312b1c: