https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86575

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mpolacek at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The bug is in:
          /* Nested scope.  Only look at the last statement of
             the innermost scope.  */
          location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
          gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
          if (last)
            {
              prev = last;
              /* It might be a label without a location.  Use the
                 location of the scope then.  */
              if (!gimple_has_location (prev))
                gimple_set_location (prev, bind_loc);
            }
          gsi_next (gsi_p);

The gimple_set_location in there may affect code generation, on this testcase
the difference is unimportant:
@@ -25,10 +25,10 @@ f2:
        movl    -4(%rbp), %eax
        cmpl    -28(%rbp), %eax
        jl      .L5
-       jmp     .L7
+       jmp     .L4
 .L6:
        nop
-.L7:
+.L4:
        nop
        popq    %rbp
        .cfi_def_cfa 7, 8
but on others it could matter.

I see roughly two possibilities to solve this, one is never set a location in
the warning code and use some on-the-side hash map for the warning and use some
helper that will use gimple_location and otherwise fall back to looking up the
hash map.
Or, do the gimple_set_location above, but also push into some vector the gimple
* prev we've modified and traverse that vector at the end of
maybe_warn_implicit_fallthrough ? and set gimple location back to
UNKNOWN_LOCATION and finally release the vector.
What I do not know is if this location is needed also in case of nested
switches etc., or if reseting the location back at the end of
maybe_warn_implicit_fallthrough is fine.  Plus, whether !gimple_has_location at
this point always implies gimple_location (prev) == UNKNOWN_LOCATION, or if it
could be already something with on-the-side data (then we'd need to save in the
vector(s) not just gimple *, but also the location_t we should restore to).

Reply via email to