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