> On 1/29/24 9:05 AM, Jose E. Marchesi wrote: >>> On Sun, 2024-01-28 at 21:33 -0800, Yonghong Song wrote: >>> [...] >>>> I tried below example with the above prog/dynptr_fail.c case with gcc 11.4 >>>> for native x86 target and didn't trigger the warning. Maybe this requires >>>> latest gcc? Or test C file is not sufficient enough to trigger the warning? >>>> >>>> [~/tmp1]$ cat t.c >>>> struct t { >>>> char a; >>>> short b; >>>> int c; >>>> }; >>>> void init(struct t *); >>>> long foo() { >>>> struct t dummy; >>>> init(&dummy); >>>> return *(int *)&dummy; >>>> } >>>> [~/tmp1]$ gcc -Wall -Werror -O2 -g -Wno-compare-distinct-pointer-types -c t.c >>>> [~/tmp1]$ gcc --version >>>> gcc (GCC) 11.4.1 20230605 (Red Hat 11.4.1-2) >>> I managed to trigger this warning for gcc 13.2.1: >>> >>> $ gcc -fstrict-aliasing -Wstrict-aliasing=1 -c test-punning.c -o /dev/null >>> test-punning.c: In function ‘foo’: >>> test-punning.c:10:19: warning: dereferencing type-punned pointer might break strict-aliasing rules [-Wstrict-aliasing] >>> 10 | return *(int *)&dummy; >>> | ^~~~~~ >>> Note the -Wstrict-aliasing=1 option, w/o =1 suffix it does not >>> trigger. >>> >>> Grepping words "strict-aliasing", "strictaliasing", "strict_aliasing" >>> through clang code-base does not show any diagnostic related tests or >>> detection logic. It appears to me clang does not warn about strict >>> aliasing violations at all and -Wstrict-aliasing=* are just stubs at >>> the moment. >> Detecting strict aliasing violations can only be done by looking at >> particular code constructions (casts immediately followed by >> dereferencing for example) so GCC provides these three levels: 1, 2, and >> 3 which is the default. Level 1 can result in false positives (hence >> the "might" in the warning message) while higher levels have less false >> positives, but will likely miss lots of real positives. > > clang has not implemented this yet. > >> >> In this case, it seems to me clear that a pointer to int does not alias >> a pointer to struct t. So I would say, in this little program >> strict-aliasing=1 catches a real positive, while strict-aliasing=3 >> misses a real positive. > > This make sense. But could you pose the exact bpf compilation command > line which triggers strict-aliasing warning? Does the compiler command > line have -fstrict-aliasing? In GCC -fstrict-aliasing is activated at levels -O2, -O3 and -Os. From a quick look at Clang.cpp, I _think_ it generally assumes strict aliasing when optimizing except when it tries to be compatible with Visual Studio C++ compilers (that clang-cl driver thingie.) >From the GCC manual: '-fstrict-aliasing' Allow the compiler to assume the strictest aliasing rules applicable to the language being compiled. For C (and C++), this activates optimizations based on the type of expressions. In particular, an object of one type is assumed never to reside at the same address as an object of a different type, unless the types are almost the same. For example, an 'unsigned int' can alias an 'int', but not a 'void*' or a 'double'. A character type may alias any other type. Pay special attention to code like this: union a_union { int i; double d; }; int f() { union a_union t; t.d = 3.0; return t.i; } The practice of reading from a different union member than the one most recently written to (called "type-punning") is common. Even with '-fstrict-aliasing', type-punning is allowed, provided the memory is accessed through the union type. So, the code above works as expected. *Note Structures unions enumerations and bit-fields implementation::. However, this code might not: int f() { union a_union t; int* ip; t.d = 3.0; ip = &t.i; return *ip; } Similarly, access by taking the address, casting the resulting pointer and dereferencing the result has undefined behavior, even if the cast uses a union type, e.g.: int f() { double d = 3.0; return ((union a_union *) &d)->i; } The '-fstrict-aliasing' option is enabled at levels '-O2', '-O3', '-Os'.