steakhal added inline comments.

================
Comment at: clang/test/Analysis/initialization.cpp:295-299
+void glob_cast_opposite_sign1() {
+  auto *ptr = (unsigned int *)glob_arr2;
+  auto x1 = ptr[0]; // no-warning
+  auto x2 = ptr[1]; // expected-warning{{garbage or undefined}}
+}
----------------
ASDenysPetrov wrote:
> steakhal wrote:
> > ASDenysPetrov wrote:
> > > steakhal wrote:
> > > > I think it's not correct.
> > > > 
> > > > `glob_arr2` refers to an object of dynamic type `int[2]`.
> > > > And the pointer decayed from it is `int *`, which has //similar type// 
> > > > to `unsigned *` what you are using to access the memory.
> > > > Since they are //similar//, this operation should work for all the 
> > > > valid indices, thus `ptr[0]`, `ptr[1]`, `ptr[2]`, `ptr[3]` should all 
> > > > be valid.
> > > > 
> > > > 
> > > > glob_arr2 refers to an object of dynamic type int[2].
> > > `glob_arr2` has an extent of 4.
> > > > And the pointer decayed from it is int *, which has similar type to 
> > > > unsigned * what you are using to access the memory.
> > > Yes, they are the same and it perfectly suits to 
> > > http://eel.is/c++draft/basic.lval#11 . But still you can't access other 
> > > element then the first one according to 
> > > http://eel.is/c++draft/basic.compound#3 : //For purposes of pointer 
> > > arithmetic ([expr.add]) and comparison ([expr.rel], [expr.eq]), [...] an 
> > > object of type T that is not an array element is considered to belong to 
> > > an array with one element of type T. //
> > > `unsigned int` and `int` are different types according to 
> > > http://eel.is/c++draft/basic.fundamental#2 . The object of type `unsigned 
> > > int` is NOT an array, beacuse there is no array of type `unsigned int`. 
> > > Hence you can only only access the first and a single element of type 
> > > `unsigned int`.
> > > 
> > Yes, `glob_arr` has 4 elements, sorry for this typo.
> > 
> > ---
> > I disagree with the second part though. It seems like gcc disagrees as 
> > well: https://godbolt.org/z/5o7ozvPar
> > ```lang=C++
> > auto foo(unsigned (&p)[4], int (&q)[4]) {
> >     p[0] = 2;
> >     q[0] = 1;
> >     return p[0]; // memory read! thus, p and q can alias according to g++.
> > }
> > ```
> > `gcc` still thinks that `p` and `q` can refer to the same memory region 
> > even if the `-fstrict-aliasing` flag is present.
> > In other circumstances, it would produce a `mov eax, 2` instead of a memory 
> > load if `p` and `q` cannot alias.
> >I disagree with the second part though. It seems like gcc disagrees as well: 
> >https://godbolt.org/z/5o7ozvPar
> I see how all the compilers handle this. I've switched several vendors on 
> Godbolt. They all have the similar behavior. You are right from compiler 
> perspective, but it's not quite the same in terms of C++ abstract machine.
> Your example is correct, it works OK and is consistent with the Standard:
> ```
>     p[0] = 2;
>     q[0] = 1;
> ```
> This one also works as expected but goes against the Standard:
> ```
>     p[1] = 2;
>     q[1] = 1;
> ```
> I want you watch this particular part about access via aliased pointers: 
> https://youtu.be/_qzMpk-22cc?t=2623 For me it seems correct, at least I can't 
> argue against of it now.
But in this example we have an array, thus pointer arithmetic should be fine 
according to the video.
Could you find the mentioned email discussion? I would be really curious.
BTW from the analyzer user's perspective, it would be 'better' to find strict 
aliasing violations which actually matter - now, and risking miscompilations.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D110927/new/

https://reviews.llvm.org/D110927

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to