[clang-tidy] implement check for goto
The usage of `goto` is discourage in C++ since forever. This check implements
a warning for every `goto`. Even though there are (rare) valid use cases for
`goto`, better high level constructs should be used.
`goto` is used sometimes in C programs to free resources at the end of
functions in the case of errors. This pattern is better implemented with
RAII in C++.
Reviewers: aaron.ballman, alexfh, hokein
Reviewed By: aaron.ballman
Subscribers: lebedev.ri, jbcoe, Eugene.Zelenko, klimek, nemanjai, mgorny, xazax.hun, kbarton, cfe-commits
Differential Revision: https://reviews.llvm.org/D41815
llvm-svn: 322626
2018-01-17 18:27:41 +08:00
|
|
|
// RUN: %check_clang_tidy %s cppcoreguidelines-avoid-goto %t
|
|
|
|
|
|
|
|
void noop() {}
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
noop();
|
|
|
|
goto jump_to_me;
|
2018-10-02 17:38:26 +08:00
|
|
|
// CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control
|
|
|
|
// CHECK-NOTES: [[@LINE+3]]:1: note: label defined here
|
[clang-tidy] implement check for goto
The usage of `goto` is discourage in C++ since forever. This check implements
a warning for every `goto`. Even though there are (rare) valid use cases for
`goto`, better high level constructs should be used.
`goto` is used sometimes in C programs to free resources at the end of
functions in the case of errors. This pattern is better implemented with
RAII in C++.
Reviewers: aaron.ballman, alexfh, hokein
Reviewed By: aaron.ballman
Subscribers: lebedev.ri, jbcoe, Eugene.Zelenko, klimek, nemanjai, mgorny, xazax.hun, kbarton, cfe-commits
Differential Revision: https://reviews.llvm.org/D41815
llvm-svn: 322626
2018-01-17 18:27:41 +08:00
|
|
|
noop();
|
|
|
|
|
|
|
|
jump_to_me:;
|
|
|
|
|
|
|
|
jump_backwards:;
|
|
|
|
noop();
|
|
|
|
goto jump_backwards;
|
2018-10-02 17:38:26 +08:00
|
|
|
// CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control
|
|
|
|
// CHECK-NOTES: [[@LINE-4]]:1: note: label defined here
|
[clang-tidy] implement check for goto
The usage of `goto` is discourage in C++ since forever. This check implements
a warning for every `goto`. Even though there are (rare) valid use cases for
`goto`, better high level constructs should be used.
`goto` is used sometimes in C programs to free resources at the end of
functions in the case of errors. This pattern is better implemented with
RAII in C++.
Reviewers: aaron.ballman, alexfh, hokein
Reviewed By: aaron.ballman
Subscribers: lebedev.ri, jbcoe, Eugene.Zelenko, klimek, nemanjai, mgorny, xazax.hun, kbarton, cfe-commits
Differential Revision: https://reviews.llvm.org/D41815
llvm-svn: 322626
2018-01-17 18:27:41 +08:00
|
|
|
|
|
|
|
goto jump_in_line;
|
|
|
|
;
|
|
|
|
jump_in_line:;
|
2018-10-02 17:38:26 +08:00
|
|
|
// CHECK-NOTES: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control
|
|
|
|
// CHECK-NOTES: [[@LINE-2]]:1: note: label defined here
|
[clang-tidy] implement check for goto
The usage of `goto` is discourage in C++ since forever. This check implements
a warning for every `goto`. Even though there are (rare) valid use cases for
`goto`, better high level constructs should be used.
`goto` is used sometimes in C programs to free resources at the end of
functions in the case of errors. This pattern is better implemented with
RAII in C++.
Reviewers: aaron.ballman, alexfh, hokein
Reviewed By: aaron.ballman
Subscribers: lebedev.ri, jbcoe, Eugene.Zelenko, klimek, nemanjai, mgorny, xazax.hun, kbarton, cfe-commits
Differential Revision: https://reviews.llvm.org/D41815
llvm-svn: 322626
2018-01-17 18:27:41 +08:00
|
|
|
|
|
|
|
// 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;
|
2018-10-02 17:38:26 +08:00
|
|
|
// CHECK-NOTES: [[@LINE-1]]:9: warning: avoid using 'goto' for flow control
|
|
|
|
// CHECK-NOTES: [[@LINE-8]]:1: note: label defined here
|
[clang-tidy] implement check for goto
The usage of `goto` is discourage in C++ since forever. This check implements
a warning for every `goto`. Even though there are (rare) valid use cases for
`goto`, better high level constructs should be used.
`goto` is used sometimes in C programs to free resources at the end of
functions in the case of errors. This pattern is better implemented with
RAII in C++.
Reviewers: aaron.ballman, alexfh, hokein
Reviewed By: aaron.ballman
Subscribers: lebedev.ri, jbcoe, Eugene.Zelenko, klimek, nemanjai, mgorny, xazax.hun, kbarton, cfe-commits
Differential Revision: https://reviews.llvm.org/D41815
llvm-svn: 322626
2018-01-17 18:27:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|