$ cat test.cc #include <new> struct APInt { int i; }; int main() { APInt I; char Data[sizeof(APInt)]; new((void*)Data)APInt(); *(APInt*)Data = I; } $ g++ -O3 -Wstrict-aliasing test.cc -o /dev/null test.cc: In function 'int main()': test.cc:9: warning: dereferencing type-punned pointer will break strict-aliasing rules test.cc:9: warning: dereferencing type-punned pointer will break strict-aliasing rules $ g++ -v Using built-in specs. Target: i386-apple-darwin9 Configured with: ../gcc-4.4.1/configure --prefix=/opt/local --build=i386-apple-darwin9 --enable-languages=c,c++,objc,obj-c++,java,fortran --libdir=/opt/local/lib/gcc44 --includedir=/opt/local/include/gcc44 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-4.4 --with-gxx-include-dir=/opt/local/include/gcc44/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local Thread model: posix gcc version 4.4.1 (GCC) The warning goes away if I change "*(APInt*)Data = I;" to "*(APInt*)(void*)Data = I;" even though an extra cast through void* can't improve the situation wrt strict-aliasing.
4.5 also fails and I cannot figure why if I do: #include <new> struct APInt { int i; }; int main() { APInt I; void *d; char Data[sizeof(APInt)]; new((void*)Data)APInt(); d = Data; *(APInt*)d = I; } GCC does not warn.
Subject: Re: Incorrect "dereferencing type-punned pointer will break strict-aliasing rules" warning On Fri, 6 Nov 2009, pinskia at gcc dot gnu dot org wrote: > ------- Comment #1 from pinskia at gcc dot gnu dot org 2009-11-06 09:09 ------- > 4.5 also fails and I cannot figure why if I do: "fails"? > #include <new> > struct APInt { > int i; > }; > int main() { > APInt I; > void *d; > char Data[sizeof(APInt)]; > new((void*)Data)APInt(); > d = Data; > *(APInt*)d = I; > } > > GCC does not warn. Of course not - the code is perfectly valid (apart from Data not having suitable alignment for APInt, but that's unrelated to aliasing issues). Richard.
> > ------- Comment #1 from pinskia at gcc dot gnu dot org 2009-11-06 09:09 ------- > > 4.5 also fails Fails in that it warns still. The first example warns with 4.5, while adding an extra variable and doing a cast to void* causes GCC not to warn.
Btw, this warning is emitted from the frontend which only warns if it sees the address of an object casted, not random pointers (because of the many false positives). The frontend code also has no idea of the concept of a dynamic type.
Isn't this a wrong-code bug? Or is the information used for the diagnostic not used by the optimizers?
(In reply to comment #5) > Isn't this a wrong-code bug? Or is the information used for the diagnostic not > used by the optimizers? The diagnostics are independent on the optimizers, the one diagnostic that isn't (that is emitted from the optimizer itself) causes the optimizer to not optimize (well, because it saw the problem and thus there is no point in breaking things just because we can). The general problem is that alias analysis is hard, thus follows that proper warnings are equally hard. All warnings we emit are either possible false positives or if they are not the optimizers will not miscompile your code because they know there is an alias even though type-based analysis says there is not (well, this is exactly the case you want to warn about, but as analysis is hard once you can tell you can as well not exploit the mis-optimization opportunity).
AFAIK, users of Boost.Function suffer from this PR too. https://svn.boost.org/trac/boost/ticket/4538
(In reply to comment #6) > The general problem is that alias analysis is hard, thus follows that proper > warnings are equally hard. Note that it says "will break strict-aliasing rules", not "might break strict-aliasing rules" (which also exists). I think the user can reasonably expect that the "will break" variant is actually true.
I've come across another weird warning emission in g++ 4.4: $ cat test.cc #include <new> struct interface_type { virtual interface_type* clone(void* storage) const { return ::new (storage) interface_type(); } }; struct poly_base { poly_base(const interface_type& x) { x.clone(data); } typedef char storage_t[100]; storage_t data; }; struct instance_t: interface_type {}; int main() { instance_t pi; poly_base p1(pi); interface_type* ptr = (interface_type*)(p1.data); poly_base p2(*ptr); } $ g++ -O3 -Wstrict-aliasing test.cc -o /dev/null test.cc: In function ‘int main()’: test.cc:12: warning: dereferencing pointer ‘ptr’ does break strict-aliasing rules test.cc:25: note: initialized from here $ g++ -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.1-4ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9) I get this only in g++ 4.4, g++ 4.5 does not warn. I want to note that this is a different type of warning about strict-aliasing rules, likely a more serious one. Can anyone tell what a difference between "warning: dereferencing type-punned pointer will break strict-aliasing rules" and "warning: dereferencing pointer ‘ptr’ does break strict-aliasing rules"?
On Wed, 6 Oct 2010, muravev at yandex dot ru wrote: > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41874 > > --- Comment #9 from Ilya Murav'jov <muravev at yandex dot ru> 2010-10-06 19:43:30 UTC --- > I've come across another weird warning emission in g++ 4.4: > > $ cat test.cc > #include <new> > struct interface_type { > > virtual interface_type* clone(void* storage) const > { > return ::new (storage) interface_type(); > } > }; > > struct poly_base { > > poly_base(const interface_type& x) { x.clone(data); } > > typedef char storage_t[100]; > storage_t data; > }; > > struct instance_t: interface_type {}; > > int main() > { > instance_t pi; > poly_base p1(pi); > > interface_type* ptr = (interface_type*)(p1.data); > poly_base p2(*ptr); > } > $ g++ -O3 -Wstrict-aliasing test.cc -o /dev/null > test.cc: In function ‘int main()’: > test.cc:12: warning: dereferencing pointer ‘ptr’ does break strict-aliasing > rules > test.cc:25: note: initialized from here > > $ g++ -v > Using built-in specs. > Target: i486-linux-gnu > Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.1-4ubuntu9' > --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs > --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared > --enable-multiarch --enable-linker-build-id --with-system-zlib > --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix > --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls > --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc > --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic > --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu > --target=i486-linux-gnu > Thread model: posix > gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9) > > I get this only in g++ 4.4, g++ 4.5 does not warn. > > I want to note that this is a different type of warning about strict-aliasing > rules, likely a more serious one. Can anyone tell what a difference between > "warning: dereferencing type-punned pointer will break strict-aliasing rules" > and "warning: dereferencing pointer ‘ptr’ does break strict-aliasing rules"? The latter means that when doing pointer analysis GCC pruned all pointed-to objects using TBAA so the pointer ended up pointing to nothing (but still was dereferenced). The good news for you is that GCC will assume the pointer points to anything in that case, not nothing. In GCC 4.5 points-to analysis doesn't use TBAA to prune the sets anymore (because its fundamentally wrong), so the code emitting the warning was removed. Richard.
Richard, is this still an issue?
No, the warning is gone from all releases that are still maintained.
Still have same problem in g++ 6.3.0. So, please reopen this bug.
(In reply to Aso Renji from comment #13) > Still have same problem in g++ 6.3.0. So, please reopen this bug. What do you mean by "same problem"? The original testcase does not produce a warning with GCC 6.3.0 If you get a warning for a different piece of code then please open a new bug, this one is fixed.
(In reply to Jonathan Wakely from comment #14) > What do you mean by "same problem"? The original testcase does not produce a warning with GCC 6.3.0 No, this warning still appear if (and only if) you use -O2 or -O3 optimization key (as it be in startpost with "g++ -O3 -Wstrict-aliasing test.cc -o /dev/null" line). If I don't use any optimization - yes, this warning don't appeared.
(In reply to Richard Biener from comment #12) > No, the warning is gone from all releases that are still maintained. Looks like this wasn't true.
(In reply to Aso Renji from comment #15) > No, this warning still appear if (and only if) you use -O2 or -O3 > optimization key (as it be in startpost with "g++ -O3 -Wstrict-aliasing > test.cc -o /dev/null" line). I don't see this with any compiler after 6.5.0.