On Tue, Mar 24, 2015 at 10:20:20AM -0700, Kenton Varda wrote: > My hunch is that GCC is incorrectly deciding that the modifications to > the source object don't matter, perhaps because it's a temporary that > will be destroyed shortly anyway and GCC incorrectly decides that D's > destructor is trivial. It seems to be affected by the presence of > virtual inheritance.
I digged a bit. The code is still in there after the "Value range propagation" pass: | struct D D.2804; | bool _10; | | D.2804 = {}; | [...] | MEM[(struct A &)&D.2804 + 8].moved = 1; | [...] | _10 = MEM[(struct A *)&D.2804 + 8B].moved; | if (_10 != 0) After the first "Dead code elimination" it's gone: | struct D D.2804; | bool _10; | | MEM[(struct C *)&D.2804] ={v} {CLOBBER}; | _10 = MEM[(struct A *)&D.2804 + 8B].moved; | if (_10 != 0) Let's try disabling this pass: | $ g++ -o test test.cpp -Wall -W -std=c++11 -O2 -fdisable-tree-dce1 | cc1plus: note: disable pass tree-dce1 for functions in the range of [0, 4294967295] | $ ./test | ~A(): moved = true | ~A(): moved = false Let's try with 4.8. Wow, this looks completely different. 4.8 managed to get rid of the whole block way earlier in the optimization. (4.9 refuses to inline D::~D(), because it is too large). Bastian -- Conquest is easy. Control is not. -- Kirk, "Mirror, Mirror", stardate unknown -- To UNSUBSCRIBE, email to debian-gcc-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: https://lists.debian.org/20150324193448.ga22...@mail.waldi.eu.org