https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48885

--- Comment #19 from rguenther at suse dot de <rguenther at suse dot de> ---
On Fri, 25 Sep 2015, vries at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48885
> 
> vries at gcc dot gnu.org changed:
> 
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                  CC|                            |jsm28 at gcc dot gnu.org
> 
> --- Comment #18 from vries at gcc dot gnu.org ---
> Let's rewrite the example from comment 14 to plain C (as we did in PR67705):
> 
> void
> f (int *__restrict__ *__restrict__ fpp, int *fp2)
> {
>   int *fp = *fpp;
>   *fp = 1;
>   *fp2 = 2;
> }
> 
> void
> g (int *__restrict__ gp)
> {
>   f (&gp, gp);
> }
> 
> void
> h (void)
> {
>   int ha;
>   g (&ha);
> }
> 
> My interpretation of the restricts in the example (given what I've learned in
> PR67705):
> 
> Restrict declaration D: "int *__restrict__ gp"
> Type T: int
> Object P: gp
> Block B: g function block
> Lvalues: *fp and *fp2
> Objects designated by lvalues: ha in both cases.
> Object ha modified during execution of B: yes
> Object gp considered modified during execution of B: yes
> &Lvalues: pointer expressions fp and fp2
> &Lvalues based on object P: yes
> Conclusion: Valid example.  Since both lvalues have their address based on
>             the same restrict pointer, there are no disambiguation
>             consequences.
> 
> Restrict declaration D: "int *__restrict__ *__restrict__ fpp"
> Type T: int *__restrict__
> Object P: fpp
> Block B: f function block
> Lvalues: *fpp
> Objects designated by lvalues: gp
> Object gp modified during execution of B: considered modified, yes
> Object fpp considered modified during execution of B: yes
> &Lvalues: pointer expression fpp
> &Lvalues based on object P: yes
> Conclusion: Valid example. Since there's only one lvalue accessing gp there
>             are no disambiguation consequences.
> 
> Joseph, can you confirm that:
> - this is a valid example, and
> - there are no disambiguation consequences.
> 
> If that is indeed the case, then the committed patch is invalid.

I don't see how one needs to consider fp2 based on fp (*fpp).  If
we need to consider that then what's the difference to

int foo (int * __restrict__ p, int *q)
{
  *p = 1;
  *q = 2;
  return *p;
}

int main ()
{
  int i;
  if (foo (&i, &i) != 2)
    abort ();
}

here q is based on p if you take into account the caller.

But IIRC what matters here is that the BLOCK with the restrict
declaration of 'p' starts at the beginning of foo and does not
include the initialization at the call site.  Thus any
"based-on" properties that are formed before the execution of
BLOCK begins are irrelevant to the standards wording.

Thus it's like

int main()
{
  int i;
  int *pcaller = &i;
  int *qcaller = &i;
  int ret;
  {
    int * __restrict__ p = pcaller;
    int * q = qcaller;
    *p = 1;
    *q = 2;
    ret = *p;
  }
  if (ret != 2)
    abort ();
}

(where GCC doesn't handle restrict as it can only guarantee to
follow the scoping rule on a whole function basis).

Reply via email to