blob: 0b9bf7080873a00bb22160767dfaeb292652da30 [file] [log] [blame]
Sean Eveson70eece22015-10-30 15:23:57 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s
2
3void clang_analyzer_eval(int);
4void clang_analyzer_warnIfReached();
5
6typedef __typeof(sizeof(int)) size_t;
7void *malloc(size_t);
8void free(void *);
9
10void loop_which_iterates_limit_times_not_widened() {
11 int i;
12 int x = 1;
13 // Check loop isn't widened by checking x isn't invalidated
14 for (i = 0; i < 1; ++i) {}
15 clang_analyzer_eval(x == 1); // expected-warning {{TRUE}}
16 for (i = 0; i < 2; ++i) {}
17 clang_analyzer_eval(x == 1); // expected-warning {{TRUE}}
18 for (i = 0; i < 3; ++i) {}
19 // FIXME loss of precision as a result of evaluating the widened loop body
20 // *instead* of the last iteration.
21 clang_analyzer_eval(x == 1); // expected-warning {{UNKNOWN}}
22}
23
24int a_global;
25
26void loop_evaluated_before_widening() {
27 int i;
28 a_global = 1;
29 for (i = 0; i < 10; ++i) {
30 if (i == 2) {
31 // True before widening then unknown after.
32 clang_analyzer_eval(a_global == 1); // expected-warning{{TRUE}} expected-warning{{UNKNOWN}}
33 }
34 }
35 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
36}
37
38void warnings_after_loop() {
39 int i;
40 for (i = 0; i < 10; ++i) {}
41 char *m = (char*)malloc(12);
42} // expected-warning {{Potential leak of memory pointed to by 'm'}}
43
44void for_loop_exits() {
45 int i;
46 for (i = 0; i < 10; ++i) {}
47 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
48}
49
50void while_loop_exits() {
51 int i = 0;
52 while (i < 10) {++i;}
53 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
54}
55
56void do_while_loop_exits() {
57 int i = 0;
58 do {++i;} while (i < 10);
59 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
60}
61
62void loop_body_is_widened() {
63 int i = 0;
64 while (i < 100) {
65 if (i > 10) {
66 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
67 }
68 ++i;
69 }
70 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
71}
72
73void invariably_infinite_loop() {
74 int i = 0;
75 while (1) { ++i; }
76 clang_analyzer_warnIfReached(); // no-warning
77}
78
79void invariably_infinite_break_loop() {
80 int i = 0;
81 while (1) {
82 ++i;
83 int x = 1;
84 if (!x) break;
85 }
86 clang_analyzer_warnIfReached(); // no-warning
87}
88
89void reachable_break_loop() {
90 int i = 0;
91 while (1) {
92 ++i;
93 if (i == 100) break;
94 }
95 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
96}
97
98void condition_constrained_true_in_loop() {
99 int i = 0;
100 while (i < 50) {
101 clang_analyzer_eval(i < 50); // expected-warning {{TRUE}}
102 ++i;
103 }
104 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
105}
106
107void condition_constrained_false_after_loop() {
108 int i = 0;
109 while (i < 50) {
110 ++i;
111 }
112 clang_analyzer_eval(i >= 50); // expected-warning {{TRUE}}
113 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
114}
115
116void multiple_exit_test() {
117 int x = 0;
118 int i = 0;
119 while (i < 50) {
120 if (x) {
121 i = 10;
122 break;
123 }
124 ++i;
125 }
126 // Reachable by 'normal' exit
127 if (i == 50) clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
128 // Reachable by break point
129 if (i == 10) clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
130 // Not reachable
131 if (i < 10) clang_analyzer_warnIfReached(); // no-warning
132 if (i > 10 && i < 50) clang_analyzer_warnIfReached(); // no-warning
133}
134
135void pointer_doesnt_leak_from_loop() {
136 int *h_ptr = (int *) malloc(sizeof(int));
137 for (int i = 0; i < 2; ++i) {}
138 for (int i = 0; i < 10; ++i) {} // no-warning
139 free(h_ptr);
140}
141
142int g_global;
143
144void unknown_after_loop(int s_arg) {
145 g_global = 0;
146 s_arg = 1;
147 int s_local = 2;
148 int *h_ptr = malloc(sizeof(int));
149
150 for (int i = 0; i < 10; ++i) {}
151
152 clang_analyzer_eval(g_global); // expected-warning {{UNKNOWN}}
153 clang_analyzer_eval(s_arg); // expected-warning {{UNKNOWN}}
154 clang_analyzer_eval(s_local); // expected-warning {{UNKNOWN}}
155 clang_analyzer_eval(h_ptr == 0); // expected-warning {{UNKNOWN}}
156 free(h_ptr);
157}
158
159void variable_bound_exiting_loops_widened(int x) {
160 int i = 0;
161 int t = 1;
162 while (i < x) {
163 ++i;
164 }
165 clang_analyzer_eval(t == 1); // expected-warning {{TRUE}} // expected-warning {{UNKNOWN}}
166}
167
168void nested_loop_outer_widen() {
169 int i = 0, j = 0;
170 for (i = 0; i < 10; i++) {
171 clang_analyzer_eval(i < 10); // expected-warning {{TRUE}}
172 for (j = 0; j < 2; j++) {
173 clang_analyzer_eval(j < 2); // expected-warning {{TRUE}}
174 }
175 clang_analyzer_eval(j >= 2); // expected-warning {{TRUE}}
176 }
177 clang_analyzer_eval(i >= 10); // expected-warning {{TRUE}}
178}
179
180void nested_loop_inner_widen() {
181 int i = 0, j = 0;
182 for (i = 0; i < 2; i++) {
183 clang_analyzer_eval(i < 2); // expected-warning {{TRUE}}
184 for (j = 0; j < 10; j++) {
185 clang_analyzer_eval(j < 10); // expected-warning {{TRUE}}
186 }
187 clang_analyzer_eval(j >= 10); // expected-warning {{TRUE}}
188 }
189 clang_analyzer_eval(i >= 2); // expected-warning {{TRUE}}
190}