1// RUN: %clang_cc1 -std=c++1z -verify %s
2
3void f(int n) {
4  switch (n) {
5  case 0:
6    n += 1;
7    [[fallthrough]]; // ok
8  case 1:
9    if (n) {
10      [[fallthrough]]; // ok
11    } else {
12      return;
13    }
14  case 2:
15    for (int n = 0; n != 10; ++n)
16      [[fallthrough]]; // expected-error {{does not directly precede switch label}}
17  case 3:
18    while (true)
19      [[fallthrough]]; // expected-error {{does not directly precede switch label}}
20  case 4:
21    while (false)
22      [[fallthrough]]; // expected-error {{does not directly precede switch label}}
23  case 5:
24    do [[fallthrough]]; while (true); // expected-error {{does not directly precede switch label}}
25  case 6:
26    do [[fallthrough]]; while (false); // expected-error {{does not directly precede switch label}}
27  case 7:
28    switch (n) {
29    case 0:
30      // FIXME: This should be an error, even though the next thing we do is to
31      // fall through in an outer switch statement.
32      [[fallthrough]];
33    }
34  case 8:
35    [[fallthrough]]; // expected-error {{does not directly precede switch label}}
36    goto label;
37  label:
38  case 9:
39    n += 1;
40  case 10: // no warning, -Wimplicit-fallthrough is not enabled in this test, and does not need to
41           // be enabled for these diagnostics to be produced.
42    break;
43  }
44}
45
46[[fallthrough]] typedef int n; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
47typedef int [[fallthrough]] n; // expected-error {{'fallthrough' attribute cannot be applied to types}}
48typedef int n [[fallthrough]]; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
49
50enum [[fallthrough]] E {}; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
51class [[fallthrough]] C {}; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
52
53[[fallthrough]] // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
54void g() {
55  [[fallthrough]] int n; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
56  [[fallthrough]] ++n; // expected-error-re {{{{^}}fallthrough attribute is only allowed on empty statements}}
57
58  switch (n) {
59    // FIXME: This should be an error.
60    [[fallthrough]];
61    return;
62
63  case 0:
64    [[fallthrough, fallthrough]]; // expected-error {{multiple times}}
65  case 1:
66    [[fallthrough(0)]]; // expected-error {{argument list}}
67  case 2:
68    break;
69  }
70}
71