blob: 33f3b9b251772e76c946e2048f3ca0be22d335d6 [file] [log] [blame]
Richard Trieu526e6272012-11-14 22:50:24 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range -Wno-tautological-compare %s
Jordy Roseba0f61c2010-06-18 22:49:11 +00002
Jordy Rose43d9f0d2012-05-16 16:01:10 +00003void clang_analyzer_eval(bool);
4
Jordy Rose9e607dd2012-05-03 07:33:56 +00005#define UINT_MAX (~0U)
Jordy Rose1d8db492012-05-08 03:27:16 +00006#define INT_MAX (UINT_MAX & (UINT_MAX >> 1))
7#define INT_MIN (-INT_MAX - 1)
Jordy Roseba0f61c2010-06-18 22:49:11 +00008
9//---------------
10// Plus/minus
11//---------------
12
13void separateExpressions (int a) {
14 int b = a + 1;
15 --b;
16
Jordy Rose43d9f0d2012-05-16 16:01:10 +000017 clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000018}
19
20void oneLongExpression (int a) {
21 // Expression canonicalization should still allow this to work, even though
22 // the first term is on the left.
23 int b = 15 + a + 15 - 10 - 20;
24
Jordy Rose43d9f0d2012-05-16 16:01:10 +000025 clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000026}
27
Jordy Roseb4954a42010-06-21 20:15:15 +000028void mixedTypes (int a) {
Jordy Roseb4954a42010-06-21 20:15:15 +000029 // Different additive types should not cause crashes when constant-folding.
30 // This is part of PR7406.
31 int b = a + 1LL;
Jordy Rose43d9f0d2012-05-16 16:01:10 +000032 clang_analyzer_eval(a != 0 && (b-1) == 0); // not crash, expected-warning{{FALSE}}
Jordy Roseb4954a42010-06-21 20:15:15 +000033
34 int c = a + 1U;
Jordy Rose43d9f0d2012-05-16 16:01:10 +000035 clang_analyzer_eval(a != 0 && (c-1) == 0); // not crash, expected-warning{{FALSE}}
Jordy Roseb4954a42010-06-21 20:15:15 +000036}
37
Jordy Roseba0f61c2010-06-18 22:49:11 +000038//---------------
39// Comparisons
40//---------------
41
42// Equality and inequality only
43void eq_ne (unsigned a) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +000044 if (a == UINT_MAX) {
45 clang_analyzer_eval(a+1 == 0); // expected-warning{{TRUE}}
46 clang_analyzer_eval(a-1 == UINT_MAX-1); // expected-warning{{TRUE}}
47 } else {
48 clang_analyzer_eval(a+1 != 0); // expected-warning{{TRUE}}
49 clang_analyzer_eval(a-1 != UINT_MAX-1); // expected-warning{{TRUE}}
50 }
Jordy Roseba0f61c2010-06-18 22:49:11 +000051}
52
Jordy Roseb4954a42010-06-21 20:15:15 +000053// Mixed typed inequalities (part of PR7406)
54// These should not crash.
55void mixed_eq_ne (int a) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +000056 if (a == 1) {
57 clang_analyzer_eval(a+1U == 2); // expected-warning{{TRUE}}
58 clang_analyzer_eval(a-1U == 0); // expected-warning{{TRUE}}
59 } else {
60 clang_analyzer_eval(a+1U != 2); // expected-warning{{TRUE}}
61 clang_analyzer_eval(a-1U != 0); // expected-warning{{TRUE}}
62 }
Jordy Roseb4954a42010-06-21 20:15:15 +000063}
64
Jordy Roseba0f61c2010-06-18 22:49:11 +000065
66// Simple order comparisons with no adjustment
67void baselineGT (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000068 if (a > 0)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000069 clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}
70 else
71 clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000072}
73
74void baselineGE (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000075 if (a >= UINT_MAX)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000076 clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
77 else
78 clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000079}
80
81void baselineLT (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000082 if (a < UINT_MAX)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000083 clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}
84 else
85 clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000086}
87
88void baselineLE (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000089 if (a <= 0)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000090 clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}
91 else
92 clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000093}
94
95
96// Adjustment gives each of these an extra solution!
97void adjustedGT (unsigned a) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +000098 clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000099}
100
101void adjustedGE (unsigned a) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000102 clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}
103
Jordy Roseba0f61c2010-06-18 22:49:11 +0000104 if (a-1 >= UINT_MAX-1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000105 clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}}
Jordy Roseba0f61c2010-06-18 22:49:11 +0000106}
107
108void adjustedLT (unsigned a) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000109 clang_analyzer_eval(a+1 < 1); // expected-warning{{UNKNOWN}}
Jordy Roseba0f61c2010-06-18 22:49:11 +0000110}
111
112void adjustedLE (unsigned a) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000113 clang_analyzer_eval(a+1 <= 1); // expected-warning{{UNKNOWN}}
114
Jordy Roseba0f61c2010-06-18 22:49:11 +0000115 if (a+1 <= 1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000116 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
Jordy Roseba0f61c2010-06-18 22:49:11 +0000117}
118
119
120// Tautologies
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000121// The negative forms are exercised as well
122// because clang_analyzer_eval tests both possibilities.
123void tautologies(unsigned a) {
124 clang_analyzer_eval(a <= UINT_MAX); // expected-warning{{TRUE}}
125 clang_analyzer_eval(a >= 0); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +0000126}
Jordy Rose14d20b12012-05-03 07:34:01 +0000127
128
Jordy Rose1d8db492012-05-08 03:27:16 +0000129// Tautologies from outside the range of the symbol
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000130void tautologiesOutside(unsigned char a) {
Richard Trieu526e6272012-11-14 22:50:24 +0000131 clang_analyzer_eval(a <= 0x100); // expected-warning{{TRUE}}
132 clang_analyzer_eval(a < 0x100); // expected-warning{{TRUE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000133
Richard Trieu526e6272012-11-14 22:50:24 +0000134 clang_analyzer_eval(a != 0x100); // expected-warning{{TRUE}}
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000135 clang_analyzer_eval(a != -1); // expected-warning{{TRUE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000136
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000137 clang_analyzer_eval(a > -1); // expected-warning{{TRUE}}
138 clang_analyzer_eval(a >= -1); // expected-warning{{TRUE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000139}
140
141
142// Wraparound with mixed types. Note that the analyzer assumes
143// -fwrapv semantics.
144void mixedWraparoundSanityCheck(int a) {
145 int max = INT_MAX;
146 int min = INT_MIN;
147
148 int b = a + 1;
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000149 clang_analyzer_eval(a == max && b != min); // expected-warning{{FALSE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000150}
151
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000152void mixedWraparoundLE_GT(int a) {
Jordy Rose1d8db492012-05-08 03:27:16 +0000153 int max = INT_MAX;
154 int min = INT_MIN;
155
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000156 clang_analyzer_eval((a + 2) <= (max + 1LL)); // expected-warning{{TRUE}}
157 clang_analyzer_eval((a - 2) > (min - 1LL)); // expected-warning{{TRUE}}
158 clang_analyzer_eval((a + 2LL) <= max); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000159}
160
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000161void mixedWraparoundGE_LT(int a) {
Jordy Rose1d8db492012-05-08 03:27:16 +0000162 int max = INT_MAX;
163 int min = INT_MIN;
164
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000165 clang_analyzer_eval((a + 2) < (max + 1LL)); // expected-warning{{TRUE}}
166 clang_analyzer_eval((a - 2) >= (min - 1LL)); // expected-warning{{TRUE}}
167 clang_analyzer_eval((a - 2LL) >= min); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000168}
169
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000170void mixedWraparoundEQ_NE(int a) {
Jordy Rose1d8db492012-05-08 03:27:16 +0000171 int max = INT_MAX;
172
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000173 clang_analyzer_eval((a + 2) != (max + 1LL)); // expected-warning{{TRUE}}
174 clang_analyzer_eval((a + 2LL) == (max + 1LL)); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000175}
176
177
178// Mixed-signedness comparisons.
179void mixedSignedness(int a, unsigned b) {
180 int sMin = INT_MIN;
181 unsigned uMin = INT_MIN;
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000182
183 clang_analyzer_eval(a == sMin && a != uMin); // expected-warning{{FALSE}}
184 clang_analyzer_eval(b == uMin && b != sMin); // expected-warning{{FALSE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000185}
186
187
Jordy Rose1d8db492012-05-08 03:27:16 +0000188void multiplicativeSanityTest(int x) {
189 // At one point we were ignoring the *4 completely -- the constraint manager
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000190 // would see x < 8 and then declare the assertion to be known false.
Jordy Rose1d8db492012-05-08 03:27:16 +0000191 if (x*4 < 8)
192 return;
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000193
194 clang_analyzer_eval(x == 3); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000195}