This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug debug/43176] var-tracking fails to notice a value change



------- Comment #4 from jakub at gcc dot gnu dot org  2010-03-02 13:17 -------
There is another very important issue and that is that
emit_note_insn_var_location and vt_expand_loc_callback completely ignores
cur_loc, but the code that decides whether a variable actually changed uses
heavily cur_loc.
So, on guality/vla-1.c (f2):
void bar (short *p);
int
f2 (int i)
{
  short a[i * 2 + 7];
  bar (a);
  return a[i];
}
on x86_64-linux -O2 -g, we have:
  name: D#2
    offset 0
      (value/s/u/f:DI 6:8002 @0x170f458/0x1727080)
 (value/s/u/f:DI 6:8002 @0x170f458/0x1727080)
    offset 0
      (sign_extend:DI (plus:SI (mult:SI (value/s/u:SI 5:5 @0x170f440/0x170f130)
            (const_int 2 [0x2]))
        (const_int 7 [0x7])))
 (value/s/u:SI 5:5 @0x170f440/0x170f130)
    offset 0
      (reg/v:SI 41 r12 [orig:69 iD.1617 ] [69])
      (value/s/u:SI 27:27 @0x170f650/0x17273d0)
 (value/s/u:SI 27:27 @0x170f650/0x17273d0)
    offset 0
      (reg:SI 5 di [ iD.1617 ])
      (value/s/u:SI 5:5 @0x170f440/0x170f130)
value 5:5's cur_loc is at this point value 27:27, value 27:27's cur_loc is
%edi.
That is not a cur_loc loop.  But, when we vt_expand_loc on the array bound, we
completely ignore cur_loc fields, and thus emit var_location for the array
bound using %r12 register instead of %rdi (both contain at that point the same
value).  cur_loc of the value stays to be value 27:27, later on %r12 is
changed, %r12 disappears from value 5:5's location list, but as it is not
cur_loc, it is not marked as changed, eventhough vt_expand_loc actually used
that register.  The code believes it lives in %rdi and finally when %rdi is
clobbered, the var is marked as changed and the code figures out it is no
longer anywhere.

Thinking about it, is there any reason why we bother with cur_loc before
vt_emit_notes at all?  Shouldn't emit_notes_for_differences just ignore cur_loc
differences, as long as the old cur_loc is on the loc_chain list (in that case
just update it in the new_var to point to whatever it was pointing in the
old_var)?  And, shouldn't emit_note_insn_var_location and
vt_expand_loc_callback just use cur_loc, unconditionally, instead of
unconditionally using the first location (emit_note_insn_var_location) resp.
looping through all locations (vt_expand_loc_callback)?  For
MAY_HAVE_DEBUG_INSNS I guess check_changed_vars_{1,2} would need to verify
cur_loc and update it if needed.
In emit_note_insn_var_location we can surely update cur_loc too (and, loop
through all locations until we find one for which vt_expand_loc returns
non-NULL), as we know dv is not a VALUE nor DEBUG_EXPR_DECL.  But in
vt_expand_loc_callback I'm not 100% sure it is not too late to update it.
Perhaps we could update it there, but after clearing all cur_loc values in
check_changed_vars_{1,2} and then in vt_expand_loc_callback use cur_loc
unconditionally if non-NULL, if NULL loop through all locations and set
cur_loc.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43176


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]