1 // RUN: %check_clang_tidy %s cppcoreguidelines-avoid-goto %t
2 
noop()3 void noop() {}
4 
main()5 int main() {
6   noop();
7   goto jump_to_me;
8   // CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control
9   // CHECK-NOTES: [[@LINE+3]]:1: note: label defined here
10   noop();
11 
12 jump_to_me:;
13 
14 jump_backwards:;
15   noop();
16   goto jump_backwards;
17   // CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control
18   // CHECK-NOTES: [[@LINE-4]]:1: note: label defined here
19 
20   goto jump_in_line;
21   ;
22 jump_in_line:;
23   // CHECK-NOTES: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control
24   // CHECK-NOTES: [[@LINE-2]]:1: note: label defined here
25 
26   // Test the GNU extension https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
27 some_label:;
28   void *dynamic_label = &&some_label;
29 
30   // FIXME: `IndirectGotoStmt` is not detected.
31   goto *dynamic_label;
32 }
33 
forward_jump_out_nested_loop()34 void forward_jump_out_nested_loop() {
35   int array[] = {1, 2, 3, 4, 5};
36   for (int i = 0; i < 10; ++i) {
37     noop();
38     for (int j = 0; j < 10; ++j) {
39       noop();
40       if (i + j > 10)
41         goto early_exit1;
42     }
43     noop();
44   }
45 
46   for (int i = 0; i < 10; ++i) {
47     noop();
48     while (true) {
49       noop();
50       if (i > 5)
51         goto early_exit1;
52     }
53     noop();
54   }
55 
56   for (auto value : array) {
57     noop();
58     for (auto number : array) {
59       noop();
60       if (number == 5)
61         goto early_exit1;
62     }
63   }
64 
65   do {
66     noop();
67     do {
68       noop();
69       goto early_exit1;
70     } while (true);
71   } while (true);
72 
73   do {
74     for (auto number : array) {
75       noop();
76       if (number == 2)
77         goto early_exit1;
78     }
79   } while (true);
80 
81   // Jumping further results in error, because the variable declaration would
82   // be skipped.
83 early_exit1:;
84 
85   int i = 0;
86   while (true) {
87     noop();
88     while (true) {
89       noop();
90       if (i > 5)
91         goto early_exit2;
92       i++;
93     }
94     noop();
95   }
96 
97   while (true) {
98     noop();
99     for (int j = 0; j < 10; ++j) {
100       noop();
101       if (j > 5)
102         goto early_exit2;
103     }
104     noop();
105   }
106 
107   while (true) {
108     noop();
109     for (auto number : array) {
110       if (number == 1)
111         goto early_exit2;
112       noop();
113     }
114   }
115 
116   while (true) {
117     noop();
118     do {
119       noop();
120       goto early_exit2;
121     } while (true);
122   }
123 early_exit2:;
124 }
125 
jump_out_backwards()126 void jump_out_backwards() {
127 
128 before_the_loop:
129   noop();
130 
131   for (int i = 0; i < 10; ++i) {
132     for (int j = 0; j < 10; ++j) {
133       if (i * j > 80)
134         goto before_the_loop;
135       // CHECK-NOTES: [[@LINE-1]]:9: warning: avoid using 'goto' for flow control
136       // CHECK-NOTES: [[@LINE-8]]:1: note: label defined here
137     }
138   }
139 }
140