https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67705
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jsm28 at gcc dot gnu.org, | |rguenth at gcc dot gnu.org --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- Indeed the wording contains "and X is also modified (by any means)." thus fp == fp2 are valid even though they are marked restrict. Btw, lets forgo the use of references here and talk plain C: void f (int *__restrict__ *__restrict__ fp, int *__restrict__ *__restrict__ fp2) { int *p = *fp; // 1 int *p2 = *fp2; // 2 *p = 1; // 3 *p2 = 2; // 4 } void g (int *__restrict__ gp) { f (gp, gp); } void h (void) { int ha; g (&ha); } which better explains the issue you are rising. The standard doesn't talk about stmts 1 and 2 (they do not modify anything). We are interested on whether the writes 3 and 4 may alias or not. *p and *p2 would have to be based on the same pointer: "Every other lvalue used to access the value of X shall also have its address based on P." The "pointer expression" here are *fp or *fp2 and either p needs to be dependent on p2 or p2 needs to be dependent on p. Both are not the case IMHO - that both p and p2 are dependent on "*gp" does not count. I don't think writing **fp = 1; **fp2 = 2; changes any of this. If it does then this is worth a DR I think. I think the standard refers to 'P' as rvalue, thus "modifying P to point to a copy of the array object..." would not modify the lvalue *fp but the rvalue *fp. But yes, my original reasoning that *fp and *fp2 cannot refer to the same storage is moot. Adding Joseph.