[RISCV][FMV] Support target_clones (#85786)
[llvm-project.git] / clang / test / Analysis / conversion.c
blobcafe9c37c240225247f23497b1a8e1937097c713
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
6 unsigned char U8;
7 signed char S8;
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
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
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
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
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}}
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}}
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}}
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}}
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}}
78 void init1(void) {
79 long long A = 1LL << 60;
80 short X = A; // expected-warning {{Loss of precision in implicit conversion}}
83 void relational(unsigned U, signed S) {
84 if (S > 10) {
85 if (U < S) { // no-warning
88 if (S < -10) {
89 if (U < S) { // expected-warning {{Loss of sign in implicit conversion}}
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}}
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}}
108 void f(unsigned x) {}
109 void g(unsigned x) {}
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);
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}}
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.
129 U8 = -1; // Explicit conversion.
130 S8 = ~0U; // Explicit conversion.
131 if (U > 300)
132 U8 &= U; // No loss of precision since there is &=.
135 void dontwarn2(unsigned int U) {
136 if (U <= 4294967295) {
138 if (U <= (2147483647 * 2U + 1U)) {
142 void dontwarn3(int X) {
143 S8 = X ? 'a' : 'b';
146 // don't warn for macros
147 #define DOSTUFF ({ unsigned X = 1000; U8 = X; })
148 void dontwarn4(void) {
149 DOSTUFF;
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;
165 void dontwarn6(void) {
166 int x = ~0;
167 unsigned y = ~0;
170 void dontwarn7(unsigned x) {
171 if (x == (unsigned)-1) {
175 void dontwarn8(void) {
176 unsigned x = (unsigned)-1;
179 unsigned dontwarn9(void) {
180 return ~0;
183 char dontwarn10(long long x) {
184 long long y = 42;
185 y += x;
186 return y == 42;
190 // C library functions, handled via unix.StdCLibraryFunctions
192 int isascii(int c);
193 void libraryFunction1(void) {
194 char kb2[5];
195 int X = 1000;
196 if (isascii(X)) {
197 kb2[0] = X; // no-warning
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);
207 int libraryFunction2(void) {
208 int c, n;
209 int dig;
210 char *cp = reply_string;
211 int pflag = 0;
212 int code;
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
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;
239 return 137;
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;
250 int floating_point_3(unsigned long long a) {
251 double b = a; // no-warning
252 return 42;