1 // RUN: %clang_analyze_cc1 %s \
2 // RUN: -Wno-conversion -Wno-tautological-constant-compare \
3 // RUN: -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions,alpha.core.Conversion \
4 // RUN: -verify
5
6 unsigned char U8;
7 signed char S8;
8
assign(unsigned U,signed S)9 void assign(unsigned U, signed S) {
10 if (S < -10)
11 U8 = S; // expected-warning {{Loss of sign in implicit conversion}}
12 if (U > 300)
13 S8 = U; // expected-warning {{Loss of precision in implicit conversion}}
14 if (S > 10)
15 U8 = S; // no-warning
16 if (U < 200)
17 S8 = U; // no-warning
18 }
19
addAssign(void)20 void addAssign(void) {
21 unsigned long L = 1000;
22 int I = -100;
23 U8 += L; // expected-warning {{Loss of precision in implicit conversion}}
24 L += I; // no-warning
25 }
26
subAssign(void)27 void subAssign(void) {
28 unsigned long L = 1000;
29 int I = -100;
30 U8 -= L; // expected-warning {{Loss of precision in implicit conversion}}
31 L -= I; // no-warning
32 }
33
mulAssign(void)34 void mulAssign(void) {
35 unsigned long L = 1000;
36 int I = -1;
37 U8 *= L; // expected-warning {{Loss of precision in implicit conversion}}
38 L *= I; // expected-warning {{Loss of sign in implicit conversion}}
39 I = 10;
40 L *= I; // no-warning
41 }
42
divAssign(void)43 void divAssign(void) {
44 unsigned long L = 1000;
45 int I = -1;
46 U8 /= L; // no-warning
47 L /= I; // expected-warning {{Loss of sign in implicit conversion}}
48 }
49
remAssign(void)50 void remAssign(void) {
51 unsigned long L = 1000;
52 int I = -1;
53 U8 %= L; // no-warning
54 L %= I; // expected-warning {{Loss of sign in implicit conversion}}
55 }
56
andAssign(void)57 void andAssign(void) {
58 unsigned long L = 1000;
59 int I = -1;
60 U8 &= L; // no-warning
61 L &= I; // expected-warning {{Loss of sign in implicit conversion}}
62 }
63
orAssign(void)64 void orAssign(void) {
65 unsigned long L = 1000;
66 int I = -1;
67 U8 |= L; // expected-warning {{Loss of precision in implicit conversion}}
68 L |= I; // expected-warning {{Loss of sign in implicit conversion}}
69 }
70
xorAssign(void)71 void xorAssign(void) {
72 unsigned long L = 1000;
73 int I = -1;
74 U8 ^= L; // expected-warning {{Loss of precision in implicit conversion}}
75 L ^= I; // expected-warning {{Loss of sign in implicit conversion}}
76 }
77
init1(void)78 void init1(void) {
79 long long A = 1LL << 60;
80 short X = A; // expected-warning {{Loss of precision in implicit conversion}}
81 }
82
relational(unsigned U,signed S)83 void relational(unsigned U, signed S) {
84 if (S > 10) {
85 if (U < S) { // no-warning
86 }
87 }
88 if (S < -10) {
89 if (U < S) { // expected-warning {{Loss of sign in implicit conversion}}
90 }
91 }
92 }
93
multiplication(unsigned U,signed S)94 void multiplication(unsigned U, signed S) {
95 if (S > 5)
96 S = U * S; // no-warning
97 if (S < -10)
98 S = U * S; // expected-warning {{Loss of sign}}
99 }
100
division(unsigned U,signed S)101 void division(unsigned U, signed S) {
102 if (S > 5)
103 S = U / S; // no-warning
104 if (S < -10)
105 S = U / S; // expected-warning {{Loss of sign}}
106 }
107
f(unsigned x)108 void f(unsigned x) {}
g(unsigned x)109 void g(unsigned x) {}
110
functioncall1(void)111 void functioncall1(void) {
112 long x = -1;
113 int y = 0;
114 f(x); // expected-warning {{Loss of sign in implicit conversion}}
115 f(y);
116 }
117
functioncall2(int x,int y)118 void functioncall2(int x, int y) {
119 if (x < 0)
120 f(x); // expected-warning {{Loss of sign in implicit conversion}}
121 f(y);
122 f(x); // expected-warning {{Loss of sign in implicit conversion}}
123 }
124
dontwarn1(unsigned U,signed S)125 void dontwarn1(unsigned U, signed S) {
126 U8 = S; // It might be known that S is always 0x00-0xff.
127 S8 = U; // It might be known that U is always 0x00-0xff.
128
129 U8 = -1; // Explicit conversion.
130 S8 = ~0U; // Explicit conversion.
131 if (U > 300)
132 U8 &= U; // No loss of precision since there is &=.
133 }
134
dontwarn2(unsigned int U)135 void dontwarn2(unsigned int U) {
136 if (U <= 4294967295) {
137 }
138 if (U <= (2147483647 * 2U + 1U)) {
139 }
140 }
141
dontwarn3(int X)142 void dontwarn3(int X) {
143 S8 = X ? 'a' : 'b';
144 }
145
146 // don't warn for macros
147 #define DOSTUFF ({ unsigned X = 1000; U8 = X; })
dontwarn4(void)148 void dontwarn4(void) {
149 DOSTUFF;
150 }
151
dontwarn5(void)152 void dontwarn5(void) {
153 unsigned char c1 = 'A';
154 c1 = (c1 >= 'A' && c1 <= 'Z') ? c1 - 'A' + 'a' : c1;
155 unsigned char c2 = 0;
156 c2 = (c2 >= 'A' && c2 <= 'Z') ? c2 - 'A' + 'a' : c2;
157 unsigned char c3 = 'Z';
158 c3 = (c3 >= 'A' && c3 <= 'Z') ? c3 - 'A' + 'a' : c3;
159 unsigned char c4 = 'a';
160 c4 = (c4 >= 'A' && c4 <= 'Z') ? c4 - 'A' + 'a' : c4;
161 unsigned char c5 = '@';
162 c5 = (c5 >= 'A' && c5 <= 'Z') ? c5 - 'A' + 'a' : c5;
163 }
164
dontwarn6(void)165 void dontwarn6(void) {
166 int x = ~0;
167 unsigned y = ~0;
168 }
169
dontwarn7(unsigned x)170 void dontwarn7(unsigned x) {
171 if (x == (unsigned)-1) {
172 }
173 }
174
dontwarn8(void)175 void dontwarn8(void) {
176 unsigned x = (unsigned)-1;
177 }
178
dontwarn9(void)179 unsigned dontwarn9(void) {
180 return ~0;
181 }
182
dontwarn10(long long x)183 char dontwarn10(long long x) {
184 long long y = 42;
185 y += x;
186 return y == 42;
187 }
188
189
190 // C library functions, handled via unix.StdCLibraryFunctions
191
192 int isascii(int c);
libraryFunction1(void)193 void libraryFunction1(void) {
194 char kb2[5];
195 int X = 1000;
196 if (isascii(X)) {
197 kb2[0] = X; // no-warning
198 }
199 }
200
201
202 typedef struct FILE {} FILE; int getc(FILE *stream);
203 # define EOF (-1)
204 char reply_string[8192];
205 FILE *cin;
206 extern int dostuff(void);
libraryFunction2(void)207 int libraryFunction2(void) {
208 int c, n;
209 int dig;
210 char *cp = reply_string;
211 int pflag = 0;
212 int code;
213
214 for (;;) {
215 dig = n = code = 0;
216 while ((c = getc(cin)) != '\n') {
217 if (dig < 4 && dostuff())
218 code = code * 10 + (c - '0');
219 if (!pflag && code == 227)
220 pflag = 1;
221 if (n == 0)
222 n = c;
223 if (c == EOF)
224 return(4);
225 if (cp < &reply_string[sizeof(reply_string) - 1])
226 *cp++ = c; // no-warning
227 }
228 }
229 }
230
floating_point(long long a,int b)231 double floating_point(long long a, int b) {
232 if (a > 1LL << 55) {
233 double r = a; // expected-warning {{Loss of precision}}
234 return r;
235 } else if (b > 1 << 25) {
236 float f = b; // expected-warning {{Loss of precision}}
237 return f;
238 }
239 return 137;
240 }
241
floating_point2(void)242 double floating_point2(void) {
243 int a = 1 << 24;
244 long long b = 1LL << 53;
245 float f = a; // no-warning
246 double d = b; // no-warning
247 return d - f;
248 }
249
floating_point_3(unsigned long long a)250 int floating_point_3(unsigned long long a) {
251 double b = a; // no-warning
252 return 42;
253 }
254