http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49951
--- Comment #10 from dodji at seketeli dot org <dodji at seketeli dot org> 2011-12-03 20:55:15 UTC --- > What I don't understand is how, according to your analysis, this > worked before revision 149722 and how that patch could possibly > change the behavior. OK, you caught me. I admit I haven't really looked at that patch before starting debugging this issue. So now I might have an additional theory. :-) I think that before the commit r149722, the call expression to the destructor simply had no location. And that patch added a location to it. So we didn't have the jumpy behaviour because we were ignoring the presence of the call to the destructor, from a stepping point of view. Here is why I am thinking that. The call to the destructor of "m" ends up being generated by build_cxx_call, in cp/call.c. At the time of the patch, that function started with: tree build_cxx_call (tree fn, int nargs, tree *argarray) { tree fndecl; fn = build_call_a (fn, nargs, argarray); ... } So it was calling build_call_a, that the patch modified as: --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -362,7 +362,8 @@ build_call_a (tree function, int n, tree *argarray) argarray[i], t); } - function = build_call_array (result_type, function, n, argarray); + function = build_call_array_loc (input_location, + result_type, function, n, argarray); TREE_HAS_CONSTRUCTOR (function) = is_constructor; TREE_NOTHROW (function) = nothrow; See how the call to build_call_array got changed into a call tobuild_call_array_loc. The change that turned build_call_array into build_call_array_loc in tree.c was: tree -build_call_array (tree return_type, tree fn, int nargs, const tree *args) +build_call_array_loc (location_t loc, tree return_type, tree fn, + int nargs, const tree *args) { tree t; int i; @@ -8549,6 +8550,7 @@ build_call_array (tree return_type, tree fn, int nargs, const tree *args) for (i = 0; i < nargs; i++) CALL_EXPR_ARG (t, i) = args[i]; process_call_operands (t); + SET_EXPR_LOCATION (t, loc); return t; } See how the patch adds a location to the resulting call expression there. Without that, the previous build_call_array just had no location, I think. The change you had to do on gcc/testsuite/g++.dg/gcov/gcov-2.C doesn't seem to argue against this theory: @@ -20,7 +20,7 @@ private: void foo() { - C c; /* count(1) */ + C c; /* count(2) */ c.seti (1); /* count(1) */ } Here we see that before the patch, there was only one call issued on the line of C c; - and that was probably the call to the constructor. After, there were two calls on that line, and I think that was the call to the destructor that added up. Note that we didn't have any call on the line of the closing '}', for instance. Now I am thinking that maybe it would be best to have the call to the destructor be on the last statement of the block, rather than on the '}', if we'd have a location for that call at all.