[PATCH] D110927: [analyzer] Access stored value of a constant array through a pointer to another type
Balázs Benics via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 10 09:08:42 PST 2021
steakhal added a comment.
In D110927#3118936 <https://reviews.llvm.org/D110927#3118936>, @ASDenysPetrov wrote:
>> You could have a parameter, and take its address to accomplish your reinterpret casts and type puns.
>
> Do you mean: ...
> If so, IMO it doesn't matter.
I see. Sorry about the confusion I caused.
In D110927#3115795 <https://reviews.llvm.org/D110927#3115795>, @ASDenysPetrov wrote:
> Does anyone know how to check the status of`-fno-strict-aliasing` flag from CSA side?
I think I know.
Within the `AnalysisConsumer::AnalysisConsumer()` you have access to the `CompilerInstance` object. Using that you can acquire the `CI.getCodeGenOpts().RelaxedAliasing` bool member, which represents exactly what we need, according to the `clang/include/clang/Basic/CodeGenOptions.def:211`:
CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled.
I think you should simply save a `const` reference to the `CodeGenOptions` object from the `AnalysisConsumer`.
================
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:
> > 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.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D110927/new/
https://reviews.llvm.org/D110927
More information about the cfe-commits
mailing list