[PATCH] use TYPE_SIZE instead of DECL_SIZE for classes (PR 97595)

Jason Merrill jason@redhat.com
Tue Nov 24 20:09:44 GMT 2020


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).

Jason



More information about the Gcc-patches mailing list