On Tue, Mar 12, 2019 at 5:36 PM Martin Sebor <[email protected]> wrote:
>
> On 3/12/19 2:20 AM, Richard Biener wrote:
> > On Mon, Mar 11, 2019 at 9:16 PM Martin Sebor <[email protected]> wrote:
> >>
> >> A -Warray-bounds enhancement committed last year into GCC 9
> >> introduced an assumption that the MEM_REF type argument has
> >> a size. The test case submitted in PR89662 does pointer
> >> addition on void*, in which the MEM_REF type is void*, which
> >> breaks the assumption.
> >>
> >> The attached change removes this assumption and considers such
> >> types to have the size of 1. (The result is used to scale
> >> the offset in diagnostics after it has been determined to be
> >> out of bounds.)
> >
> > Why's this not catched here:
> >
> > if (POINTER_TYPE_P (reftype)
> > || !COMPLETE_TYPE_P (reftype)
> > ^^^
> >
> > || TREE_CODE (TYPE_SIZE_UNIT (reftype)) != INTEGER_CST
> > || RECORD_OR_UNION_TYPE_P (reftype))
> > return;
>
> Reftype is the type of the argument referenced by the MEM_REF,
> not the type of the MEM_REF itself.
Ugh how misleading...
> The type examined in
> the patch is the latter. In the test case in PR 89662, reftype
> is unsigned char but the MEM_REF type is void*.
>
> void *f (void *c) { return c; }
> void g () {
> // unsigned char D.1930[1];
> int n = 1;
> char c[n];
> h (f(c) - 1); // h (&MEM[(void *)&D.1930 + -1B]);
> }
>
> >
> > and what avoids the bad situation for
> >
> > char (*a)[n];
> > sink (a - 1);
> >
> > ? That is, the code assumes TYPE_SIZE_UNIT is an INTEGER_CST
> > but the above should get you a non-constant type? It's probably
> > easier to generate a gimple testcase with this.
>
> I think it will depend on what a points to. The only kind of VLA
> the code works with is one whose size is known (for others, like
> in some range, I haven't seen a MEM_REF) . In the following for
> instance we get:
>
> void f (void)
> {
> int n = 4;
> char a[n]; // unsigned char D.1935[4];
> int (*p)[n] = &a;
> sink (p - 1); // &MEM[(void *)&D.1935 - 16B]
> // warning: array subscript -4 is outside array bounds of ‘unsigned
> char[4]’
> sink (*p - 1); // &MEM[(void *)&D.1935 - 4B]
> // warning: array subscript -1 is outside array bounds of ‘unsigned
> char[4]’
> }
>
> I'm not sure what a GIMPLE test case might look like that would
> make the code misbehave. I tried a few variations but most of
> them ICE somewhere else.
Thanks for trying. The patch is OK if you adjust it to verify
TYPE_SIZE_UNIT is an INTEGER_CST before throwing it
at wi::to_offset.
Richard.
> Martin