On Tue, Mar 12, 2019 at 5:36 PM Martin Sebor <mse...@gmail.com> wrote:
>
> On 3/12/19 2:20 AM, Richard Biener wrote:
> > On Mon, Mar 11, 2019 at 9:16 PM Martin Sebor <mse...@gmail.com> 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

Reply via email to