diff options
author | Marek Polacek <polacek@redhat.com> | 2022-03-28 18:19:20 -0400 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2022-03-29 14:10:37 -0400 |
commit | d886a5248e66ab911391af18bf955beb87ee8461 (patch) | |
tree | f47537490d8af1be79da3e2789de16eb383f891e /gcc/testsuite/c-c++-common/Wimplicit-fallthrough-39.c | |
parent | 89976d082488b3a7dc7520b980f854ce83043d38 (diff) | |
download | gcc-d886a5248e66ab911391af18bf955beb87ee8461.zip gcc-d886a5248e66ab911391af18bf955beb87ee8461.tar.gz gcc-d886a5248e66ab911391af18bf955beb87ee8461.tar.bz2 |
gimple: Wrong -Wimplicit-fallthrough with if(1) [PR103597]
This patch fixes a wrong -Wimplicit-fallthrough warning for
case 0:
if (1) // wrong may fallthrough
return 0;
case 1:
which in .gimple looks like
<D.1981>: // case 0
if (1 != 0) goto <D.1985>; else goto <D.1986>;
<D.1985>:
D.1987 = 0;
// predicted unlikely by early return (on trees) predictor.
return D.1987;
<D.1986>: // dead
<D.1982>: // case 1
and the warning thinks that <D.1986>: falls through to <D.1982>:. It
does not know that <D.1986> is effectively a dead label, only reachable
through fallthrough from previous instructions, never jumped to. To
that effect, Jakub introduced UNUSED_LABEL_P, which is set on such dead
labels.
collect_fallthrough_labels has code to deal with cases like
case 2:
if (e != 10)
i++; // this may fallthru, warn
else
return 44;
case 3:
which collects labels that may fall through. Here it sees the "goto <D.1990>;"
at the end of the then branch and so when the warning reaches
...
<D.1990>: // from if-then
<D.1984>: // case 3
it knows it should warn about the possible fallthrough. But an UNUSED_LABEL_P
is not a label that can fallthrough like that, so it should ignore those.
However, we still want to warn about this:
case 0:
if (1)
n++; // falls through
case 1:
so collect_fallthrough_labels needs to return the "n = n + 1;" statement, rather
than the dead label.
Co-authored-by: Jakub Jelinek <jakub@redhat.com>
PR middle-end/103597
gcc/ChangeLog:
* gimplify.cc (collect_fallthrough_labels): Don't push UNUSED_LABEL_Ps
into labels. Maybe set prev to the statement preceding UNUSED_LABEL_P.
(gimplify_cond_expr): Set UNUSED_LABEL_P.
* tree.h (UNUSED_LABEL_P): New.
gcc/testsuite/ChangeLog:
* c-c++-common/Wimplicit-fallthrough-39.c: New test.
Diffstat (limited to 'gcc/testsuite/c-c++-common/Wimplicit-fallthrough-39.c')
-rw-r--r-- | gcc/testsuite/c-c++-common/Wimplicit-fallthrough-39.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-39.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-39.c new file mode 100644 index 0000000..da4aef3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-39.c @@ -0,0 +1,140 @@ +/* PR middle-end/103597 */ +/* { dg-do compile } */ +/* { dg-options "-Wimplicit-fallthrough" } */ + +#define E(c, e) if (c) e + +int +fn0 (int n) +{ + switch (n) + { + case 0: + E (1, return 0); + case 1: + return -1; + } + return 0; +} + +int +fn1 (int n) +{ + switch (n) + { + case 0: + E (1, goto out); + case 1: + return -1; + } +out: + return 0; +} + +int +fn2 (int n) +{ + switch (n) + { + case 0: + if (1) /* { dg-warning "statement may fall through" "" { target c++ } } */ + n++; /* { dg-warning "statement may fall through" "" { target c } } */ + case 1: /* { dg-message "here" } */ + return -1; + } + return 0; +} + +int +fn3 (int n) +{ + switch (n) + { + case 0: + if (0) /* { dg-warning "statement may fall through" } */ + return 0; + case 1: /* { dg-message "here" } */ + return -1; + } + return 0; +} + +int +fn4 (int n) +{ + switch (n) + { + case 0: + E (0, n++); + --n; /* { dg-warning "statement may fall through" } */ + case 1: /* { dg-message "here" } */ + return -1; + } + return 0; +} + +int +fn5 (int n) +{ + switch (n) + { + case 0: + if (1) + return 0; + else + return -1; + case 1: + return -1; + } + return 0; +} + +int +fn6 (int n) +{ + switch (n) + { + case 0: + if (1) + return 0; + else + { +meow: + n--; /* { dg-warning "statement may fall through" } */ + } + case 1: /* { dg-message "here" } */ + return -1; + case 2: + goto meow; + } + return 0; +} + +int +fn7 (int n) +{ + switch (n) + { + case 0: + if (1) + return 0; +woof: + case 1: + return -1; + } + return 0; +} + +int +fn8 (int n) +{ + switch (n) + { + case 0: + if (1) n++; /* { dg-warning "statement may fall through" } */ +woof: /* { dg-message "here" } */ + case 1: + return -1; + } + return 0; +} |