------- Comment #16 from jason at gcc dot gnu dot org 2009-03-07 20:16 ------- So here's what happens:
1) The front end chooses 'x' as the NRV for f4 and rewrites the assignments. 2) inlining creates a temporary variable for the return value of f1. So we have <bb 3>: D.1204 = ax; <retval> = D.1204; goto <bb 5>; <bb 4>: <retval> = OBJ_TYPE_REF(*this->_vptr.C;this->0) (this); 3) tree-nrv looks at this, sees <retval> = D.1204, doesn't see the other assignment to retval because it's a GIMPLE_CALL rather than a GIMPLE_ASSIGN, and decides to make D.1204 the NRV. 4) tree-nrv copies the debugging information for D.1204 over the debugging information for the f4 return value, which already had the info for 'x'. 5) The f4 retval now has DECL_ABSTRACT_ORIGIN referring to f1, which causes chaos. It seems that there are several bugs here: * tree-nrv shouldn't do NRV after the front end already did, as it might miss modifications that aren't of the form it expects. Specifically, it doesn't seem to check whether anything takes the address of the RESULT_DECL. * tree-nrv needs to notice GIMPLE_CALL modifications. * tree-nrv shouldn't clobber the debug information on the RESULT_DECL in favor of another artificial variable. * tree-nrv shouldn't copy DECL_ABSTRACT_ORIGIN that refers to another function. I'm working on a patch for all these issues. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39086