1 | // RUN: %check_clang_tidy %s cppcoreguidelines-avoid-goto %t |
2 | |
3 | void noop() {} |
4 | |
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 | |
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 | |
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 | |