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