1 // RUN: %clang_analyze_cc1 -triple=x86_64-unknown-linux-gnu -analyzer-checker=core,apiModeling,debug.ExprInspection -analyzer-config eagerly-assume=false -verify %s
2
3 void clang_analyzer_dump(int);
4 void clang_analyzer_dumpL(long);
5 void clang_analyzer_warnIfReached();
6
testInspect(int x)7 void testInspect(int x) {
8 if ((x < 10) || (x > 100)) {
9 return;
10 }
11 // x: [10, 100]
12
13 int i = x + 1;
14 long l = i - 10U;
15 clang_analyzer_dump(i); // expected-warning-re {{(reg_${{[0-9]+}}<int x>) + 1 }}
16 clang_analyzer_dumpL(l); // expected-warning-re {{(reg_${{[0-9]+}}<int x>) - 9U }} instead of + 4294967287U
17 clang_analyzer_dumpL(l + 0L); // expected-warning-re {{(reg_${{[0-9]+}}<int x>) - 9 }} instead of + 4294967287
18
19 if ((l - 1000) > 0) {
20 clang_analyzer_warnIfReached(); // no-warning
21 }
22 if (l > 1000) {
23 clang_analyzer_warnIfReached(); // no-warning
24 }
25 if (l > 1000L) {
26 clang_analyzer_warnIfReached(); // no-warning
27 }
28 if ((l + 0L) > 1000) {
29 clang_analyzer_warnIfReached(); // no-warning
30 }
31
32 i = x - 1;
33 l = i + 10U;
34 clang_analyzer_dumpL(l); // expected-warning-re {{(reg_${{[0-9]+}}<int x>) + 9U }} instead of - 4294967287U
35
36 i = x + (-1);
37 l = i - 10U;
38 clang_analyzer_dumpL(l); // expected-warning-re {{(reg_${{[0-9]+}}<int x>) - 11U }} instead of + 4294967285U
39
40 i = x + 1U;
41 l = i - 10U;
42 clang_analyzer_dumpL(l); // expected-warning-re {{(reg_${{[0-9]+}}<int x>) - 9U }} instead of + 4294967287U
43 }
44
45 const int intMin = 1 << (sizeof(int) * 8 - 1); // INT_MIN, negation value is not representable
46 const long longMin = 1L << (sizeof(long) * 8 - 1); // LONG_MIN, negation value is not representable
47
testMin(int i,long l)48 void testMin(int i, long l) {
49 clang_analyzer_dump(i + (-1)); // expected-warning-re {{(reg_${{[0-9]+}}<int i>) - 1 }} instead of + -1
50 clang_analyzer_dump(i - (-1)); // expected-warning-re {{(reg_${{[0-9]+}}<int i>) + 1 }} instead of - -1
51 clang_analyzer_dumpL(l + (-1)); // expected-warning-re {{(reg_${{[0-9]+}}<long l>) - 1 }} instead of + -1
52 clang_analyzer_dumpL(l - (-1)); // expected-warning-re {{(reg_${{[0-9]+}}<long l>) + 1 }} instead of - -1
53
54 // Do not normalize representation if negation would not be representable
55 clang_analyzer_dump(i + intMin); // expected-warning-re {{(reg_${{[0-9]+}}<int i>) + -2147483648 }} no change
56 clang_analyzer_dump(i - intMin); // expected-warning-re {{(reg_${{[0-9]+}}<int i>) - -2147483648 }} no change
57 // Produced value has higher bit with (long) so negation if representable
58 clang_analyzer_dumpL(l + intMin); // expected-warning-re {{(reg_${{[0-9]+}}<long l>) - 2147483648 }} instead of + -2147483648
59 clang_analyzer_dumpL(l - intMin); // expected-warning-re {{(reg_${{[0-9]+}}<long l>) + 2147483648 }} instead of - -2147483648
60 }
61
changingToUnsigned(unsigned u,int i)62 void changingToUnsigned(unsigned u, int i) {
63 unsigned c = u + (unsigned)i;
64 unsigned d = u - (unsigned)i;
65 if (i == -1) {
66 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned int u>) - 1U }}
67 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned int u>) + 1U }}
68 return;
69 }
70 if (i == intMin) {
71 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned int u>) - 2147483648U }}
72 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned int u>) + 2147483648U }}
73 return;
74 }
75 }
76
extendingToSigned(long l,int i)77 void extendingToSigned(long l, int i) {
78 long c = l + (long)i;
79 long d = l - (long)i;
80 if (i == -1) {
81 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<long l>) - 1 }}
82 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<long l>) + 1 }}
83 return;
84 }
85 if (i == intMin) {
86 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<long l>) - 2147483648 }}
87 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<long l>) + 2147483648 }}
88 return;
89 }
90 }
91
extendingToUnsigned(unsigned long ul,int i)92 void extendingToUnsigned(unsigned long ul, int i) {
93 unsigned long c = ul + (unsigned long)i;
94 unsigned long d = ul - (unsigned long)i;
95 if (i == -1) {
96 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned long ul>) - 1U }}
97 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned long ul>) + 1U }}
98 return;
99 }
100 if (i == intMin) {
101 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned long ul>) - 2147483648U }}
102 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned long ul>) + 2147483648U }}
103 return;
104 }
105 }
106
truncatingToSigned(int i,long l)107 void truncatingToSigned(int i, long l) {
108 int c = i + (int)l;
109 int d = i - (int)l;
110 if (l == -1L) {
111 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<int i>) - 1 }}
112 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<int i>) + 1 }}
113 return;
114 }
115 if (l == (long)intMin) { // negation outside of range, no-changes
116 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<int i>) + -2147483648 }}
117 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<int i>) + -2147483648 }}
118 return;
119 }
120 if (l == ((long)intMin - 1L)) { // outside or range, no changes
121 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<int i>) + 2147483647 }}
122 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<int i>) - 2147483647 }}
123 return;
124 }
125 if (l == longMin) { // outside of range, no changes
126 clang_analyzer_dump(c + 0); // expected-warning-re {{reg_${{[0-9]+}}<int i> }}
127 clang_analyzer_dump(d + 0); // expected-warning-re {{reg_${{[0-9]+}}<int i> }}
128 return;
129 }
130 }
131
truncatingToUnsigned(unsigned u,long l)132 void truncatingToUnsigned(unsigned u, long l) {
133 unsigned c = u + (unsigned)l;
134 unsigned d = u - (unsigned)l;
135 if (l == -1L) {
136 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned int u>) - 1U }}
137 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned int u>) + 1U }}
138 return;
139 }
140 if (l == (long)intMin) {
141 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned int u>) - 2147483648U }}
142 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned int u>) + 2147483648U }}
143 return;
144 }
145 if (l == ((long)intMin - 1L)) { // outside or range, no changes
146 clang_analyzer_dump(c + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned int u>) + 2147483647U }}
147 clang_analyzer_dump(d + 0); // expected-warning-re {{(reg_${{[0-9]+}}<unsigned int u>) - 2147483647U }}
148 return;
149 }
150 if (l == longMin) { // outside of range, no changes
151 clang_analyzer_dump(c + 0); // expected-warning-re {{reg_${{[0-9]+}}<unsigned int u> }}
152 clang_analyzer_dump(d + 0); // expected-warning-re {{reg_${{[0-9]+}}<unsigned int u> }}
153 return;
154 }
155 }
156
157 // Test for crashes
158 typedef long ssize_t;
159 ssize_t write(int, const void *, unsigned long);
160
crashTest(int x,int fd)161 int crashTest(int x, int fd) {
162 unsigned wres = write(fd, "a", 1);
163 if (wres) {
164 }
165 int t1 = x - wres;
166 if (wres < 0) {
167 }
168 return x + t1; // no crash
169 }
170