Bug 82818 - Bad Codegen, delete does not check for nullptrs
Summary: Bad Codegen, delete does not check for nullptrs
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-11-03 02:16 UTC by dark_sylinc
Modified: 2017-11-03 09:11 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Simple repro of the problem (610 bytes, text/x-csrc)
2017-11-03 02:16 UTC, dark_sylinc
Details
Workaround. Uncomment "//a.~FastArray();" to make the crash come back (640 bytes, text/x-csrc)
2017-11-03 02:45 UTC, dark_sylinc
Details

Note You need to log in before you can comment on or make changes to this bug.
Description dark_sylinc 2017-11-03 02:16:00 UTC
Created attachment 42539 [details]
Simple repro of the problem

The attached file, when compiled and run with the following:
c++ -std=c++11 -Wall -Wextra -O2 -g -DNDEBUG -fno-strict-aliasing main.cpp

will crash complaining about a double free; even though:
 * operator delete is guaranteed to check for nullptrs
 * There's also an explicit check for if( mData ). Trying a boolean instead results in the same problem. The check is just left out.
 * AFAIK it is legal to call the destructor.

Problem does not reproduce without optimizations, and cannot be reproduced in Clang or MSVC either.
It seems that GCC optimizer cannot deal with code explicitly calling the destructor.

Info about me:
g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 6.3.0-12ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 6.3.0 20170406 (Ubuntu 6.3.0-12ubuntu2)


I heard the report from another guy who has a much newer version of everything than me; so it's very possible this problem is still present in newer versions or even latest gcc.

Running with -fsanitize reports nothing, but the program stops crashing.
Comment 1 dark_sylinc 2017-11-03 02:44:18 UTC
Update:

1. Confirmed to be broken with gcc 7.2
2. When I said fsanitize; I meant fsanitize=undefined
3. When code is slightly modified as in the new attachment, the crash is gone. But it appears again if after calling a.destroy(); we add a.~FastArray();
Comment 2 dark_sylinc 2017-11-03 02:45:41 UTC
Created attachment 42540 [details]
Workaround. Uncomment "//a.~FastArray();" to make the crash come back
Comment 3 Marc Glisse 2017-11-03 08:08:38 UTC
Please read the documentation for -flifetime-dse, your code is invalid.
Comment 4 Richard Biener 2017-11-03 08:52:53 UTC
INvalid.
Comment 5 Jonathan Wakely 2017-11-03 09:11:00 UTC
(In reply to dark_sylinc from comment #0)
>  * AFAIK it is legal to call the destructor.

Only if you have ensured it won't be called implicitly, e.g. by creating it on the heap. Your object is an automatic (stack) variable, so gets destroyed three times in total, which is so invalid it hurts.