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.

Reply via email to