This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug debug/49951] [4.5/4.6/4.7 Regression] Debug stepping behavior regarding g++ Class destructor has changed for the worse starting at gcc 4.5.0
- From: "dodji at seketeli dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sat, 03 Dec 2011 20:55:15 +0000
- Subject: [Bug debug/49951] [4.5/4.6/4.7 Regression] Debug stepping behavior regarding g++ Class destructor has changed for the worse starting at gcc 4.5.0
- Auto-submitted: auto-generated
- References: <bug-49951-4@http.gcc.gnu.org/bugzilla/>
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.