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

source code of clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp