[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#781060: g++-4.9: Broken optimization when move-constructing from virtual subclass



Package: g++-4.9
Version: 4.9.2-10

Using g++ 4.9.2-10 on amd64, the below program behaves differently
when compiled with -O2 vs. not. The non-optimized version is correct;
the program's output should be:

~A(): moved = true
~A(): moved = false

However, with the optimized version, the program incorrectly outputs:

~A(): moved = false
~A(): moved = false

I.e. the line `other.moved = true` has been elided, or perhaps written
to the wrong location in memory. In practice, given the typical use
cases for move constructors, this bug tends to cause double-frees and
use-after-frees. In praticular, this is breaking the Cap'n Proto
library, which I maintain.

The attached self-contained script will demonstrate the problem.

Both G++ 4.8.4-1 and Clang 3.5.0-10 produce the correct output.
Additionally, G++ "4.9.2 20150304 (prerelease)" on Arch Linux produces
the correct output, possibly suggesting that this bug is
Debian-specific. (You can test different compiler versions by passing
the compiler command to use as the script's first parameter. By
default it uses `g++`.)

-Kenton

=======Program text=======
#include <stdio.h>

class A {
public:
  bool moved = false;

  A() = default;
  A(A&& other) {
    other.moved = true;
  }
  ~A() {
    printf("~A(): moved = %s\n", moved ? "true" : "false");
  }
};
class B: virtual public A {};
class C: virtual public B {};
class D: public C {};

int main() {
  A a = D();
}
=========================

-- System Information:
Debian Release: 8.0
  APT prefers testing-updates
  APT policy: (500, 'testing-updates'), (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.16.0-4-amd64 (SMP w/12 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages g++-4.9 depends on:
ii  gcc-4.9            4.9.2-10
ii  gcc-4.9-base       4.9.2-10
ii  libc6              2.19-15
ii  libcloog-isl4      0.18.2-1+b2
ii  libgmp10           2:6.0.0+dfsg-6
ii  libisl10           0.12.2-2
ii  libmpc3            1.0.2-1
ii  libmpfr4           3.1.2-2
ii  libstdc++-4.9-dev  4.9.2-10
ii  zlib1g             1:1.2.8.dfsg-2+b1

g++-4.9 recommends no packages.

Versions of packages g++-4.9 suggests:
ii  g++-4.9-multilib    4.9.2-10
pn  gcc-4.9-doc         <none>
pn  libstdc++6-4.9-dbg  <none>

-- no debconf information

Attachment: test-move-from-virtual-subclass.sh
Description: Bourne shell script


Reply to: