http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54770
Steven Bosscher <steven at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |NEW --- Comment #2 from Steven Bosscher <steven at gcc dot gnu.org> 2012-10-02 11:44:41 UTC --- Confirmed, complete test case: ---------------------- 8< ---------------------- typedef long unsigned int size_t; namespace std { using ::size_t; class exception { public: exception() throw() { } virtual ~exception() throw(); }; class bad_alloc : public exception { public: bad_alloc() throw() { } virtual ~bad_alloc() throw(); }; struct nothrow_t { }; extern const nothrow_t nothrow; } inline void* operator new(std::size_t, void* __p) throw() { return __p; } inline void operator delete (void*, void*) throw() { } template<typename T> struct Intrusive { Intrusive(T * p = 0) : px(p) { if(px) incref(px); } ~Intrusive() { if(px) decref(px); } T * operator->() const { return px; } T * px; }; struct Node; typedef Intrusive<Node> NodePtr; struct Node { Node() : refcnt(0) {} virtual ~Node() {} virtual void H() {} unsigned short refcnt; friend void incref(Node * node) { ++node->refcnt; } friend void decref(Node * node) { if(--node->refcnt == 0) delete node; } }; struct MainNode : Node { MainNode(NodePtr const & arg_) : Node(), arg(arg_) {} virtual ~MainNode() {} NodePtr arg; virtual void H() { { NodePtr tmp(arg); this->~Node(); new(this) MainNode(tmp); } this->H(); } }; int main() { NodePtr arg = NodePtr(); NodePtr root(new MainNode(arg)); root->H(); return 0; } ---------------------- 8< ---------------------- At trunk r191835, compiling with: "./xgcc -B. -S -O3 -fdump-tree-optimized-lineno t.C" Gives the call at line 58: <L6>: tmp ={v} {CLOBBER}; [t.C : 58:15] _13 = MEM[(int (*__vtbl_ptr_type) () *)prephitmp_29+16B]; [t.C : 58:16] OBJ_TYPE_REF(_13;this_3(D)->2) (this_3(D)); [t.C : 59:5] return;