On Wed, 18 May 2022, Martin Sebor wrote:

> On 5/18/22 00:26, Richard Biener wrote:
> > On Tue, 17 May 2022, Martin Sebor wrote:
> > 
> >> On 5/16/22 03:16, Richard Biener wrote:
> >>> The following tries to correct get_origin_and_offset_r not handling
> >>> non-constant sizes of array elements in ARRAY_REFs and non-constant
> >>> offsets of COMPONENT_REFs.  It isn't exactly clear how such failures
> >>> should be treated in this API and existing handling isn't consistent
> >>> here either.  The following applies two different variants, treating
> >>> non-constant array sizes like non-constant array indices and
> >>> treating non-constant offsets of COMPONENT_REFs by terminating
> >>> the recursion (not sure what that means to the callers).
> >>>
> >>> Basically the code failed to use component_ref_field_offset and
> >>> array_ref_element_size and instead relies on inappropriate
> >>> helpers (that shouldn't exist in the first place ...).  The code
> >>> is also not safe-guarded against overflows in the final offset/size
> >>> computations but I'm not trying to rectify that.
> >>>
> >>> Martin - can you comment on how the API should handle such
> >>> situations?
> >>
> >> It looks like the -Wrestrict warning here ignores offsets equal to
> >> HOST_WIDE_INT_MIN so presumably setting dst_offset (via *fldoff) to
> >> that should avoid it.  Or maybe to HWI_MAX as it does for variable
> >> offsets.
> > 
> > Can you suggest wording for the function comment as to how it handles
> > the case when offset or size cannot be determined exactly?   The
> > comment currently only suggests that the caller possibly cannot
> > trust fldsize or off when the function returns NULL but the actual
> > implementation differs from that.
> 
> 
> 
> > 
> >> It also looks like the function only handles constant offsets and
> >> sizes, and I have a vague recollection of enhancing it to work with
> >> ranges.  That should avoid the overflow problem too.
> > 
> > So the correct thing is to return NULL?
> 
> No, I don't think so.  The recursive get_origin_and_offset_r() assumes
> its own invocations never return null (the one place it does that should
> probably be moved to the nonrecursive caller).
> 
> > 
> > Is the patch OK as-is?
> 
> It's an improvement but it's not complete as the following also ICEs
> (albeit somewhere else):
> 
> void* f (void);
> 
> void g (int n)
> {
>   struct {
>     char a[n], b[];
>   } *p = f ();
> 
>   __builtin_sprintf (p->b, "%s", p->a);
> }
> 
> With the ICE fixed the warning triggers.  That's not ideal but it's
> unavoidable given the IR (I believe I mentioned this caveat some time
> back).  This is the same as for:
> 
>   struct {
>     char a[8], b[8];
>   } *p = f ();
> 
>   __builtin_sprintf (&p->b[n], "%s", p->a);
> 
> because the IR looks more or less the same for &p->a[n] as it is for
> &p->b[n].
> 
> > As said, I'm not sure how the caller interprets
> > the result and how it can distinguish the exact vs. non-exact cases
> > or what a "conservative" inexact answer would be.
> 
> The warning triggers in both the certain cases and the inexact
> ones like the one above when an overlap cannot be ruled out.  To
> differentiate the two it's phrased as "may overlap".  The handling
> is in maybe_warn_overlap().
> 
> > 
> > Please help properly documenting this API.
> 
> I can spend some time in the next few days to page it all in, see
> if I can clean it up a bit in addition to fixing the ICEs and
> improve the comment.  Let me know if you have a different
> preference.

That works for me - thanks for taking it from here.

Richard.

Reply via email to