[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