Richard Trieu | 694e796 | 2012-04-30 18:01:30 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -Wloop-analysis -verify %s |
| 2 | |
| 3 | struct S { |
| 4 | bool stop() { return false; } |
| 5 | bool keep_running; |
| 6 | }; |
| 7 | |
| 8 | void by_ref(int &value) { } |
| 9 | void by_value(int value) { } |
| 10 | void by_pointer(int *value) {} |
| 11 | |
| 12 | void 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; } |
| 22 | exit_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 | |
| 44 | void test2() { |
| 45 | int i, j, k; |
| 46 | int *ptr; |
| 47 | |
| 48 | // Testing CastExpr |
| 49 | for (; i; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}} |
| 50 | for (; i; ) { i = 5; } |
| 51 | |
| 52 | // Testing BinaryOperator |
| 53 | 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 IntegerLiteral |
| 58 | 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 FloatingLiteral |
| 62 | 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 CharacterLiteral |
| 66 | 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 CXXBoolLiteralExpr |
| 70 | 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 GNUNullExpr |
| 74 | 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 UnaryOperator |
| 78 | for (; -i > 5; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}} |
| 79 | for (; -i > 5; ) { ++i; } |
| 80 | |
| 81 | // Testing ImaginaryLiteral |
| 82 | for (; i != 3i; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}} |
| 83 | for (; i != 3i; ) { ++i; } |
| 84 | |
| 85 | // Testing ConditionalOperator |
Richard Trieu | 82129e2 | 2012-05-02 22:48:45 +0000 | [diff] [blame] | 86 | for (; i ? j : k; ) {} // expected-warning {{variables 'i', 'j', and 'k' used in loop condition not modified in loop body}} |
Richard Trieu | 694e796 | 2012-04-30 18:01:30 +0000 | [diff] [blame] | 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 BinaryConditionalOperator |
| 95 | 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 ParenExpr |
| 101 | for (; (i); ) { } // expected-warning {{variable 'i' used in loop condition not modified in loop body}} |
| 102 | for (; (i); ) { ++i; } |
| 103 | |
| 104 | // Testing non-evaluated variables |
| 105 | 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. |
| 111 | void 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. |
| 123 | void 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}} |
Richard Trieu | 82129e2 | 2012-05-02 22:48:45 +0000 | [diff] [blame] | 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}} |
Richard Trieu | 694e796 | 2012-04-30 18:01:30 +0000 | [diff] [blame] | 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}} |
Richard Trieu | 82129e2 | 2012-05-02 22:48:45 +0000 | [diff] [blame] | 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}} |
Richard Trieu | 694e796 | 2012-04-30 18:01:30 +0000 | [diff] [blame] | 133 | } |
| 134 | |
| 135 | // Ensure that the warning doesn't fail when lots of variables are used |
| 136 | // in the conditional. |
| 137 | void 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 | } |
Richard Trieu | 9087599 | 2012-05-04 03:01:54 +0000 | [diff] [blame] | 147 | |
| 148 | // Ignore global variables and static variables. |
| 149 | int x6; |
| 150 | void test6() { |
| 151 | static int y; |
| 152 | for (;x6;); |
| 153 | for (;y;); |
| 154 | } |