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