public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/67773] New: dealloc called on temp object before and named object after move, while not being called on named object before move
@ 2015-09-30  0:57 awenocur at aol dot com
  2015-09-30  1:37 ` [Bug c++/67773] destructor " awenocur at aol dot com
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: awenocur at aol dot com @ 2015-09-30  0:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67773

            Bug ID: 67773
           Summary: dealloc called on temp object before and named object
                    after move, while not being called on named object
                    before move
           Product: gcc
           Version: 4.8.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: awenocur at aol dot com
  Target Milestone: ---

Created attachment 36420
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36420&action=edit
pre-processed C++11 file exhibiting this behavior

The problem occurs on line 23813 of the provided .ii file.
An object initialized with specific parameters is dealloc'd once before moving,
and once after moving, while the target of the move is never dealloc'd.

This demo is simplified from a program I'm writing that has to assign an object
with an embedded pointer.  In the original, this object is destroyed twice
separately, resulting in a double free on the pointer.  In the demo there is no
pointer member, but the undesired behavior is the same.
The workaround featured in the demo is the same one that fixed the real
program.

This problem appears to exist on dialects of C++, at least from '03 onward, but
I chose to use C++11, because move constructors can be explicitly declared.  In
C++03, it does the move in the same manner.

compilation command:
c++ -g -O0 -std=c++11 -save-temps -o test test.cpp

GCC info:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs
--enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.8 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls
--with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug
--enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap
--enable-plugin --with-system-zlib --disable-browser-plugin
--enable-java-awt=gtk --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64
--with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686
--with-abi=m64 --with-multilib-list=m32,m64,mx32 --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 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) 

OS description:
Ubuntu 3.13.0-48.80-generic 3.13.11-ckt16


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/67773] destructor called on temp object before and named object after move, while not being called on named object before move
  2015-09-30  0:57 [Bug c++/67773] New: dealloc called on temp object before and named object after move, while not being called on named object before move awenocur at aol dot com
@ 2015-09-30  1:37 ` awenocur at aol dot com
  2015-09-30  9:19 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: awenocur at aol dot com @ 2015-09-30  1:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67773

--- Comment #1 from Adam Wenocur <awenocur at aol dot com> ---
compiler output:

-*- mode: compilation; default-directory: "~/compiler-test/" -*-  
Compilation started at Wed Sep 30 00:45:55                        

./compile.sh                                                      

Compilation finished at Wed Sep 30 00:45:55


the command:
./test


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/67773] destructor called on temp object before and named object after move, while not being called on named object before move
  2015-09-30  0:57 [Bug c++/67773] New: dealloc called on temp object before and named object after move, while not being called on named object before move awenocur at aol dot com
  2015-09-30  1:37 ` [Bug c++/67773] destructor " awenocur at aol dot com
@ 2015-09-30  9:19 ` redi at gcc dot gnu.org
  2015-09-30  9:21 ` redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2015-09-30  9:19 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67773

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I don't see a bug here, could you please try a supported release and explain
exactly what output you are seeing and what you expect to see.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/67773] destructor called on temp object before and named object after move, while not being called on named object before move
  2015-09-30  0:57 [Bug c++/67773] New: dealloc called on temp object before and named object after move, while not being called on named object before move awenocur at aol dot com
  2015-09-30  1:37 ` [Bug c++/67773] destructor " awenocur at aol dot com
  2015-09-30  9:19 ` redi at gcc dot gnu.org
@ 2015-09-30  9:21 ` redi at gcc dot gnu.org
  2015-09-30 11:42 ` awenocur at aol dot com
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2015-09-30  9:21 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67773

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Oh, are you expecting this:

  a_thing = demo(demo::second);

to have the same behaviour as this:

  a_thing.~demo();
  new(&a_thing) demo(demo::second);

?

That's not how C++ works.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/67773] destructor called on temp object before and named object after move, while not being called on named object before move
  2015-09-30  0:57 [Bug c++/67773] New: dealloc called on temp object before and named object after move, while not being called on named object before move awenocur at aol dot com
                   ` (2 preceding siblings ...)
  2015-09-30  9:21 ` redi at gcc dot gnu.org
@ 2015-09-30 11:42 ` awenocur at aol dot com
  2015-09-30 11:43 ` awenocur at aol dot com
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: awenocur at aol dot com @ 2015-09-30 11:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67773

--- Comment #4 from Adam Wenocur <awenocur at aol dot com> ---
(In reply to Jonathan Wakely from comment #3)
> Oh, are you expecting this:
> 
>   a_thing = demo(demo::second);
> 
> to have the same behaviour as this:
> 
>   a_thing.~demo();
>   new(&a_thing) demo(demo::second);
> 
> ?
> 
> That's not how C++ works.

I don't expect the same behavior, however I expect the same end result:

for the destructor to be called on to be called on the named variable before
the move, then for it to be called on the temporary object.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/67773] destructor called on temp object before and named object after move, while not being called on named object before move
  2015-09-30  0:57 [Bug c++/67773] New: dealloc called on temp object before and named object after move, while not being called on named object before move awenocur at aol dot com
                   ` (3 preceding siblings ...)
  2015-09-30 11:42 ` awenocur at aol dot com
@ 2015-09-30 11:43 ` awenocur at aol dot com
  2015-09-30 12:00 ` awenocur at aol dot com
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: awenocur at aol dot com @ 2015-09-30 11:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67773

--- Comment #5 from Adam Wenocur <awenocur at aol dot com> ---
(In reply to Jonathan Wakely from comment #3)
> Oh, are you expecting this:
> 
>   a_thing = demo(demo::second);
> 
> to have the same behaviour as this:
> 
>   a_thing.~demo();
>   new(&a_thing) demo(demo::second);
> 
> ?
> 
> That's not how C++ works.

I don't expect the same behavior, however I expect the same end result:

for the destructor to be called on to be called on the named variable before
the move, then for it to be called on the temporary object.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/67773] destructor called on temp object before and named object after move, while not being called on named object before move
  2015-09-30  0:57 [Bug c++/67773] New: dealloc called on temp object before and named object after move, while not being called on named object before move awenocur at aol dot com
                   ` (4 preceding siblings ...)
  2015-09-30 11:43 ` awenocur at aol dot com
@ 2015-09-30 12:00 ` awenocur at aol dot com
  2015-09-30 13:45 ` redi at gcc dot gnu.org
  2015-09-30 13:49 ` redi at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: awenocur at aol dot com @ 2015-09-30 12:00 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67773

--- Comment #6 from Adam Wenocur <awenocur at aol dot com> ---
Whoops! Sorry about the malformed double-post.

Another way of explaining the problem is that the compiler appears to be
suppressing the wrong destructor call.  Since this is a move and not a copy, or
in C++03 it's a copy elision, it should be suppressing the destructor call on
the temporary variable.  It's not doing this though; it's suppressing the first
destructor call on the named variable instead.

When I get a chance, I'll build a GCC for testing purposes.  What version would
be appropriate in this case?  Is 4.8.5 supported?


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/67773] destructor called on temp object before and named object after move, while not being called on named object before move
  2015-09-30  0:57 [Bug c++/67773] New: dealloc called on temp object before and named object after move, while not being called on named object before move awenocur at aol dot com
                   ` (5 preceding siblings ...)
  2015-09-30 12:00 ` awenocur at aol dot com
@ 2015-09-30 13:45 ` redi at gcc dot gnu.org
  2015-09-30 13:49 ` redi at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2015-09-30 13:45 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67773

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Adam Wenocur from comment #6)
> Another way of explaining the problem is that the compiler appears to be
> suppressing the wrong destructor call.  Since this is a move and not a copy,
> or in C++03 it's a copy elision,

No, you can't elide an assignment to an existing variable.

> it should be suppressing the destructor
> call on the temporary variable.  It's not doing this though; it's
> suppressing the first destructor call on the named variable instead.

No, that's not how C++ works.

> When I get a chance, I'll build a GCC for testing purposes.  What version
> would be appropriate in this case?  Is 4.8.5 supported?

No, the currently supported versions are listed on the home page,
https://gcc.gnu.org/

The oldest supported release is 4.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/67773] destructor called on temp object before and named object after move, while not being called on named object before move
  2015-09-30  0:57 [Bug c++/67773] New: dealloc called on temp object before and named object after move, while not being called on named object before move awenocur at aol dot com
                   ` (6 preceding siblings ...)
  2015-09-30 13:45 ` redi at gcc dot gnu.org
@ 2015-09-30 13:49 ` redi at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2015-09-30 13:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67773

--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Specifically, a move assignment doesn't destroy anything, it just performs an
assignment. So the named variable is not destroyed, its move assignment
operator is called, which does whatever it is written to do. The temporary is
destroyed at the end of the expression, moving from it doesn't alter its
lifetime in any way. The named variable is destroyed at the end of the block as
usual, move assigning to it doesn't alter its lifetime in any way.

There are online compilers you can use to check the results from various GCC
and Clang releases, e.g. http://melponlorg/wandbox

You will find none of them runs a destructor on the target of a move
assignment, because that's not how C++ works.


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-09-30 13:49 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-30  0:57 [Bug c++/67773] New: dealloc called on temp object before and named object after move, while not being called on named object before move awenocur at aol dot com
2015-09-30  1:37 ` [Bug c++/67773] destructor " awenocur at aol dot com
2015-09-30  9:19 ` redi at gcc dot gnu.org
2015-09-30  9:21 ` redi at gcc dot gnu.org
2015-09-30 11:42 ` awenocur at aol dot com
2015-09-30 11:43 ` awenocur at aol dot com
2015-09-30 12:00 ` awenocur at aol dot com
2015-09-30 13:45 ` redi at gcc dot gnu.org
2015-09-30 13:49 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).