summaryrefslogtreecommitdiff
path: root/gcc/testsuite/c-c++-common
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/c-c++-common')
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-1.c38
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-10.c239
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-11.c23
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-12.c26
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-13.c63
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-14.c162
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-15.c31
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-16.c32
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-17.c29
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-18.c42
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-19.c85
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-2.c223
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-20.c41
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-21.c25
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-3.c543
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-4.c250
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-5.c109
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-6.c305
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-7.c124
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-8.c101
-rw-r--r--gcc/testsuite/c-c++-common/Wimplicit-fallthrough-9.c26
-rw-r--r--gcc/testsuite/c-c++-common/attr-fallthrough-1.c57
-rw-r--r--gcc/testsuite/c-c++-common/attr-fallthrough-2.c54
23 files changed, 2628 insertions, 0 deletions
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-1.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-1.c
new file mode 100644
index 00000000000..b45880f19b4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-1.c
@@ -0,0 +1,38 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+/* Test taken from
+ <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0188r0.pdf>. */
+
+extern void f (int);
+
+void
+foo (int n)
+{
+ switch (n)
+ {
+ case 22:
+ case 33:
+ f (1); /* { dg-warning "statement may fall through" } */
+ case 44:
+ f (2);
+ __attribute__((fallthrough));
+ case 55:
+ if (n > 10)
+ {
+ f (3);
+ break;
+ }
+ else
+ {
+ f (4);
+ __attribute__((fallthrough));
+ }
+ case 66:
+ f (5);
+ __attribute__((fallthrough)); /* { dg-warning "not preceding" } */
+ f (6); /* { dg-warning "statement may fall through" } */
+ case 77:
+ f (7);
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-10.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-10.c
new file mode 100644
index 00000000000..99e44d9be7a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-10.c
@@ -0,0 +1,239 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+extern void bar (int);
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (0);
+ break;
+ }
+ else if (i > 10)
+ {
+ bar (1);
+ __attribute__((fallthrough));
+ }
+ else
+ break;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ bar (2);
+ else if (i > 10)
+ {
+ bar (3);
+ __attribute__((fallthrough));
+ }
+ else
+ break;
+ case 2:
+ bar (4);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (0);
+ break;
+ }
+ else if (i > 10) /* { dg-warning "statement may fall through" } */
+ {
+ bar (1);
+ }
+ else
+ break;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (0);
+ break;
+ }
+ else if (i > 10)
+ {
+ bar (1);
+ break;
+ }
+ else
+ break;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (0);
+ break;
+ }
+ else if (i > 10)
+ {
+ bar (1);
+ break;
+ }
+ else
+ bar (2); /* { dg-warning "statement may fall through" } */
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (0);
+ __attribute__((fallthrough));
+ }
+ else if (i > 10)
+ {
+ bar (1);
+ break;
+ }
+ else
+ bar (2); /* { dg-warning "statement may fall through" } */
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (0);
+ __attribute__((fallthrough));
+ }
+ else if (i > 10)
+ {
+ bar (1);
+ __attribute__((fallthrough));
+ }
+ else
+ break;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (0);
+ __attribute__((fallthrough));
+ }
+ else if (i > 10)
+ {
+ bar (1);
+ __attribute__((fallthrough));
+ }
+ else
+ bar (2); /* { dg-warning "statement may fall through" } */
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (0);
+ __attribute__((fallthrough));
+ }
+ else if (i > 10) /* { dg-warning "statement may fall through" } */
+ {
+ bar (1);
+ bar (2);
+ }
+ else
+ __attribute__((fallthrough));
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ {
+ bar (0);
+ }
+ else if (i > 10)
+ {
+ bar (1);
+ }
+ else
+ {
+ bar (1);
+ __attribute__((fallthrough));
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (0);
+ __attribute__((fallthrough));
+ }
+ else if (i > 10)
+ {
+ bar (1);
+ break;
+ }
+ else
+ {
+ bar (1);
+ __attribute__((fallthrough));
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (0);
+ break;
+ }
+ else if (i > 10) /* { dg-warning "statement may fall through" } */
+ {
+ bar (1);
+ }
+ else
+ {
+ bar (1);
+ __attribute__((fallthrough));
+ }
+ case 2:
+ bar (99);
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-11.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-11.c
new file mode 100644
index 00000000000..e8f47f56ab9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-11.c
@@ -0,0 +1,23 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough -O2" } */
+
+/* Prevent false positive with optimizations. */
+
+extern void g (int);
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i > 10)
+ g (0);
+ else
+ goto L;
+ break;
+L:
+ case 2:;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-12.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-12.c
new file mode 100644
index 00000000000..91a68ab0771
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-12.c
@@ -0,0 +1,26 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough -O2" } */
+
+/* Don't let optimizations preclude the warning. */
+
+extern void bar (int);
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i > 1)
+ bar (1);
+ else
+ goto D;
+ break;
+ case 2:
+ bar (2); /* { dg-warning "statement may fall through" } */
+ D:
+ default:
+ bar (33);
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-13.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-13.c
new file mode 100644
index 00000000000..f3ec79f9756
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-13.c
@@ -0,0 +1,63 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+/* As per <http://security.coverity.com/blog/2013/Sep/gimme-a-break.html>, don't
+ warn for terminated branches (fall through to break / end of the switch). */
+
+extern void bar (int);
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ bar (1);
+ default:
+ return;
+ }
+
+ switch (i)
+ {
+ case 1:
+ bar (1);
+ default:
+ goto X;
+ }
+X:
+
+ switch (i)
+ {
+ case 1:
+ bar (1);
+ default:
+ break;
+ }
+
+ switch (i)
+ {
+ case 1:
+ bar (1);
+ case 2:
+ case 3:
+ default:
+ break;
+ }
+
+ switch (i)
+ {
+ case 1:
+ bar (1);
+ default:;
+ }
+
+ switch (i)
+ {
+ case 1:
+ bar (1);
+ case 2:
+ case 3:
+ default:;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-14.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-14.c
new file mode 100644
index 00000000000..b7c825b5450
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-14.c
@@ -0,0 +1,162 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+/* Test various falls through comments. */
+
+extern void bar (int);
+
+void
+fn (int i)
+{
+ switch (i)
+ {
+ case -1:
+ bar (-1);
+ /*-fallthrough*/
+ case 0:
+ bar (0);
+ /*@fallthrough@*/
+ case 1:
+ bar (1);
+ /* FALL THRU */
+ case 2:
+ bar (2);
+ /* FALLTHRU */
+ case 3:
+ bar (3);
+ /* FALLS THRU */
+ case 4:
+ bar (4);
+ /* FALL-THRU */
+ case 5:
+ bar (5);
+ /* FALL THROUGH */
+ case 6:
+ bar (6);
+ /* FALLTHROUGH */
+ case 7:
+ bar (7);
+ /* FALLS THROUGH */
+ case 8:
+ bar (8);
+ /* FALL-THROUGH */
+ case 9:
+ bar (9);
+ /*FALLTHRU*/
+ case 10:
+ bar (10);
+ /* FALLTHRU.*/
+ case 11:
+ bar (11);
+ /* FALLTHROUGH. */
+ case 12:
+ bar (12);
+ /* Fall thru */
+ case 13:
+ bar (13);
+ /* Falls thru */
+ case 14:
+ bar (14);
+ /* Fall-thru */
+ case 15:
+ bar (15);
+ /* Fall Thru */
+ case 16:
+ bar (16);
+ /* Falls Thru */
+ case 17:
+ bar (17);
+ /* Fall-Thru */
+ case 18:
+ bar (18);
+ /* Fall through */
+ case 19:
+ bar (19);
+ /* Falls through */
+ case 20:
+ bar (20);
+ /* Fall-through */
+ case 21:
+ bar (21);
+ /* Fall Through */
+ case 22:
+ bar (22);
+ /* Falls Through */
+ case 23:
+ bar (23);
+ /* Fall-Through */
+ case 24:
+ bar (24);
+ /* Falls through. */
+ case 25:
+ bar (25);
+ /* Falls through. */
+ case 26:
+ bar (26);
+ /* fall thru */
+ case 27:
+ bar (27);
+ /* falls thru */
+ case 28:
+ bar (28);
+ /* fall-thru */
+ case 29:
+ bar (29);
+ /* fall thru */
+ case 30:
+ bar (30);
+ /* falls thru */
+ case 31:
+ bar (31);
+ /* fall-thru */
+ case 32:
+ bar (32);
+ /* fall through */
+ case 33:
+ bar (33);
+ /* falls through */
+ case 34:
+ bar (34);
+ /* fall-through */
+ default:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 0:
+ i++;
+ /*@fallthrough@*/
+L:
+ default:
+ bar (6);
+ }
+
+ {
+ __label__ L2;
+ switch (i)
+ {
+ case 0:
+ i++;
+ /*@fallthrough@*/
+L2:
+ default:
+ bar (6);
+ }
+ }
+
+ /* Don't generate false -Wswitch-unreachable warning. */
+ switch (i)
+ {
+ /*FALLTHROUGH*/
+ case 0:
+ i++;
+ }
+
+ if (i)
+ {
+ /* fall through */
+ L1:;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-15.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-15.c
new file mode 100644
index 00000000000..ee3e52d5dc4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-15.c
@@ -0,0 +1,31 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+/* Another nested switch. Check that we don't warn here. */
+
+void
+f (int i)
+{
+ int j = 0;
+ switch (i)
+ {
+ case 0:
+ case 1:
+ j = 10;
+ __attribute__((fallthrough));
+ case 2:
+ j += 10;
+ break;
+ case 3:
+ switch (i)
+ {
+ case 5:
+ j += 2;
+ __attribute__((fallthrough));
+ case 6:
+ j += 4;
+ break;
+ }
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-16.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-16.c
new file mode 100644
index 00000000000..923f0121475
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-16.c
@@ -0,0 +1,32 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+/* Another nested switch, and with an initialization on top. Check that
+ we do warn here. */
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ {
+ int t = 3;
+ switch (i)
+ {
+ case 3:
+ if (i > 5)
+ --i;
+ i += 10; /* { dg-warning "statement may fall through" } */
+ case 4:
+ t /= 5;
+ break;
+ }
+ break;
+ }
+ case 2:
+ --i;
+ break;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-17.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-17.c
new file mode 100644
index 00000000000..23ff5f184fb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-17.c
@@ -0,0 +1,29 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+/* Another nested switch, and with an initialization on top. Check that
+ we do not warn here as the case 3 falls through to break. */
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ {
+ int t = 3;
+ switch (i)
+ {
+ case 3:
+ i += 10;
+ case 4:
+ break;
+ }
+ break;
+ }
+ case 2:
+ --i;
+ break;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-18.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-18.c
new file mode 100644
index 00000000000..2c8a3cb98b3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-18.c
@@ -0,0 +1,42 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+/* Testing some loops. */
+
+int f (void);
+
+int
+g (int i)
+{
+ switch (i)
+ {
+ case 0:
+ for (;;)
+ {
+ if (f ()) /* { dg-warning "statement may fall through" "fall through" { xfail *-*-* } } */
+ break;
+ }
+ case 1:
+ return 1;
+ }
+ return 0;
+}
+
+int
+h (int i)
+{
+ switch (i)
+ {
+ case 0:
+ do
+ {
+ if (f ()) /* { dg-warning "statement may fall through" } */
+ break;
+ }
+ while (0);
+ case 1:
+ return 1;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-19.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-19.c
new file mode 100644
index 00000000000..b7a37910db3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-19.c
@@ -0,0 +1,85 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+/* Testing non-case labels. */
+
+int foo (int);
+
+void
+f1 (int i)
+{
+ switch (i)
+ {
+ case 0:
+ foo (1);
+ L1:
+ foo (2);
+ }
+
+ switch (i)
+ {
+ case 0:
+ foo (1); /* { dg-warning "statement may fall through" } */
+ L2:
+ case 2:
+ foo (2);
+ }
+
+ switch (i)
+ {
+ case 0:
+ foo (1); /* { dg-warning "statement may fall through" } */
+ case 2:
+ L3:
+ foo (2);
+ }
+
+ switch (i)
+ {
+ case 0:
+ foo (1); /* { dg-warning "statement may fall through" } */
+ L4:
+ case 2:
+ L5:
+ foo (2);
+ }
+
+ switch (i)
+ {
+ case 0:
+ switch (i)
+ {
+ case 1:
+ foo (2);
+ L6:
+ foo (3);
+ }
+ }
+
+ switch (i)
+ {
+ case 0:
+ switch (i)
+ {
+ case 1:
+ foo (2); /* { dg-warning "statement may fall through" } */
+ L7:
+ case 2:
+ foo (3);
+ }
+ }
+
+ switch (i)
+ {
+ case 0:
+ switch (i)
+ {
+ case 1:
+ foo (2); /* { dg-warning "statement may fall through" } */
+ case 2:
+ L8:
+ foo (3);
+ }
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-2.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-2.c
new file mode 100644
index 00000000000..4dfb278c27b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-2.c
@@ -0,0 +1,223 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+extern void bar (int);
+
+/* Test if without else. */
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ return;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ goto L1;
+ case 2:
+L1:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ goto L2;
+L2:
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ goto L3;
+ break;
+ case 2:
+L3:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ goto L4;
+ break;
+L4:
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ if (i > 9)
+ bar (1);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ if (i > 9)
+ bar (1);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ { int a; }
+ {
+ if (i) /* { dg-warning "statement may fall through" } */
+ if (i > 9)
+ bar (1);
+ }
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ bar (2); /* { dg-warning "statement may fall through" } */
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ bar (2);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ bar (2); /* { dg-warning "statement may fall through" } */
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ bar (2);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ if (i)
+ bar (2);
+ if (i)
+ bar (3);
+ bar (4); /* { dg-warning "statement may fall through" } */
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ if (i)
+ bar (2);
+ if (i) /* { dg-warning "statement may fall through" } */
+ bar (3);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ if (i)
+ bar (2);
+ if (i)
+ bar (3);
+ bar (4);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ if (i)
+ bar (2);
+ if (i)
+ bar (3);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-20.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-20.c
new file mode 100644
index 00000000000..d37a840a0d9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-20.c
@@ -0,0 +1,41 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+int
+f (int i)
+{
+ switch (i)
+ {
+ case -1:
+ __attribute__((fallthrough));
+ default:
+ __attribute__((fallthrough));
+ case 1:
+ return 6;
+ case 2 ... 4:
+ __attribute__((fallthrough));
+ case 5:
+ return 7;
+ }
+ return 0;
+}
+
+int
+g (int i)
+{
+ switch (i)
+ {
+ case -1:
+ __attribute__((used)); /* { dg-warning "ignored|only attribute" } */
+ default:
+ __attribute__((used)); /* { dg-warning "ignored|only attribute" } */
+ case 1:
+ return 6;
+ case 2 ... 4:
+ __attribute__((used)); /* { dg-warning "ignored|only attribute" } */
+ case 5:
+ return 7;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-21.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-21.c
new file mode 100644
index 00000000000..6092a9018f3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-21.c
@@ -0,0 +1,25 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+int
+f (int i)
+{
+ switch (i)
+ {
+ case 0:
+ i++;
+ __attribute__((fallthrough));
+ lab1:
+ case 1:
+ i++;
+ __attribute__((fallthrough)); /* { dg-warning "not preceding" } */
+ lab2:
+ --i;
+ break;
+ case 3:
+ i++;
+ break;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-3.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-3.c
new file mode 100644
index 00000000000..fbb97122ecb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-3.c
@@ -0,0 +1,543 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+extern void bar (int);
+
+/* Test if with else. */
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else
+ bar (2);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ else
+ bar (2);
+ bar (3); /* { dg-warning "statement may fall through" } */
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ else
+ bar (2); /* { dg-warning "statement may fall through" } */
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ else
+ bar (2);
+ bar (3); /* { dg-warning "statement may fall through" } */
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else
+ return;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ else
+ return;
+ bar (3); /* { dg-warning "statement may fall through" } */
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ else
+ return;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ else
+ return;
+ bar (3); /* { dg-warning "statement may fall through" } */
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ {
+ bar (1);
+ bar (2);
+ bar (3);
+ bar (4);
+ }
+ else
+ {
+ bar (5);
+ bar (6);
+ bar (7);
+ bar (8);
+ }
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (1);
+ bar (2);
+ bar (3);
+ bar (4);
+ }
+ else
+ {
+ bar (5);
+ bar (6);
+ bar (7);
+ bar (8);
+ }
+ bar (9); /* { dg-warning "statement may fall through" } */
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ {
+ }
+ else
+ bar (2);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else
+ {
+ }
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ {
+ }
+ else
+ {
+ }
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ return;
+ else
+ {
+ }
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ {
+ }
+ else
+ return;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ goto L1;
+ else
+ bar (2); /* { dg-warning "statement may fall through" } */
+ case 2:
+L1:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ goto L2;
+ else
+ bar (2); /* { dg-warning "statement may fall through" } */
+L2:
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else
+ goto L3;
+ case 2:
+L3:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else
+ goto L4;
+L4:
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ goto L5;
+ else
+ goto L5;
+L5:
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ else
+ bar (2);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ else
+ bar (2);
+ bar (3);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ else
+ bar (2);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ else
+ bar (2);
+ bar (3);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ else
+ return;
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ else
+ return;
+ bar (3);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ else
+ return;
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ else
+ return;
+ bar (3);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (1);
+ bar (2);
+ bar (3);
+ bar (4);
+ }
+ else
+ {
+ bar (5);
+ bar (6);
+ bar (7);
+ bar (8);
+ }
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ bar (1);
+ bar (2);
+ bar (3);
+ bar (4);
+ }
+ else
+ {
+ bar (5);
+ bar (6);
+ bar (7);
+ bar (8);
+ }
+ bar (9);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ }
+ else
+ bar (2);
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ else
+ {
+ }
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ }
+ else
+ {
+ }
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ return;
+ else
+ {
+ }
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ {
+ }
+ else
+ return;
+ break;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ goto L6;
+ else
+ bar (2);
+ break;
+ case 2:
+L6:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ goto L7;
+ else
+ bar (2);
+ break;
+L7:
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ else
+ goto L8;
+ break;
+ case 2:
+L8:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ bar (1);
+ else
+ goto L9;
+ break;
+L9:
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i)
+ goto L10;
+ else
+ goto L10;
+ break;
+L10:
+ case 2:
+ __builtin_abort ();
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-4.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-4.c
new file mode 100644
index 00000000000..9a0aeb753d9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-4.c
@@ -0,0 +1,250 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+extern void bar (int);
+
+/* Test if with more elses. */
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i > 5) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else if (i > 10)
+ bar (2);
+ else if (i > 15)
+ bar (3);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else if (i > 10)
+ bar (2);
+ else if (i > 15)
+ bar (3);
+ else
+ bar (4);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5)
+ return;
+ else if (i > 10) /* { dg-warning "statement may fall through" } */
+ bar (2);
+ else if (i > 15)
+ bar (3);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5)
+ return;
+ else if (i > 10) /* { dg-warning "statement may fall through" } */
+ bar (2);
+ else if (i > 15)
+ bar (3);
+ else
+ bar (4);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else if (i > 10)
+ return;
+ else if (i > 15)
+ bar (3);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else if (i > 10)
+ return;
+ else if (i > 15)
+ bar (3);
+ else
+ bar (4);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else if (i > 10)
+ bar (4);
+ else if (i > 15)
+ return;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else if (i > 10)
+ bar (4);
+ else if (i > 15)
+ return;
+ else
+ bar (4);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5)
+ return;
+ else if (i > 10)
+ return;
+ else if (i > 15) /* { dg-warning "statement may fall through" } */
+ bar (3);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5)
+ return;
+ else if (i > 10)
+ return;
+ else if (i > 15) /* { dg-warning "statement may fall through" } */
+ bar (3);
+ else
+ bar (4);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5)
+ return;
+ else if (i > 10) /* { dg-warning "statement may fall through" } */
+ bar (2);
+ else if (i > 15)
+ return;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5)
+ return;
+ else if (i > 10) /* { dg-warning "statement may fall through" } */
+ bar (2);
+ else if (i > 15)
+ return;
+ else
+ bar (4);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else if (i > 10)
+ return;
+ else if (i > 15)
+ return;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5) /* { dg-warning "statement may fall through" } */
+ bar (1);
+ else if (i > 10)
+ return;
+ else if (i > 15)
+ return;
+ else
+ bar (4);
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5)
+ return;
+ else if (i > 10)
+ return;
+ else if (i > 15) /* { dg-warning "statement may fall through" } */
+ return;
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5)
+ return;
+ else if (i > 10)
+ return;
+ else if (i > 15)
+ return;
+ else
+ bar (4); /* { dg-warning "statement may fall through" } */
+ case 2:
+ __builtin_abort ();
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 5)
+ return;
+ else if (i > 10)
+ return;
+ else if (i > 15)
+ return;
+ else
+ return;
+ case 2:
+ __builtin_abort ();
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-5.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-5.c
new file mode 100644
index 00000000000..9317484dbb2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-5.c
@@ -0,0 +1,109 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+extern void bar (int);
+extern void die (void) __attribute__((noreturn));
+
+/* Test may_fallthru-ness. */
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ bar (0);
+ __attribute__((fallthrough));
+ case 2:;
+ }
+
+ switch (i)
+ {
+ case 1:
+ bar (0);
+ return;
+ case 2:;
+ }
+
+ switch (i)
+ {
+ case 1:
+ bar (0);
+ break;
+ case 2:;
+ }
+
+ switch (i)
+ {
+ case 1:
+ bar (0);
+ goto L1;
+L1:
+ case 2:;
+ }
+
+ switch (i)
+ {
+ case 1:
+ bar (0);
+ die ();
+ case 2:;
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int i, j, k;
+ bar (0);
+ __attribute__((fallthrough));
+ }
+ case 2:;
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int i, j, k;
+ bar (0);
+ return;
+ }
+ case 2:;
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int i, j, k;
+ bar (0);
+ break;
+ }
+ case 2:;
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int i, j, k;
+ bar (0);
+ goto L2;
+ }
+L2:
+ case 2:;
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int i, j, k;
+ bar (0);
+ die ();
+ }
+ case 2:;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-6.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-6.c
new file mode 100644
index 00000000000..8364c1b670b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-6.c
@@ -0,0 +1,305 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+extern void bar (int);
+
+/* Test nested scopes. */
+
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ {
+ int j;
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 10; /* { dg-warning "statement may fall through" } */
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int k = 9;
+ k++;
+ {
+ int j = 10;
+ j++; /* { dg-warning "statement may fall through" } */
+ }
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int k = 9;
+ k++;
+ {
+ int j = 10;
+ j++;
+ {
+ bar (1); /* { dg-warning "statement may fall through" } */
+ }
+ }
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ __attribute__((fallthrough));
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ {
+ int k = j + 5;
+ bar (k);
+ __attribute__((fallthrough));
+ }
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ return;
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ goto L1;
+ }
+L1:
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ { /* { dg-warning "statement may fall through" "" { target c } 120 } */
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ return; /* { dg-warning "statement may fall through" "" { target c++ } 124 } */
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ return;
+ else
+ return;
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ { /* { dg-warning "statement may fall through" "" { target c } 148 } */
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ bar (1);
+ else
+ return; /* { dg-warning "statement may fall through" "" { target c++ } 154 } */
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ return;
+ else
+ bar (2); /* { dg-warning "statement may fall through" } */
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ { /* { dg-warning "statement may fall through" "" { target c } 178 } */
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ bar (1);
+ else
+ bar (2); /* { dg-warning "statement may fall through" "" { target c++ } 184 } */
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ return;
+ }
+ break;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ return;
+ else
+ return;
+ }
+ break;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ bar (1);
+ else
+ return;
+ }
+ break;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ return;
+ else
+ bar (2);
+ }
+ break;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ bar (1);
+ else
+ bar (2);
+ }
+ break;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 9;
+ while (1);
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ { /* { dg-warning "statement may fall through" "" { target c } 282 } */
+ int j = 9;
+ switch (j); /* { dg-warning "statement may fall through" "" { target c++ } 284 } */
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ int j = 0;
+ bar (j);
+ if (j == 8)
+ bar (1);
+ else
+ bar (2);
+ __attribute__((fallthrough));
+ }
+ case 2:
+ bar (99);
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-7.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-7.c
new file mode 100644
index 00000000000..21a158ca14f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-7.c
@@ -0,0 +1,124 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+extern void bar (int);
+extern int bar2 (void);
+extern int *map;
+void
+f (int i)
+{
+ switch (i)
+ {
+ case 1:
+ bar (0); /* { dg-warning "statement may fall through" } */
+ static int i = 10;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ { /* { dg-warning "statement may fall through" "" { target c } 23 } */
+ int a[i]; /* { dg-warning "statement may fall through" "" { target c++ } 24 } */
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ for (int j = 0; j < 10; j++) /* { dg-warning "statement may fall through" "" { target c } 33 } */
+ map[j] = j; /* { dg-warning "statement may fall through" "" { target c++ } 34 } */
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ do /* { dg-warning "statement may fall through" "" { target c++ } 42 } */
+ bar (2);
+ while (--i); /* { dg-warning "statement may fall through" "" { target c } 44 } */
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ {
+ switch (i + 2)
+ case 4:
+ bar (1); /* { dg-warning "statement may fall through" } */
+ case 5:
+ bar (5);
+ return;
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:;
+ case 2:;
+ }
+
+ switch (i)
+ {
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i & 1) /* { dg-warning "statement may fall through" } */
+ {
+ bar (23);
+ break;
+ }
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ if (i > 9) /* { dg-warning "statement may fall through" } */
+ {
+ bar (9);
+ if (i == 10)
+ {
+ bar (10);
+ break;
+ }
+ }
+ case 2:
+ bar (99);
+ }
+
+ int r;
+ switch (i)
+ {
+ case 1:
+ r = bar2 ();
+ if (r) /* { dg-warning "statement may fall through" } */
+ break;
+ case 2:
+ bar (99);
+ }
+
+ switch (i)
+ {
+ case 1:
+ r = bar2 ();
+ if (r)
+ return;
+ if (!i) /* { dg-warning "statement may fall through" } */
+ return;
+ case 2:
+ bar (99);
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-8.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-8.c
new file mode 100644
index 00000000000..0ed7928fd79
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-8.c
@@ -0,0 +1,101 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+extern void grace (int);
+
+int
+fn1 (int i)
+{
+ switch (i)
+ case 1:
+ if (i == 5)
+ grace (0);
+ else
+ goto done;
+done:;
+}
+
+int
+fn2 (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i == 5) /* { dg-warning "statement may fall through" } */
+ grace (0);
+ else
+ goto done;
+ case 2:
+ --i;
+ }
+done:;
+}
+
+int
+fn3 (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i == 5)
+ goto done;
+ else
+ goto done;
+ }
+done:;
+}
+
+int
+fn4 (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i == 5)
+ {
+ grace (1);
+ goto done;
+ }
+ else
+ goto done;
+ case 2:;
+ }
+done:;
+}
+
+int
+fn5 (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i == 5)
+ {
+ grace (1);
+ goto done;
+ }
+ else
+ grace (4); /* { dg-warning "statement may fall through" } */
+ case 2:
+ grace (9);
+ }
+done:;
+}
+
+int
+fn6 (int i)
+{
+ switch (i)
+ {
+ case 1:
+ if (i == 5) /* { dg-warning "statement may fall through" } */
+ {
+ grace (1);
+ goto done;
+ }
+ case 2:
+ grace (8);
+ }
+done:;
+}
diff --git a/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-9.c b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-9.c
new file mode 100644
index 00000000000..394d6998b65
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wimplicit-fallthrough-9.c
@@ -0,0 +1,26 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wimplicit-fallthrough" } */
+
+/* Test we don't remove FALLTHROUGH () too early. */
+
+extern void h (int);
+
+void
+g (int i)
+{
+ switch (i)
+ {
+ case 1:
+ {
+ switch (i)
+ {
+ case 3:
+ h (7);
+ __attribute__((fallthrough));
+ case 4:;
+ }
+ }
+ case 2:;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/attr-fallthrough-1.c b/gcc/testsuite/c-c++-common/attr-fallthrough-1.c
new file mode 100644
index 00000000000..ecfd094d9cd
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-fallthrough-1.c
@@ -0,0 +1,57 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wall -Wextra -Wpedantic" } */
+
+extern void bar (int);
+void
+fn (int i)
+{
+ __attribute__((fallthrough)) int j = 0; /* { dg-warning "ignored|attribute not followed" } */
+
+ if (j)
+ __attribute__((fallthrough)); /* { dg-error "invalid use" } */
+
+ __attribute__((fallthrough)); /* { dg-error "invalid use" } */
+ switch (i)
+ {
+ __attribute__((fallthrough)); /* { dg-warning "statement will never" } */
+ case 1:
+ i++;
+ __attribute__((fallthrough));
+ case 2:
+ if (i) /* { dg-warning "statement may fall through" } */
+ bar (2);
+ else
+ __attribute__((fallthrough));
+ case 3:
+ if (i > 1)
+ __attribute__((fallthrough));
+ else
+ return;
+ case 4:
+ if (i)
+ __attribute__((fallthrough)); /* { dg-warning "not preceding" } */
+ __attribute__((fallthrough));
+ case 5:
+ ;
+ __attribute__((fallthrough));
+ case 6:
+ if (i) /* { dg-warning "statement may fall through" } */
+ bar (6);
+ else
+ {
+ __attribute__((fallthrough));
+ }
+ case 7:
+ if (i > 1)
+ {
+ __attribute__((fallthrough));
+ }
+ else
+ bar (7); /* { dg-warning "statement may fall through" } */
+ default:
+ --j;
+ }
+
+ __attribute__((fallthrough)); /* { dg-error "invalid use" } */
+}
diff --git a/gcc/testsuite/c-c++-common/attr-fallthrough-2.c b/gcc/testsuite/c-c++-common/attr-fallthrough-2.c
new file mode 100644
index 00000000000..959564bca9f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-fallthrough-2.c
@@ -0,0 +1,54 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wall -Wextra -Wpedantic -Wno-unused -Wno-implicit-fallthrough" } */
+
+extern void bar (int);
+void
+fn (int i)
+{
+ switch (i)
+ {
+ case 1:
+ bar (1);
+ __attribute__((used));
+ /* { dg-warning "empty declaration" "" { target c } 13 } */
+ /* { dg-warning "ignored" "" { target c++ } 13 } */
+ case 2:
+ bar (1);
+ __attribute__((foo));
+ /* { dg-warning "empty declaration" "" { target c } 18 } */
+ /* { dg-warning "ignored" "" { target c++ } 18 } */
+ case 3:
+ bar (1);
+ __attribute__((fallthrough)) /* { dg-warning "not followed" "" { target c } } */
+ case 4: /* { dg-error "expected" } */
+ bar (1);
+ __attribute__((fallthrough)) 1;
+ /* { dg-error "expected" "" { target c } 26 } */
+ /* { dg-warning "not followed" "" { target *-*-* } 26 } */
+ case 5:
+ bar (1);
+ __attribute__((fallthrough)) int i; /* { dg-warning "ignored|not followed" } */
+ case 6:
+ bar (1);
+ __attribute__((fallthrough ("x"))); /* { dg-warning "specified with a parameter" } */
+ case 7:
+ bar (1);
+ __attribute__((fallthrough, fallthrough)); /* { dg-warning "attribute specified multiple times" } */
+ case 8:
+ bar (1);
+ __attribute__((fallthrough));
+ case 9:
+ __attribute__((fallthrough));
+ /* { dg-warning "not preceding" "" { target *-*-* } 42 } */
+ bar (1);
+ case 10:
+ bar (1);
+ __attribute__((unused, fallthrough)); /* { dg-warning "attribute ignored" } */
+ case 11:
+ bar (1);
+ __attribute__((fallthrough, unused)); /* { dg-warning "attribute ignored" } */
+ default:
+ bar (99);
+ }
+}