On 2/8/21 2:56 PM, Martin Sebor wrote:
> On 2/8/21 12:59 PM, Jeff Law wrote:
>>
>>
>> On 1/19/21 5:56 PM, Martin Sebor via Gcc-patches wrote:
>>> Similar to the problem reported for -Wstringop-overflow in pr98266
>>> and already fixed, -Warray-bounds is also susceptible to false
>>> positives in assignments and copies involving virtual inheritance.
>>> Because the two warnings don't share code yet (hopefully in GCC 12)
>>> the attached patch adds its own workaround for this problem to
>>> gimple-array-bounds.cc, this one slightly more crude because of
>>> the limited insight the array bounds checking has into the checked
>>> expressions.
>>>
>>> Tested on x86_64-linux.
>>>
>>> Martin
>>>
>>> gcc-98266.diff
>>>
>>> PR middle-end/98266 - bogus array subscript is partly outside array
>>> bounds on virtual inheritance
>>>
>>> gcc/ChangeLog:
>>>
>>> PR middle-end/98266
>>> * gimple-array-bounds.cc
>>> (array_bounds_checker::check_array_bounds):
>>> Avoid checking references involving artificial members.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> PR middle-end/98266
>>> * g++.dg/warn/Warray-bounds-15.C: New test.
>> It seems to me that we've got the full statement at some point and thus
>> the full expression so at some point couldn't we detect when
>> TYPE_SIZE_UNIT!= DECL_SIZE_UNIT? Or should we be using TYPE_SIZE_UNIT
>> rather than DECL_SIZE_UNIT in gimple-array-bounds.cc
>>
>> Am I missing something?
>
> The expression we're looking at when the false positive is issued
> is the MEM_REF in the LHS of:
>
> MEM[(struct D *)&D.2652 + 24B]._vptr.D = &MEM <int (*) ()> [(void
> *)&_ZTC1E24_1D + 24B];
>
> TREE_TYPE(LHS) is D, DECL_SIZE_UNIT (D.2652) is 24, and
> TYPE_SIZE_UNIT(D) is also 24, so there's no discrepancy between
> DECL_SIZE and TYPE_SIZE.
So it's a related, but not necessary exactly the same as pr97595 where
we do have the discrepancy between DECL_SIZE and TYPE_SIZE.
I think Jason's comment in pr97595 is the key here. For a base subject
with virtual bases the offset is bounded by the most-derived object size
-- which runs a bit counter to some of the concepts we rely on.
So I think that raises two key questions.
First, can we detect when we've got an access to a base subobject with
virtual bases. I think that's what you're trying to do with the
DECL_ARTIFICIAL check. I don't know offhand if that's the best way to
detect these kinds of accesses or not. That's probably the most
important question here, particularly for gcc-11.
Second, if we can detect those kinds of accesses, do we have any way to
get the most derived object size? If so, obviously we'd want to use it
(gcc-12 perhaps), if not, we'd punt like your patch does.
Jeff