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 Changed 4 years ago by
Description: | modified (diff) |
---|
comment:2 Changed 4 years ago by
Owner: | set to Thierry Delisle <tdelisle@…> |
---|---|
Resolution: | → fixed |
Status: | new → closed |
In 6312b1c: