conversion.c revision 323ed74658bc8375278eabf074b4777458376540
1// RUN: %clang_cc1 -fsyntax-only -verify -Wconversion -nostdinc -isystem %S/Inputs -triple x86_64-apple-darwin %s -Wno-unreachable-code
2
3#include <conversion.h>
4
5#define BIG 0x7f7f7f7f7f7f7f7fL
6
7void test0(char c, short s, int i, long l, long long ll) {
8  c = c;
9  c = s; // expected-warning {{implicit cast loses integer precision}}
10  c = i; // expected-warning {{implicit cast loses integer precision}}
11  c = l; // expected-warning {{implicit cast loses integer precision}}
12  s = c;
13  s = s;
14  s = i; // expected-warning {{implicit cast loses integer precision}}
15  s = l; // expected-warning {{implicit cast loses integer precision}}
16  i = c;
17  i = s;
18  i = i;
19  i = l; // expected-warning {{implicit cast loses integer precision}}
20  l = c;
21  l = s;
22  l = i;
23  l = l;
24
25  c = (char) 0;
26  c = (short) 0;
27  c = (int) 0;
28  c = (long) 0;
29  s = (char) 0;
30  s = (short) 0;
31  s = (int) 0;
32  s = (long) 0;
33  i = (char) 0;
34  i = (short) 0;
35  i = (int) 0;
36  i = (long) 0;
37  l = (char) 0;
38  l = (short) 0;
39  l = (int) 0;
40  l = (long) 0;
41
42  c = (char) BIG;
43  c = (short) BIG; // expected-warning {{implicit cast loses integer precision}}
44  c = (int) BIG; // expected-warning {{implicit cast loses integer precision}}
45  c = (long) BIG; // expected-warning {{implicit cast loses integer precision}}
46  s = (char) BIG;
47  s = (short) BIG;
48  s = (int) BIG; // expected-warning {{implicit cast loses integer precision}}
49  s = (long) BIG; // expected-warning {{implicit cast loses integer precision}}
50  i = (char) BIG;
51  i = (short) BIG;
52  i = (int) BIG;
53  i = (long) BIG; // expected-warning {{implicit cast loses integer precision}}
54  l = (char) BIG;
55  l = (short) BIG;
56  l = (int) BIG;
57  l = (long) BIG;
58}
59
60char test1(long long ll) {
61  return (long long) ll; // expected-warning {{implicit cast loses integer precision}}
62  return (long) ll; // expected-warning {{implicit cast loses integer precision}}
63  return (int) ll; // expected-warning {{implicit cast loses integer precision}}
64  return (short) ll; // expected-warning {{implicit cast loses integer precision}}
65  return (char) ll;
66  return (long long) BIG; // expected-warning {{implicit cast loses integer precision}}
67  return (long) BIG; // expected-warning {{implicit cast loses integer precision}}
68  return (int) BIG; // expected-warning {{implicit cast loses integer precision}}
69  return (short) BIG; // expected-warning {{implicit cast loses integer precision}}
70  return (char) BIG;
71}
72
73short test2(long long ll) {
74  return (long long) ll; // expected-warning {{implicit cast loses integer precision}}
75  return (long) ll; // expected-warning {{implicit cast loses integer precision}}
76  return (int) ll; // expected-warning {{implicit cast loses integer precision}}
77  return (short) ll;
78  return (char) ll;
79  return (long long) BIG;  // expected-warning {{implicit cast loses integer precision}}
80  return (long) BIG;  // expected-warning {{implicit cast loses integer precision}}
81  return (int) BIG;  // expected-warning {{implicit cast loses integer precision}}
82  return (short) BIG;
83  return (char) BIG;
84}
85
86int test3(long long ll) {
87  return (long long) ll;  // expected-warning {{implicit cast loses integer precision}}
88  return (long) ll;  // expected-warning {{implicit cast loses integer precision}}
89  return (int) ll;
90  return (short) ll;
91  return (char) ll;
92  return (long long) BIG;  // expected-warning {{implicit cast loses integer precision}}
93  return (long) BIG; // expected-warning {{implicit cast loses integer precision}}
94  return (int) BIG;
95  return (short) BIG;
96  return (char) BIG;
97}
98
99long test4(long long ll) {
100  return (long long) ll;
101  return (long) ll;
102  return (int) ll;
103  return (short) ll;
104  return (char) ll;
105  return (long long) BIG;
106  return (long) BIG;
107  return (int) BIG;
108  return (short) BIG;
109  return (char) BIG;
110}
111
112long long test5(long long ll) {
113  return (long long) ll;
114  return (long) ll;
115  return (int) ll;
116  return (short) ll;
117  return (char) ll;
118  return (long long) BIG;
119  return (long) BIG;
120  return (int) BIG;
121  return (short) BIG;
122  return (char) BIG;
123}
124
125void takes_char(char);
126void takes_short(short);
127void takes_int(int);
128void takes_long(long);
129void takes_longlong(long long);
130void takes_float(float);
131void takes_double(double);
132void takes_longdouble(long double);
133
134void test6(char v) {
135  takes_char(v);
136  takes_short(v);
137  takes_int(v);
138  takes_long(v);
139  takes_longlong(v);
140  takes_float(v);
141  takes_double(v);
142  takes_longdouble(v);
143}
144
145void test7(short v) {
146  takes_char(v); // expected-warning {{implicit cast loses integer precision}}
147  takes_short(v);
148  takes_int(v);
149  takes_long(v);
150  takes_longlong(v);
151  takes_float(v);
152  takes_double(v);
153  takes_longdouble(v);
154}
155
156void test8(int v) {
157  takes_char(v); // expected-warning {{implicit cast loses integer precision}}
158  takes_short(v); // expected-warning {{implicit cast loses integer precision}}
159  takes_int(v);
160  takes_long(v);
161  takes_longlong(v);
162  takes_float(v);
163  takes_double(v);
164  takes_longdouble(v);
165}
166
167void test9(long v) {
168  takes_char(v); // expected-warning {{implicit cast loses integer precision}}
169  takes_short(v); // expected-warning {{implicit cast loses integer precision}}
170  takes_int(v); // expected-warning {{implicit cast loses integer precision}}
171  takes_long(v);
172  takes_longlong(v);
173  takes_float(v);
174  takes_double(v);
175  takes_longdouble(v);
176}
177
178void test10(long long v) {
179  takes_char(v); // expected-warning {{implicit cast loses integer precision}}
180  takes_short(v); // expected-warning {{implicit cast loses integer precision}}
181  takes_int(v); // expected-warning {{implicit cast loses integer precision}}
182  takes_long(v);
183  takes_longlong(v);
184  takes_float(v);
185  takes_double(v);
186  takes_longdouble(v);
187}
188
189void test11(float v) {
190  takes_char(v); // expected-warning {{implicit cast turns floating-point number into integer}}
191  takes_short(v); // expected-warning {{implicit cast turns floating-point number into integer}}
192  takes_int(v); // expected-warning {{implicit cast turns floating-point number into integer}}
193  takes_long(v); // expected-warning {{implicit cast turns floating-point number into integer}}
194  takes_longlong(v); // expected-warning {{implicit cast turns floating-point number into integer}}
195  takes_float(v);
196  takes_double(v);
197  takes_longdouble(v);
198}
199
200void test12(double v) {
201  takes_char(v); // expected-warning {{implicit cast turns floating-point number into integer}}
202  takes_short(v); // expected-warning {{implicit cast turns floating-point number into integer}}
203  takes_int(v); // expected-warning {{implicit cast turns floating-point number into integer}}
204  takes_long(v); // expected-warning {{implicit cast turns floating-point number into integer}}
205  takes_longlong(v); // expected-warning {{implicit cast turns floating-point number into integer}}
206  takes_float(v); // expected-warning {{implicit cast loses floating-point precision}}
207  takes_double(v);
208  takes_longdouble(v);
209}
210
211void test13(long double v) {
212  takes_char(v); // expected-warning {{implicit cast turns floating-point number into integer}}
213  takes_short(v); // expected-warning {{implicit cast turns floating-point number into integer}}
214  takes_int(v); // expected-warning {{implicit cast turns floating-point number into integer}}
215  takes_long(v); // expected-warning {{implicit cast turns floating-point number into integer}}
216  takes_longlong(v); // expected-warning {{implicit cast turns floating-point number into integer}}
217  takes_float(v); // expected-warning {{implicit cast loses floating-point precision}}
218  takes_double(v); // expected-warning {{implicit cast loses floating-point precision}}
219  takes_longdouble(v);
220}
221
222void test14(long l) {
223  // Fine because of the boolean whitelist.
224  char c;
225  c = (l == 4);
226  c = ((l <= 4) && (l >= 0));
227  c = ((l <= 4) && (l >= 0)) || (l > 20);
228}
229
230void test15(char c) {
231  c = c + 1 + c * 2;
232  c = (short) c + 1 + c * 2; // expected-warning {{implicit cast loses integer precision}}
233}
234
235// PR 5422
236extern void *test16_external;
237void test16(void) {
238  int a = (unsigned long) &test16_external; // expected-warning {{implicit cast loses integer precision}}
239}
240
241// PR 5938
242void test17() {
243  union {
244    unsigned long long a : 8;
245    unsigned long long b : 32;
246    unsigned long long c;
247  } U;
248
249  unsigned int x;
250  x = U.a;
251  x = U.b;
252  x = U.c; // expected-warning {{implicit cast loses integer precision}}
253}
254
255// PR 5939
256void test18() {
257  union {
258    unsigned long long a : 1;
259    unsigned long long b;
260  } U;
261
262  int x;
263  x = (U.a ? 0 : 1);
264  x = (U.b ? 0 : 1);
265}
266
267// None of these should warn.
268unsigned char test19(unsigned long u64) {
269  unsigned char x1 = u64 & 0xff;
270  unsigned char x2 = u64 >> 56;
271
272  unsigned char mask = 0xee;
273  unsigned char x3 = u64 & mask;
274  return x1 + x2 + x3;
275}
276
277// <rdar://problem/7631400>
278void test_7631400(void) {
279  // This should show up despite the caret being inside a macro substitution
280  char s = LONG_MAX; // expected-warning {{implicit cast loses integer precision: 'long' to 'char'}}
281}
282
283// <rdar://problem/7676608>: assertion for compound operators with non-integral RHS
284void f7676608(int);
285void test_7676608(void) {
286  float q = 0.7f;
287  char c = 5;
288  f7676608(c *= q);
289}
290
291// <rdar://problem/7904686>
292void test_7904686(void) {
293  const int i = -1;
294  unsigned u1 = i; // expected-warning {{implicit cast changes signedness}}
295  u1 = i; // expected-warning {{implicit cast changes signedness}}
296
297  unsigned u2 = -1; // expected-warning {{implicit cast changes signedness}}
298  u2 = -1; // expected-warning {{implicit cast changes signedness}}
299}
300