https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85091
Bug ID: 85091 Summary: Compiler generates different code depending on whether -Wnonnull -Woverloaded-virtual given or not Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: vz-gcc at zeitlins dot org Target Milestone: --- Created attachment 43767 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43767&action=edit Minimal test case reduced by delta This is a completely impossible bug which is nevertheless observed when using i686-w64-mingw32-c++ from Debian Buster (gcc version 7.2-win32 20180123): the compiler produces different (and wrong) object code/assembly when using -O2 depending on whether *both* of "-Wnonnull -Woverloaded-virtual" options are used or not (i.e. the same code is produced if none of them is given, if only -Wnonnull is used or if only -Woverloaded-virtual is used, but the generated code changes if both of them are used at once). Moreover, the generated code may even change depending on the name of the input file on the command line: the attached test case was produced by delta program and was originally called tmp1/16795.cpp and running i686-w64-mingw32-g++ -c -std=c++17 -Wnonnull -Woverloaded-virtual -O2 tmp1/16795.cpp produced correct code (i.e. the same as without the warning options), while simply moving it to the current directory and running i686-w64-mingw32-g++ -c -std=c++17 -Wnonnull -Woverloaded-virtual -O2 16795.cpp produces wrong code. To reproduce the problem, the same test script as used with delta can be used: #!/bin/sh i686-w64-mingw32-g++ -c -std=c++17 -Wnonnull -Woverloaded-virtual -O2 $1 -o warn.o 2>/dev/null & pid1=$! i686-w64-mingw32-g++ -c -std=c++17 -O2 $1 -o nowarn.o 2>/dev/null & pid2=$! if ! wait $pid1 || ! wait $pid2 ; then exit 1 fi if [ $(wc -c < warn.o) -eq $(wc -c < nowarn.o) ]; then exit 2 fi exit 0 (also attached). Running it on 16795.cpp shows that, without the warning options, compiler generates the (expected, as everything is optimized out) trivial body of test_main: xor %eax, %eax ret while with the warning options it generates the following nonsensical instructions: lock addl $0x1,0x4c ret Also notice that this is really the minimal test case, removing any lines, even clearly unused ones such as declarations of never called functions, makes the problem disappear. For the same reason, this file can be only compiled, not linked: adding definitions of various functions used in it makes the problem disappear as well. However the original program, before the reduction, can, of course, be linked, and running it after compiling this file with and without the warning options produces different results at run-time. Please see this thread for more context: https://gcc.gnu.org/ml/gcc-help/2018-03/msg00077.html