https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86296
Bug ID: 86296
Summary: Creating a pointer class for a unique_ptr<>() deleter
fails with optimizations
Product: gcc
Version: 7.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: alexis at m2osw dot com
Target Milestone: ---
Created attachment 44317
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44317&action=edit
Source exhibiting the template deleter with a pointer problem
I created a C++ deleter template for unique_ptr<>() that includes a pointer
class. It works as expected when no optimizations are applied (-O0) however,
when I add any level of optimizations (-O1, -O2, -O3) the compiler doesn't work
right. At that point the pointer can't be retrieved correctly. The pointer
operator (T & operator * ()) function returns zero even though within that
function, the pointer value is correct.
main() creates a unique pointer. I immediately check for the value and it
returns -1 as expected when I use -O0, but zero when I use a higher level of
optimization.
Then I reset the pointer to the value of a file descriptor (safe_fd.reset(fd))
and at that point the pointer operator still returns zero when the code is
optimized.
The following is the output when I compile with -O0
default initialization: safe_fd = -1
fd = 3
safe_fd after the reset(3) = 3
second close returned -1 (errno = 9)
The wrong output when I compile with -O1, -O2, -O3
default initialization: safe_fd = 0
fd = 3
safe_fd after the reset(3) = 0
second close returned -1 (errno = 9)
The output is expected to be the same as with -O0.
I tested with stock g++ on Ubuntu 16.04
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
And also on Ubuntu 18.04
g++ (Ubuntu 7.3.0-16ubuntu3) 7.3.0
Both versions failed in a similar way.
I'm attaching my source file. It compiles as is on those versions of Ubuntu and
I would imagine any Unix system with the same or similar compiler version. The
command line I use to compile.
No optimization (working as expected):
g++ --std=c++14 -O0 ~/tmp/b.cpp -o b
Any level of optimization (1 to 3 at least) and the pointer operator breaks:
g++ --std=c++14 -O3 ~/tmp/b.cpp -o b