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