[PATCH] use TYPE_SIZE instead of DECL_SIZE for classes (PR 97595)
Martin Sebor
msebor@gmail.com
Tue Dec 1 22:13:26 GMT 2020
On 11/24/20 1:09 PM, Jason Merrill wrote:
> On 11/23/20 7:06 PM, Martin Sebor wrote:
>> On 11/16/20 11:54 PM, Jason Merrill wrote:
>>> On 11/16/20 9:41 PM, Martin Sebor wrote:
>>>> The result of DECL_SIZE_UNIT doesn't always reflect the size
>>>> of data members of virtual classes. This can lead to objects
>>>> of such types appearing smaller than they are to warnings like
>>>> -Warray-bounds or -Wstringop-overflow, causing false positives.
>>>>
>>>> To avoid these false positives, the attached replaces the use
>>>> of DECL_SIZE_UNIT in component_ref_size in the middle end with
>>>> TYPE_SIZE_UNIT.
>>>
>>> Unfortunately, that's not enough; the offset between the intermediate
>>> base and the virtual base could be greater than the TYPE_SIZE of the
>>> intermediate base:
>>>
>>> extern "C" int printf (const char *, ...);
>>>
>>> struct A { char ar1[24]; };
>>> struct B: virtual A { };
>>> struct C { char ar2[42]; };
>>> struct D: B, C { };
>>>
>>> int main()
>>> {
>>> D d;
>>> printf ("size %d, offset %d\n", sizeof (B), d.ar1 - (char*)(B*)&d);
>>> }
>>>
>>> Here base C is allocated between base B and its virtual base A, so
>>> the offset between them is 50, while the size of B is only 32.
>>>
>>> The difference between TYPE_SIZE and DECL_SIZE could be a way to
>>> recognize the case of bases with virtual bases, and then either hunt
>>> down all the virtual bases or just use the bounds of the enclosing
>>> most-derived object.
>>
>> An advanced analysis of classes with virtual bases is beyond what
>> I have cycles to tackle at this point (it seems it would also need
>> to be done in the C++ front end?) It will have to wait until I have
>> more time or the next stage 1.
>>
>> So for now, I've changed component_ref_size to fail when DECL_SIZE
>> isn't equal TYPE_SIZE.
>
> OK.
>
>>>> + /* DECL_SIZE may be less than TYPE_SIZE in C++ when referring
>>>> + to the type of a virtual base class which doesn't reflect
>>>> + the size of the virtual's members (see pr97595). */
>>>
>>> The problem isn't with the virtual base class itself (A), but with
>>> the intermediate base class subobject (B), for which DECL_SIZE
>>> doesn't include the size of the virtual base A, because the A base
>>> subobject is allocated separately.
>>
>> I've also adjusted the comments above the _SIZE macros in tree.h
>> to more closely reflect what happens there. My main goal isn't
>> to describe when they don't match with perfect accuracy, just to
>> point that they may be unequal and (roughly) when.
>
> Sure, but why not be precise? e.g.
>
> May be less than TYPE_SIZE for a C++ FIELD_DECL representing a base
> class subobject with its own virtual base classes (which are laid out
> separately).
I have committed the patch with the adjusted comment in r11-5628.
Martin
More information about the Gcc-patches
mailing list