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

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Completely untested patch to set the flag when a label is only known reachable
through fallthrough from previous instructions, never jumped to, as the only
goto to it is on a non-executable branch of GIMPLE_COND with constant
condition.
--- gcc/tree.h.jj       2021-11-29 14:24:14.121633747 +0100
+++ gcc/tree.h  2021-12-07 19:26:06.645324657 +0100
@@ -787,6 +787,12 @@ extern void omp_clause_range_check_faile
 #define SWITCH_BREAK_LABEL_P(NODE) \
   (LABEL_DECL_CHECK (NODE)->base.protected_flag)

+/* Set on label that is known not to be jumped to, it can be only
+   reached by falling through from previous statements.
+   This is used to implement -Wimplicit-fallthrough.  */
+#define UNUSED_LABEL_P(NODE) \
+  (LABEL_DECL_CHECK (NODE)->base.default_def_flag)
+
 /* Nonzero means this expression is volatile in the C sense:
    its address should be of type `volatile WHATEVER *'.
    In other words, the declared item is volatile qualified.
--- gcc/gimplify.c.jj   2021-12-02 19:41:52.620552908 +0100
+++ gcc/gimplify.c      2021-12-07 19:49:43.964134745 +0100
@@ -4387,9 +4387,19 @@ gimplify_cond_expr (tree *expr_p, gimple
       if (TREE_OPERAND (expr, 1) == NULL_TREE
          && !have_else_clause_p
          && TREE_OPERAND (expr, 2) != NULL_TREE)
-       label_cont = label_true;
+       {
+         /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
+            handling that label_cont == label_true can be only reached
+            through fallthrough from { code; }.  */
+         if (integer_zerop (COND_EXPR_COND (expr)))
+           UNUSED_LABEL_P (label_true) = 1;
+         label_cont = label_true;
+       }
       else
        {
+         bool then_side_effects
+           = (TREE_OPERAND (expr, 1)
+              && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)));
          gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
          have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
          /* For if (...) { code; } else {} or
@@ -4403,6 +4413,16 @@ gimplify_cond_expr (tree *expr_p, gimple
              gimple *g;
              label_cont = create_artificial_label (UNKNOWN_LOCATION);

+             /* For if (0) { non-side-effect-code } else { code }
+                tell -Wimplicit-fallthrough handling that label_cont can
+                be only reached through fallthrough from { code }.  */
+             if (integer_zerop (COND_EXPR_COND (expr)))
+               {
+                 UNUSED_LABEL_P (label_true) = 1;
+                 if (!then_side_effects)
+                   UNUSED_LABEL_P (label_cont) = 1;
+               }
+
              g = gimple_build_goto (label_cont);

              /* GIMPLE_COND's are very low level; they have embedded
@@ -4419,6 +4439,13 @@ gimplify_cond_expr (tree *expr_p, gimple
     }
   if (!have_else_clause_p)
     {
+      /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
+        tell -Wimplicit-fallthrough handling that label_false can be only
+        reached through fallthrough from { code }.  */
+      if (integer_nonzerop (COND_EXPR_COND (expr))
+         && (TREE_OPERAND (expr, 2) == NULL_TREE
+             || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))))
+       UNUSED_LABEL_P (label_false) = 1;
       gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
       have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
     }

Reply via email to