expr_fold.c revision 1.1
1/*	$NetBSD: expr_fold.c,v 1.1 2021/08/19 20:32:33 rillig Exp $	*/
2# 3 "expr_fold.c"
3
4/*
5 * Test folding of constant expressions.
6 */
7
8/* lint1-extra-flags: -h */
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	/* XXX: one of these two messages is redundant */
33	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
34	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
35	take_int(+(2147483648));
36	/* XXX: one of these two messages is redundant */
37	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
38	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
39	take_int(+(4294967295));
40
41	take_uint(+(0));
42	take_uint(+(2147483647));
43	/* expect+1: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
44	take_uint(+(2147483648));
45	/* expect+1: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
46	take_uint(+(4294967295));
47
48	/*
49	 * Hexadecimal constants and constants with the suffix 'U' get either
50	 * a signed or an unsigned integer type, so no warning here.
51	 */
52	take_uint(+(2147483648U));
53	take_uint(+(0x80000000));
54	take_uint(+(0x80000000U));
55}
56
57void
58fold_uminus(void)
59{
60	take_int(-(0));
61	take_int(-(2147483647));
62
63	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
64	take_int(-(2147483648));
65
66	/* The '-' is an operator, it is not part of the integer constant. */
67	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
68	take_int(-2147483648);
69
70	/* expect+2: warning: integer overflow detected, op + [141] */
71	/* expect+1: warning: integer overflow detected, op - [141] */
72	take_int(-(2147483647 + 1));
73	/* expect+1: warning: integer overflow detected, op - [141] */
74	take_int(-(-2147483647 - 1));
75	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
76	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
77	take_int(-(4294967295));
78
79	take_uint(-(0));
80	/* expect+2: warning: conversion of negative constant to unsigned type, arg #1 [296] */
81	/* expect+1: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */
82	take_uint(-(2147483647));
83	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
84	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
85	take_uint(-(2147483648));
86	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
87	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
88	take_uint(-(4294967295));
89}
90
91void
92fold_compl(void)
93{
94	take_int(~(0));
95	take_int(~(2147483647));
96	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
97	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
98	take_int(~(2147483648));
99	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
100	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
101	take_int(~(4294967295));
102
103	/* expect+2: warning: conversion of negative constant to unsigned type, arg #1 [296] */
104	/* expect+1: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */
105	take_uint(~(0));
106	/* expect+2: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */
107	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
108	take_uint(~(2147483647));
109	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
110	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
111	take_uint(~(2147483648));
112	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
113	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
114	take_uint(~(4294967295));
115}
116
117void
118fold_mult(void)
119{
120	take_int(32767 * 65536);
121	/* expect+1: warning: integer overflow detected, op * [141] */
122	take_int(32768 * 65536);
123	/* expect+1: warning: integer overflow detected, op * [141] */
124	take_int(65536 * 65536);
125
126	take_uint(32767 * 65536U);
127	take_uint(32768 * 65536U);
128	/* expect+1: warning: integer overflow detected, op * [141] */
129	take_uint(65536 * 65536U);
130}
131
132void
133fold_div(void)
134{
135	/* expect+3: error: division by 0 [139] */
136	/* XXX: The following message is redundant. */
137	/* expect+1: warning: integer overflow detected, op / [141] */
138	take_int(0 / 0);
139
140	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
141	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
142	take_int(-2147483648 / -1);
143}
144
145void
146fold_mod(void)
147{
148	/* expect+1: error: modulus by 0 [140] */
149	take_int(0 % 0);
150	/* expect+1: error: modulus by 0 [140] */
151	take_int(0 % 0U);
152	/* expect+1: error: modulus by 0 [140] */
153	take_int(0U % 0);
154	/* expect+1: error: modulus by 0 [140] */
155	take_int(0U % 0U);
156
157	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
158	take_int(-2147483648 % -1);
159}
160
161void
162fold_plus(void)
163{
164	/* expect+1: warning: integer overflow detected, op + [141] */
165	take_int(2147483647 + 1);
166
167	/* Assume two's complement, so no overflow. */
168	take_int(-2147483647 + -1);
169
170	/* expect+1: warning: integer overflow detected, op + [141] */
171	take_int(-2147483647 + -2);
172
173	/*
174	 * No overflow since one of the operands is unsigned, therefore the
175	 * other operand is converted to unsigned as well.
176	 * See C99 6.3.1.8p1, paragraph 8 of 10.
177	 */
178	/*FIXME*//* expect+1: warning: integer overflow detected, op + [141] */
179	take_uint(2147483647 + 1U);
180	/*FIXME*//* expect+1: warning: integer overflow detected, op + [141] */
181	take_uint(2147483647U + 1);
182}
183
184void
185fold_minus(void)
186{
187	/* expect+1: warning: integer overflow detected, op - [141] */
188	take_int(2147483647 - -1);
189	/* Assume two's complement. */
190	take_int(-2147483647 - 1);
191	/* expect+1: warning: integer overflow detected, op - [141] */
192	take_int(-2147483647 - 2);
193
194	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
195	take_int(0 - 2147483648);
196	/* expect+1: warning: integer overflow detected, op - [141] */
197	take_uint(0 - 2147483648U);
198}
199
200void
201fold_shl(void)
202{
203	/* expect+1: warning: integer overflow detected, op << [141] */
204	take_int(1 << 24 << 24);
205
206	/* expect+1: warning: integer overflow detected, op << [141] */
207	take_uint(1U << 24 << 24);
208
209	/* FIXME: undefined behavior in 'fold' at 'uint64_t << 104'. */
210	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'unsigned int' [122] */
211	take_uint(1U << 24 << 104);
212}
213
214void
215fold_shr(void)
216{
217	take_int(16777216 >> 24);
218
219	take_int(16777216 >> 25);
220
221	/* FIXME: undefined behavior in 'fold' at 'uint64_t >> 104'. */
222	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'int' [122] */
223	take_int(16777216 >> 104);
224}
225
226void
227fold_lt(void)
228{
229	take_bool(1 < 3);
230	take_bool(3 < 1);
231}
232
233void
234fold_le(void)
235{
236	take_bool(1 <= 3);
237	take_bool(3 <= 1);
238}
239
240void
241fold_ge(void)
242{
243	take_bool(1 >= 3);
244	take_bool(3 >= 1);
245}
246
247void
248fold_gt(void)
249{
250	take_bool(1 > 3);
251	take_bool(3 > 1);
252}
253
254void
255fold_eq(void)
256{
257	take_bool(1 == 3);
258	take_bool(3 == 1);
259}
260
261void
262fold_ne(void)
263{
264	take_bool(1 != 3);
265	take_bool(3 != 1);
266}
267
268void
269fold_bitand(void)
270{
271	take_bool(1 & 3);
272	take_bool(3 & 1);
273}
274
275void
276fold_bitxor(void)
277{
278	take_bool(1 ^ 3);
279	take_bool(3 ^ 1);
280}
281
282void
283fold_bitor(void)
284{
285	take_bool(1 | 3);
286	take_bool(3 | 1);
287}
288