blob: 7eb55ab1e1253fe94037e7a995d59182f5589ee8 [file] [log] [blame]
Jordy Rose43d9f0d2012-05-16 16:01:10 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range %s
Jordy Roseba0f61c2010-06-18 22:49:11 +00002
Jordy Rose43d9f0d2012-05-16 16:01:10 +00003void clang_analyzer_eval(int);
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)
8
Jordy Roseba0f61c2010-06-18 22:49:11 +00009
10// Each of these adjusted ranges has an adjustment small enough to split the
11// solution range across an overflow boundary (Min for <, Max for >).
12// This corresponds to one set of branches in RangeConstraintManager.
13void smallAdjustmentGT (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000014 if (a+2 > 1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000015 clang_analyzer_eval(a < UINT_MAX-1); // expected-warning{{TRUE}}
16 else
17 clang_analyzer_eval(a == UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000018}
19
20void smallAdjustmentGE (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000021 if (a+2 >= 1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000022 clang_analyzer_eval(a < UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
23 else
24 clang_analyzer_eval(a == UINT_MAX-1); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000025}
26
27void smallAdjustmentLT (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000028 if (a+1 < 2)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000029 clang_analyzer_eval(a == 0 || a == UINT_MAX); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000030}
31
32void smallAdjustmentLE (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000033 if (a+1 <= 2)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000034 clang_analyzer_eval(a == 0 || a == 1 || a == UINT_MAX); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000035}
36
37
38// Each of these adjusted ranges has an adjustment large enough to push the
39// comparison value over an overflow boundary (Min for <, Max for >).
40// This corresponds to one set of branches in RangeConstraintManager.
41void largeAdjustmentGT (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000042 if (a-2 > UINT_MAX-1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000043 clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
44 else
45 clang_analyzer_eval(a != 1); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000046}
47
48void largeAdjustmentGE (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000049 if (a-2 >= UINT_MAX-1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000050 clang_analyzer_eval(a == 1 || a == 0); // expected-warning{{TRUE}}
51 else
52 clang_analyzer_eval(a > 1); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000053}
54
55void largeAdjustmentLT (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000056 if (a+2 < 1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000057 clang_analyzer_eval(a == UINT_MAX-1); // expected-warning{{TRUE}}
58 else
59 clang_analyzer_eval(a != UINT_MAX-1); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000060}
61
62void largeAdjustmentLE (unsigned a) {
Jordy Roseba0f61c2010-06-18 22:49:11 +000063 if (a+2 <= 1)
Jordy Rose43d9f0d2012-05-16 16:01:10 +000064 clang_analyzer_eval(a == UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
65 else
66 clang_analyzer_eval(a < UINT_MAX-1); // expected-warning{{TRUE}}
Jordy Roseba0f61c2010-06-18 22:49:11 +000067}
Jordy Rose1d8db492012-05-08 03:27:16 +000068
69
70// Test the nine cases in RangeConstraintManager's pinning logic.
Jordy Rose43d9f0d2012-05-16 16:01:10 +000071// For out-of-range tautologies, it may be the negation that actually
72// triggers the case in question.
Jordy Rose1d8db492012-05-08 03:27:16 +000073void mixedComparisons1(signed char a) {
74 // Case 1: The range is entirely below the symbol's range.
75 int min = INT_MIN;
76
Jordy Rose43d9f0d2012-05-16 16:01:10 +000077 clang_analyzer_eval((a - 2) >= (min + 5LL)); // expected-warning{{TRUE}}
Jordy Rose1d8db492012-05-08 03:27:16 +000078
Jordy Rose43d9f0d2012-05-16 16:01:10 +000079 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
80 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
81 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +000082}
83
84void mixedComparisons2(signed char a) {
85 // Case 2: Only the lower end of the range is outside.
Jordy Rose43d9f0d2012-05-16 16:01:10 +000086 clang_analyzer_eval((a - 5) < (-0x81LL)); // expected-warning{{UNKNOWN}}
87
Jordy Rose1d8db492012-05-08 03:27:16 +000088 if ((a - 5) < (-0x81LL)) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +000089 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
90 clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
91 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +000092 }
93}
94
95void mixedComparisons3(signed char a) {
96 // Case 3: The entire symbol range is covered.
Jordy Rose43d9f0d2012-05-16 16:01:10 +000097 clang_analyzer_eval((a - 0x200) < -0x100LL); // expected-warning{{TRUE}}
98
99 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
100 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
101 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000102}
103
104void mixedComparisons4(signed char a) {
105 // Case 4: The range wraps around, but the lower wrap is out-of-range.
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000106 clang_analyzer_eval((a - 5) > 0LL); // expected-warning{{UNKNOWN}}
107
Jordy Rose1d8db492012-05-08 03:27:16 +0000108 if ((a - 5) > 0LL) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000109 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
110 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
111 clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000112 }
113}
114
115void mixedComparisons5(signed char a) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000116 // Case 5: The range is inside and may or may not wrap.
117 clang_analyzer_eval((a + 5) == 0LL); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000118
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000119 if ((a + 5) == 0LL) {
120 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
121 clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
122 clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000123 } else {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000124 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
125 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
126 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000127 }
128}
129
130void mixedComparisons6(signed char a) {
131 // Case 6: Only the upper end of the range is outside.
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000132 clang_analyzer_eval((a + 5) > 0x81LL); // expected-warning{{UNKNOWN}}
133
Jordy Rose1d8db492012-05-08 03:27:16 +0000134 if ((a + 5) > 0x81LL) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000135 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
136 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
137 clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000138 }
139}
140
141void mixedComparisons7(signed char a) {
142 // Case 7: The range wraps around but is entirely outside the symbol's range.
143 int min = INT_MIN;
144
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000145 clang_analyzer_eval((a + 2) >= (min + 5LL)); // expected-warning{{TRUE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000146
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000147 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
148 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
149 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000150}
151
152void mixedComparisons8(signed char a) {
153 // Case 8: The range wraps, but the upper wrap is out of range.
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000154 clang_analyzer_eval((a + 5) < 0LL); // expected-warning{{UNKNOWN}}
155
Jordy Rose1d8db492012-05-08 03:27:16 +0000156 if ((a + 5) < 0LL) {
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000157 clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
158 clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
159 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000160 }
161}
162
163void mixedComparisons9(signed char a) {
164 // Case 9: The range is entirely above the symbol's range.
165 int max = INT_MAX;
166
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000167 clang_analyzer_eval((a + 2) <= (max - 5LL)); // expected-warning{{TRUE}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000168
Jordy Rose43d9f0d2012-05-16 16:01:10 +0000169 clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
170 clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
171 clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
Jordy Rose1d8db492012-05-08 03:27:16 +0000172}