[Bug debug/90574] [gdb] gdb wrongly stopped at a breakpoint in an unexecuted line of code

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Jun 6 10:57:00 GMT 2019


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

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Related testcase:

int main(int argc, char **argv)
{
  switch (argc)
    {
    case 0:
      {
        foo:;
      }
    case 1:;
    }
  return 0;
}

breaking on the foo: line stops.

Fixing this is a two-edged sword - we do try to build an optimized CFG
(esp. for case label merging), creating more blocks defeats this.
It might be possible to move cleanup_dead_labels after make_edges
so that we can split blocks again when we make edges - but for
switch stmts that would be quite expensive as well.

But to fix these issues building more blocks is a requirement.

The following does this:

Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c      (revision 271990)
+++ gcc/tree-cfg.c      (working copy)
@@ -2722,10 +2722,10 @@ stmt_starts_bb_p (gimple *stmt, gimple *
          || FORCED_LABEL (gimple_label_label (label_stmt)))
        return true;

-      if (prev_stmt && gimple_code (prev_stmt) == GIMPLE_LABEL)
+      if (glabel *plabel = safe_dyn_cast <glabel *> (prev_stmt))
        {
-         if (DECL_NONLOCAL (gimple_label_label (
-                              as_a <glabel *> (prev_stmt))))
+         if (DECL_NONLOCAL (gimple_label_label (plabel))
+             || !DECL_ARTIFICIAL (gimple_label_label (plabel)))
            return true;

          cfg_stats.num_merged_labels++;

it will ensure new BBs for consecutive user labels and artificial labels
following a user label assuming that is the target of a goto.

It prevents case merging for the above testcase during CFG build
when not optimizing CFG cleanup merges them though and in the correct
fasion, deleting the user label, when optimizing.

The debug experience is that gdb no longer stops at the line with the
label but setting a breakpoint on its line will stop at some other
line (that's a consumer issue I guess?).


More information about the Gcc-bugs mailing list