Hi!

emit_note_insn_var_location already had code to ensure that
non-NOTE_DURING_CALL_P notes emitted EMIT_NOTE_BEFORE_INSN
with NEXT_INSN (call_insn) are put after all the NOTE_DURING_CALL_P
notes after the call, but if there is NOTE_INSN_CALL_ARG_LOCATION
note there too, this code doesn't trigger and we would emit
a non-NOTE_DURING_CALL_P note before NOTE_INSN_CALL_ARG_LOCATION
note possibly followed by NOTE_DURING_CALL_P notes.  That then may
trigger ICEs in dwarf2out, which assumes that the LVL labels change
monotonically, and that for calls first come all .LVLXXX-1 labels (if any)
and then .LVLXXX (if any).

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux and
with go cross to s390x-linux.  Ok for trunk?

2012-02-08  Jakub Jelinek  <ja...@redhat.com>

        PR debug/52165
        * var-tracking.c (emit_note_insn_var_location): If
        EMIT_NOTE_BEFORE_INSN and insn is NOTE_INSN_CALL_ARG_LOCATION,
        emit it before next non-NOTE_INSN_CALL_ARG_LOCATION
        non-NOTE_DURING_CALL_P insn.

--- gcc/var-tracking.c.jj       2012-01-30 00:10:01.000000000 +0100
+++ gcc/var-tracking.c  2012-02-08 16:20:54.808523330 +0100
@@ -8225,9 +8225,14 @@ emit_note_insn_var_location (void **varp
       /* Make sure that the call related notes come first.  */
       while (NEXT_INSN (insn)
             && NOTE_P (insn)
-            && NOTE_DURING_CALL_P (insn))
+            && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
+                 && NOTE_DURING_CALL_P (insn))
+                || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
        insn = NEXT_INSN (insn);
-      if (NOTE_P (insn) && NOTE_DURING_CALL_P (insn))
+      if (NOTE_P (insn)
+         && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
+              && NOTE_DURING_CALL_P (insn))
+             || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
        note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
       else
        note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);

        Jakub

Reply via email to