brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · 324dd38 Raw
302 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -Wloop-analysis -verify -std=c++17 %s2 3struct S {4  bool stop() { return false; }5  bool keep_running;6};7 8void by_ref(int &value) { }9void by_value(int value) { }10void by_pointer(int *value) {}11 12void test1() {13  S s;14  for (; !s.stop();) {}15  for (; s.keep_running;) {}16  for (int i; i < 1; ++i) {}17  for (int i; i < 1; ) {}  // expected-warning {{variable 'i' used in loop condition not modified in loop body}}18  for (int i; i < 1; ) { ++i; }19  for (int i; i < 1; ) { return; }20  for (int i; i < 1; ) { break; }21  for (int i; i < 1; ) { goto exit_loop; }22exit_loop:23  for (int i; i < 1; ) { by_ref(i); }24  for (int i; i < 1; ) { by_value(i); }  // expected-warning {{variable 'i' used in loop condition not modified in loop body}}25  for (int i; i < 1; ) { by_pointer(&i); }26 27  for (int i; i < 1; ++i)28    for (int j; j < 1; ++j)29      { }30  for (int i; i < 1; ++i)31    for (int j; j < 1; ++i)  // expected-warning {{variable 'j' used in loop condition not modified in loop body}}32      { }33  for (int i; i < 1; ++i)34    for (int j; i < 1; ++j)  // expected-warning {{variable 'i' used in loop condition not modified in loop body}}35      { }36 37  for (int *i, *j; i < j; ++i) {}38  for (int *i, *j; i < j;) {}  // expected-warning {{variables 'i' and 'j' used in loop condition not modified in loop body}}39 40  // Dereferencing pointers is ignored for now.41  for (int *i; *i; ) {}42}43 44void test2() {45  int i, j, k;46  int *ptr;47 48  // Testing CastExpr49  for (; i; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}50  for (; i; ) { i = 5; }51 52  // Testing BinaryOperator53  for (; i < j; ) {} // expected-warning {{variables 'i' and 'j' used in loop condition not modified in loop body}}54  for (; i < j; ) { i = 5; }55  for (; i < j; ) { j = 5; }56 57  // Testing IntegerLiteral58  for (; i < 5; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}59  for (; i < 5; ) { i = 5; }60 61  // Testing FloatingLiteral62  for (; i < 5.0; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}63  for (; i < 5.0; ) { i = 5; }64 65  // Testing CharacterLiteral66  for (; i == 'a'; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}67  for (; i == 'a'; ) { i = 5; }68 69  // Testing CXXBoolLiteralExpr70  for (; i == true; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}71  for (; i == true; ) { i = 5; }72 73  // Testing GNUNullExpr74  for (; ptr == __null; ) {} // expected-warning {{variable 'ptr' used in loop condition not modified in loop body}}75  for (; ptr == __null; ) { ptr = &i; }76 77  // Testing UnaryOperator78  for (; -i > 5; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}79  for (; -i > 5; ) { ++i; }80 81  // Testing ImaginaryLiteral82  for (; i != 3i; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}83  for (; i != 3i; ) { ++i; }84 85  // Testing ConditionalOperator86  for (; i ? j : k; ) {} // expected-warning {{variables 'i', 'j', and 'k' used in loop condition not modified in loop body}}87  for (; i ? j : k; ) { ++i; }88  for (; i ? j : k; ) { ++j; }89  for (; i ? j : k; ) { ++k; }90  for (; i; ) { j = i ? i : i; }  // expected-warning {{variable 'i' used in loop condition not modified in loop body}}91  for (; i; ) { j = (i = 1) ? i : i; }92  for (; i; ) { j = i ? i : ++i; }93 94  // Testing BinaryConditionalOperator95  for (; i ?: j; ) {} // expected-warning {{variables 'i' and 'j' used in loop condition not modified in loop body}}96  for (; i ?: j; ) { ++i; }97  for (; i ?: j; ) { ++j; }98  for (; i; ) { j = i ?: i; }  // expected-warning {{variable 'i' used in loop condition not modified in loop body}}99 100  // Testing ParenExpr101  for (; (i); ) { }  // expected-warning {{variable 'i' used in loop condition not modified in loop body}}102  for (; (i); ) { ++i; }103 104  // Testing non-evaluated variables105  for (; i < sizeof(j); ) { }  // expected-warning {{variable 'i' used in loop condition not modified in loop body}}106  for (; i < sizeof(j); ) { ++j; }  // expected-warning {{variable 'i' used in loop condition not modified in loop body}}107  for (; i < sizeof(j); ) { ++i; }108}109 110// False positive and how to silence.111void test3() {112  int x;113  int *ptr = &x;114  for (;x<5;) { *ptr = 6; }  // expected-warning {{variable 'x' used in loop condition not modified in loop body}}115 116  for (;x<5;) {117    *ptr = 6;118    (void)x;119  }120}121 122// Check ordering and printing of variables.  Max variables is currently 4.123void test4() {124  int a, b, c, d, e, f;125  for (; a;);  // expected-warning {{variable 'a' used in loop condition not modified in loop body}}126  for (; a + b;);  // expected-warning {{variables 'a' and 'b' used in loop condition not modified in loop body}}127  for (; a + b + c;);  // expected-warning {{variables 'a', 'b', and 'c' used in loop condition not modified in loop body}}128  for (; a + b + c + d;);  // expected-warning {{variables 'a', 'b', 'c', and 'd' used in loop condition not modified in loop body}}129  for (; a + b + c + d + e;);  // expected-warning {{variables used in loop condition not modified in loop body}}130  for (; a + b + c + d + e + f;);  // expected-warning {{variables used in loop condition not modified in loop body}}131  for (; a + c + d + b;);  // expected-warning {{variables 'a', 'c', 'd', and 'b' used in loop condition not modified in loop body}}132  for (; d + c + b + a;);  // expected-warning {{variables 'd', 'c', 'b', and 'a' used in loop condition not modified in loop body}}133}134 135// Ensure that the warning doesn't fail when lots of variables are used136// in the conditional.137void test5() {138  for (int a; a+a+a+a+a+a+a+a+a+a;); // \139   // expected-warning {{variable 'a' used in loop condition not modified in loop body}}140  for (int a; a+a+a+a+a+a+a+a+a+a+a;); // \141   // expected-warning {{variable 'a' used in loop condition not modified in loop body}}142  for (int a; a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a;);  // \143   // expected-warning {{variable 'a' used in loop condition not modified in loop body}}144  for (int a; a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a;);//\145   // expected-warning {{variable 'a' used in loop condition not modified in loop body}}146}147 148// Ignore global variables and static variables.149int x6;150void test6() {151  static int y;152  for (;x6;);153  for (;y;);154}155 156void test7() {157  int i;158  for (;;i++) {  // expected-note{{incremented here}}159    if (true) test7();160    i++;  // expected-warning{{incremented both}}161  }162  for (;;i++) {  // expected-note{{incremented here}}163    if (true) break;164    ++i;  // expected-warning{{incremented both}}165  }166  for (;;++i) {  // expected-note{{incremented here}}167    while (true) return;168    i++;  // expected-warning{{incremented both}}169  }170  for (;;++i) {  // expected-note{{incremented here}}171    ++i;  // expected-warning{{incremented both}}172  }173 174  for (;;i--) {  // expected-note{{decremented here}}175    if (true) test7();176    i--;  // expected-warning{{decremented both}}177  }178  for (;;i--) {  // expected-note{{decremented here}}179    if (true) break;180    --i;  // expected-warning{{decremented both}}181  }182  for (;;--i) {  // expected-note{{decremented here}}183    while (true) return;184    i--;  // expected-warning{{decremented both}}185  }186  for (;;--i) {  // expected-note{{decremented here}}187    --i;  // expected-warning{{decremented both}}188  }189 190  // Don't warn when loop is only one statement.191  for (;;++i)192    i++;193  for (;;--i)194    --i;195 196  // Don't warn when loop has continue statement.197  for (;;i++) {198    if (true) continue;199    i++;200  }201  for (;;i--) {202    if (true) continue;203    i--;204  }205 206  // But do warn if the continue is in a nested loop.207  for (;;i--) { // expected-note{{decremented here}}208    for (int j = 0; j < 10; ++j) continue;209    i--; // expected-warning{{decremented both}}210  }211}212 213struct iterator {214  iterator operator++() { return *this; }215  iterator operator++(int) { return *this; }216  iterator operator--() { return *this; }217  iterator operator--(int) { return *this; }218};219void test8() {220  iterator i;221  for (;;i++) {  // expected-note{{incremented here}}222    if (true) test7();223    i++;  // expected-warning{{incremented both}}224  }225  for (;;i++) {  // expected-note{{incremented here}}226    if (true) break;227    ++i;  // expected-warning{{incremented both}}228  }229  for (;;++i) {  // expected-note{{incremented here}}230    while (true) return;231    i++;  // expected-warning{{incremented both}}232  }233  for (;;++i) {  // expected-note{{incremented here}}234    ++i;  // expected-warning{{incremented both}}235  }236 237  for (;;i--) {  // expected-note{{decremented here}}238    if (true) test7();239    i--;  // expected-warning{{decremented both}}240  }241  for (;;i--) {  // expected-note{{decremented here}}242    if (true) break;243    --i;  // expected-warning{{decremented both}}244  }245  for (;;--i) {  // expected-note{{decremented here}}246    while (true) return;247    i--;  // expected-warning{{decremented both}}248  }249  for (;;--i) {  // expected-note{{decremented here}}250    --i;  // expected-warning{{decremented both}}251  }252 253  // Don't warn when loop is only one statement.254  for (;;++i)255    i++;256  for (;;--i)257    --i;258 259  // Don't warn when loop has continue statement.260  for (;;i++) {261    if (true) continue;262    i++;263  }264  for (;;i--) {265    if (true) continue;266    i--;267  }268 269  // But do warn if the continue is in a nested loop.270  for (;;i--) { // expected-note{{decremented here}}271    for (int j = 0; j < 10; ++j) continue;272    i--; // expected-warning{{decremented both}}273  }274}275 276int f(int);277void test9() {278  // Don't warn when variable is defined by the loop condition.279  for (int i = 0; int x = f(i); ++i) {}280}281 282// Don't warn when decomposition variables are in the loop condition.283// TODO: BindingDecl's which make a copy should warn.284void test10() {285  int arr[] = {1, 2, 3};286  for (auto[i, j, k] = arr;;) { }287  for (auto[i, j, k] = arr; i < j; ++i, ++j) { }288 289  for (auto[i, j, k] = arr; i;) { }290  for (auto[i, j, k] = arr; i < j;) { }291  for (auto[i, j, k] = arr; i < j; ++arr[0]) { }292 293  int a = 1, b = 2;294  for (auto[i, j, k] = arr; a < b;) { }  // expected-warning{{variables 'a' and 'b' used in loop condition not modified in loop body}}295  for (auto[i, j, k] = arr; a < b; ++a) { }296 297  for (auto [i, j, k] = arr; i < a;) { }298  for (auto[i, j, k] = arr; i < a; ++a) { }299  for (auto[i, j, k] = arr; i < a; ++i) { }300  for (auto[i, j, k] = arr; i < a; ++arr[0]) { }301};302