expr_fold.c revision 1.15
1/*	$NetBSD: expr_fold.c,v 1.15 2024/03/10 19:45:14 rillig Exp $	*/
2# 3 "expr_fold.c"
3
4/*
5 * Test folding of constant expressions.
6 */
7
8/* lint1-extra-flags: -h -X 351 */
9
10/*
11 * On ILP32 platforms, the integer constant 2147483648 cannot be represented
12 * as 'int' or 'long', therefore it becomes 'long long'.  This would
13 * influence the type names in the diagnostics.
14 */
15/* lint1-only-if: lp64 */
16
17void take_bool(_Bool);
18void take_int(int);
19void take_uint(unsigned int);
20
21/*
22 * C99 6.4.4.1p5 defines that decimal integer constants without suffix get
23 * one of the signed integer types. On the other hand, octal and hexadecimal
24 * constants get either a signed or unsigned type, whichever fits first.
25 */
26
27void
28fold_uplus(void)
29{
30	take_int(+(0));
31	take_int(+(2147483647));
32	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
33	take_int(+(2147483648));
34	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
35	take_int(+(4294967295));
36
37	take_uint(+(0));
38	take_uint(+(2147483647));
39	take_uint(+(2147483648));
40	take_uint(+(4294967295));
41
42	/*
43	 * Hexadecimal constants and constants with the suffix 'U' get either
44	 * a signed or an unsigned integer type, so no warning here.
45	 */
46	take_uint(+(2147483648U));
47	take_uint(+(0x80000000));
48	take_uint(+(0x80000000U));
49}
50
51void
52fold_uminus(void)
53{
54	take_int(-(0));
55	take_int(-(2147483647));
56
57	take_int(-(2147483648));
58
59	/* The '-' is an operator, it is not part of the integer constant. */
60	take_int(-2147483648);
61
62	/* expect+1: warning: '2147483647 + 1' overflows 'int' [141] */
63	take_int(-(2147483647 + 1));
64	/* expect+1: warning: '-(-2147483648)' overflows 'int' [141] */
65	take_int(-(-2147483647 - 1));
66	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
67	take_int(-(4294967295));
68
69	take_uint(-(0));
70	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
71	take_uint(-(2147483647));
72	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
73	take_uint(-(2147483648));
74	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
75	take_uint(-(4294967295));
76}
77
78void
79fold_compl(void)
80{
81	take_int(~(0));
82	take_int(~(2147483647));
83	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
84	take_int(~(2147483648));
85	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
86	take_int(~(4294967295));
87
88	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
89	take_uint(~(0));
90	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
91	take_uint(~(2147483647));
92	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
93	take_uint(~(2147483648));
94	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
95	take_uint(~(4294967295));
96}
97
98void
99fold_mult(void)
100{
101	take_int(32767 * 65536);
102	/* expect+1: warning: '32768 * 65536' overflows 'int' [141] */
103	take_int(32768 * 65536);
104	/* expect+1: warning: '65536 * 65536' overflows 'int' [141] */
105	take_int(65536 * 65536);
106
107	take_uint(32767 * 65536U);
108	take_uint(32768 * 65536U);
109	/* expect+1: warning: '65536 * 65536' overflows 'unsigned int' [141] */
110	take_uint(65536 * 65536U);
111}
112
113void
114fold_div(void)
115{
116	/* expect+1: error: division by 0 [139] */
117	take_int(0 / 0);
118
119	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
120	take_int(-2147483648 / -1);
121}
122
123void
124fold_mod(void)
125{
126	/* expect+1: error: modulus by 0 [140] */
127	take_int(0 % 0);
128	/* expect+1: error: modulus by 0 [140] */
129	take_int(0 % 0U);
130	/* expect+1: error: modulus by 0 [140] */
131	take_int(0U % 0);
132	/* expect+1: error: modulus by 0 [140] */
133	take_int(0U % 0U);
134
135	take_int(-2147483648 % -1);
136}
137
138void
139fold_plus(void)
140{
141	/* expect+1: warning: '2147483647 + 1' overflows 'int' [141] */
142	take_int(2147483647 + 1);
143
144	/* Assume two's complement, so no overflow. */
145	take_int(-2147483647 + -1);
146
147	/* expect+1: warning: '-2147483647 + -2' overflows 'int' [141] */
148	take_int(-2147483647 + -2);
149
150	/*
151	 * No overflow since one of the operands is unsigned, therefore the
152	 * other operand is converted to unsigned as well.
153	 * See C99 6.3.1.8p1, paragraph 8 of 10.
154	 */
155	/* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */
156	take_uint(2147483647 + 1U);
157	/* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */
158	take_uint(2147483647U + 1);
159}
160
161void
162fold_minus(void)
163{
164	/* expect+1: warning: '2147483647 - -1' overflows 'int' [141] */
165	take_int(2147483647 - -1);
166	/* Assume two's complement. */
167	take_int(-2147483647 - 1);
168	/* expect+1: warning: '-2147483647 - 2' overflows 'int' [141] */
169	take_int(-2147483647 - 2);
170
171	take_int(0 - 2147483648);
172	/* expect+1: warning: '0 - 2147483648' overflows 'unsigned int' [141] */
173	take_uint(0 - 2147483648U);
174}
175
176void
177fold_shl(void)
178{
179	/* expect+1: warning: '16777216 << 24' overflows 'int' [141] */
180	take_int(1 << 24 << 24);
181
182	/* expect+1: warning: '16777216 << 24' overflows 'unsigned int' [141] */
183	take_uint(1U << 24 << 24);
184
185	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'unsigned int' [122] */
186	take_uint(1U << 24 << 104);
187}
188
189void
190fold_shr(void)
191{
192	take_int(16777216 >> 24);
193
194	take_int(16777216 >> 25);
195
196	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'int' [122] */
197	take_int(16777216 >> 104);
198}
199
200void
201fold_lt(void)
202{
203	take_bool(1 < 3);
204	take_bool(3 < 1);
205}
206
207void
208fold_le(void)
209{
210	take_bool(1 <= 3);
211	take_bool(3 <= 1);
212}
213
214void
215fold_ge(void)
216{
217	take_bool(1 >= 3);
218	take_bool(3 >= 1);
219}
220
221void
222fold_gt(void)
223{
224	take_bool(1 > 3);
225	take_bool(3 > 1);
226}
227
228void
229fold_eq(void)
230{
231	take_bool(1 == 3);
232	take_bool(3 == 1);
233}
234
235void
236fold_ne(void)
237{
238	take_bool(1 != 3);
239	take_bool(3 != 1);
240}
241
242void
243fold_bitand(void)
244{
245	take_bool(1 & 3);
246	take_bool(3 & 1);
247}
248
249void
250fold_bitxor(void)
251{
252	take_bool(1 ^ 3);
253	take_bool(3 ^ 1);
254}
255
256void
257fold_bitor(void)
258{
259	take_bool(1 | 3);
260	take_bool(3 | 1);
261}
262
263/*
264 * The following expression originated in vndcompress.c 1.29 from 2017-07-29,
265 * where line 310 contained a seemingly harmless compile-time assertion that
266 * expanded to a real monster expression.
267 *
268 * __CTASSERT(MUL_OK(uint64_t, MAX_N_BLOCKS, MAX_BLOCKSIZE));
269 *
270 * Before tree.c 1.345 from 2021-08-22, lint wrongly assumed that the result
271 * of all binary operators were the common arithmetic type, but that was
272 * wrong for the comparison operators.  The expression '1ULL < 2ULL' does not
273 * have type 'unsigned long long' but 'int' in default mode, or '_Bool' in
274 * strict bool mode.
275 */
276struct ctassert5_struct {
277	unsigned int member:
278	    /*CONSTCOND*/
279	    0xfffffffeU
280	    <=
281		((1ULL << 63) + 1 < 1 ? ~(1ULL << 63) : ~0ULL) / 0xfffffe00U
282		? 1
283		: -1;
284};
285
286/*
287 * Since Makefile.inc 1.21 from 2022-04-08 (which added -ftrapv) and before
288 * tree.c 1.436 from 2022-04-20, lint crashed with an integer overflow when
289 * calculating '-(uint64_t)INT64_MIN' in val_t.u.integer.
290 */
291void
292unary_minus_overflow(unsigned long long val)
293{
294	if (val > -(unsigned long long)(-0x7fffffffffffffffL - 1))
295		return;
296}
297