1*98412b50Srillig /* $NetBSD: expr_fold.c,v 1.16 2024/06/08 06:37:06 rillig Exp $ */
259e08a43Srillig # 3 "expr_fold.c"
359e08a43Srillig
459e08a43Srillig /*
559e08a43Srillig * Test folding of constant expressions.
659e08a43Srillig */
759e08a43Srillig
8b2baa501Srillig /* lint1-extra-flags: -h -X 351 */
959e08a43Srillig
1059e08a43Srillig /*
1159e08a43Srillig * On ILP32 platforms, the integer constant 2147483648 cannot be represented
1259e08a43Srillig * as 'int' or 'long', therefore it becomes 'long long'. This would
1359e08a43Srillig * influence the type names in the diagnostics.
1459e08a43Srillig */
1559e08a43Srillig /* lint1-only-if: lp64 */
1659e08a43Srillig
1759e08a43Srillig void take_bool(_Bool);
1859e08a43Srillig void take_int(int);
1959e08a43Srillig void take_uint(unsigned int);
2059e08a43Srillig
2159e08a43Srillig /*
2259e08a43Srillig * C99 6.4.4.1p5 defines that decimal integer constants without suffix get
2359e08a43Srillig * one of the signed integer types. On the other hand, octal and hexadecimal
2459e08a43Srillig * constants get either a signed or unsigned type, whichever fits first.
2559e08a43Srillig */
2659e08a43Srillig
2759e08a43Srillig void
fold_uplus(void)2859e08a43Srillig fold_uplus(void)
2959e08a43Srillig {
3059e08a43Srillig take_int(+(0));
3159e08a43Srillig take_int(+(2147483647));
3259e08a43Srillig /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
3359e08a43Srillig take_int(+(2147483648));
3459e08a43Srillig /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
3559e08a43Srillig take_int(+(4294967295));
3659e08a43Srillig
3759e08a43Srillig take_uint(+(0));
3859e08a43Srillig take_uint(+(2147483647));
3959e08a43Srillig take_uint(+(2147483648));
4059e08a43Srillig take_uint(+(4294967295));
4159e08a43Srillig
4259e08a43Srillig /*
4359e08a43Srillig * Hexadecimal constants and constants with the suffix 'U' get either
4459e08a43Srillig * a signed or an unsigned integer type, so no warning here.
4559e08a43Srillig */
4659e08a43Srillig take_uint(+(2147483648U));
4759e08a43Srillig take_uint(+(0x80000000));
4859e08a43Srillig take_uint(+(0x80000000U));
4959e08a43Srillig }
5059e08a43Srillig
5159e08a43Srillig void
fold_uminus(void)5259e08a43Srillig fold_uminus(void)
5359e08a43Srillig {
5459e08a43Srillig take_int(-(0));
5559e08a43Srillig take_int(-(2147483647));
5659e08a43Srillig
5759e08a43Srillig take_int(-(2147483648));
5859e08a43Srillig
5959e08a43Srillig /* The '-' is an operator, it is not part of the integer constant. */
6059e08a43Srillig take_int(-2147483648);
6159e08a43Srillig
62dd848decSrillig /* expect+1: warning: '2147483647 + 1' overflows 'int' [141] */
6359e08a43Srillig take_int(-(2147483647 + 1));
64dd848decSrillig /* expect+1: warning: '-(-2147483648)' overflows 'int' [141] */
6559e08a43Srillig take_int(-(-2147483647 - 1));
6659e08a43Srillig /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
6759e08a43Srillig take_int(-(4294967295));
6859e08a43Srillig
6959e08a43Srillig take_uint(-(0));
70*98412b50Srillig /* expect+1: warning: conversion of negative constant -2147483647 to unsigned type 'unsigned int', arg #1 [296] */
7159e08a43Srillig take_uint(-(2147483647));
72*98412b50Srillig /* expect+1: warning: conversion of negative constant -2147483648 to unsigned type 'unsigned int', arg #1 [296] */
7359e08a43Srillig take_uint(-(2147483648));
74*98412b50Srillig /* expect+1: warning: conversion of negative constant -4294967295 to unsigned type 'unsigned int', arg #1 [296] */
7559e08a43Srillig take_uint(-(4294967295));
7659e08a43Srillig }
7759e08a43Srillig
7859e08a43Srillig void
fold_compl(void)7959e08a43Srillig fold_compl(void)
8059e08a43Srillig {
8159e08a43Srillig take_int(~(0));
8259e08a43Srillig take_int(~(2147483647));
8359e08a43Srillig /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
8459e08a43Srillig take_int(~(2147483648));
8559e08a43Srillig /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
8659e08a43Srillig take_int(~(4294967295));
8759e08a43Srillig
88*98412b50Srillig /* expect+1: warning: conversion of negative constant -1 to unsigned type 'unsigned int', arg #1 [296] */
8959e08a43Srillig take_uint(~(0));
90*98412b50Srillig /* expect+1: warning: conversion of negative constant -2147483648 to unsigned type 'unsigned int', arg #1 [296] */
9159e08a43Srillig take_uint(~(2147483647));
92*98412b50Srillig /* expect+1: warning: conversion of negative constant -2147483649 to unsigned type 'unsigned int', arg #1 [296] */
9359e08a43Srillig take_uint(~(2147483648));
94*98412b50Srillig /* expect+1: warning: conversion of negative constant -4294967296 to unsigned type 'unsigned int', arg #1 [296] */
9559e08a43Srillig take_uint(~(4294967295));
9659e08a43Srillig }
9759e08a43Srillig
9859e08a43Srillig void
fold_mult(void)9959e08a43Srillig fold_mult(void)
10059e08a43Srillig {
10159e08a43Srillig take_int(32767 * 65536);
102dd848decSrillig /* expect+1: warning: '32768 * 65536' overflows 'int' [141] */
10359e08a43Srillig take_int(32768 * 65536);
104dd848decSrillig /* expect+1: warning: '65536 * 65536' overflows 'int' [141] */
10559e08a43Srillig take_int(65536 * 65536);
10659e08a43Srillig
10759e08a43Srillig take_uint(32767 * 65536U);
10859e08a43Srillig take_uint(32768 * 65536U);
109dd848decSrillig /* expect+1: warning: '65536 * 65536' overflows 'unsigned int' [141] */
11059e08a43Srillig take_uint(65536 * 65536U);
11159e08a43Srillig }
11259e08a43Srillig
11359e08a43Srillig void
fold_div(void)11459e08a43Srillig fold_div(void)
11559e08a43Srillig {
1163e856647Srillig /* expect+1: error: division by 0 [139] */
11759e08a43Srillig take_int(0 / 0);
11859e08a43Srillig
11959e08a43Srillig /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
12059e08a43Srillig take_int(-2147483648 / -1);
12159e08a43Srillig }
12259e08a43Srillig
12359e08a43Srillig void
fold_mod(void)12459e08a43Srillig fold_mod(void)
12559e08a43Srillig {
12659e08a43Srillig /* expect+1: error: modulus by 0 [140] */
12759e08a43Srillig take_int(0 % 0);
12859e08a43Srillig /* expect+1: error: modulus by 0 [140] */
12959e08a43Srillig take_int(0 % 0U);
13059e08a43Srillig /* expect+1: error: modulus by 0 [140] */
13159e08a43Srillig take_int(0U % 0);
13259e08a43Srillig /* expect+1: error: modulus by 0 [140] */
13359e08a43Srillig take_int(0U % 0U);
13459e08a43Srillig
13559e08a43Srillig take_int(-2147483648 % -1);
13659e08a43Srillig }
13759e08a43Srillig
13859e08a43Srillig void
fold_plus(void)13959e08a43Srillig fold_plus(void)
14059e08a43Srillig {
141dd848decSrillig /* expect+1: warning: '2147483647 + 1' overflows 'int' [141] */
14259e08a43Srillig take_int(2147483647 + 1);
14359e08a43Srillig
14459e08a43Srillig /* Assume two's complement, so no overflow. */
14559e08a43Srillig take_int(-2147483647 + -1);
14659e08a43Srillig
147dd848decSrillig /* expect+1: warning: '-2147483647 + -2' overflows 'int' [141] */
14859e08a43Srillig take_int(-2147483647 + -2);
14959e08a43Srillig
15059e08a43Srillig /*
15159e08a43Srillig * No overflow since one of the operands is unsigned, therefore the
15259e08a43Srillig * other operand is converted to unsigned as well.
15359e08a43Srillig * See C99 6.3.1.8p1, paragraph 8 of 10.
15459e08a43Srillig */
1552de04c81Srillig /* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */
15659e08a43Srillig take_uint(2147483647 + 1U);
1572de04c81Srillig /* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */
15859e08a43Srillig take_uint(2147483647U + 1);
15959e08a43Srillig }
16059e08a43Srillig
16159e08a43Srillig void
fold_minus(void)16259e08a43Srillig fold_minus(void)
16359e08a43Srillig {
164dd848decSrillig /* expect+1: warning: '2147483647 - -1' overflows 'int' [141] */
16559e08a43Srillig take_int(2147483647 - -1);
16659e08a43Srillig /* Assume two's complement. */
16759e08a43Srillig take_int(-2147483647 - 1);
168dd848decSrillig /* expect+1: warning: '-2147483647 - 2' overflows 'int' [141] */
16959e08a43Srillig take_int(-2147483647 - 2);
17059e08a43Srillig
17159e08a43Srillig take_int(0 - 2147483648);
172dd848decSrillig /* expect+1: warning: '0 - 2147483648' overflows 'unsigned int' [141] */
17359e08a43Srillig take_uint(0 - 2147483648U);
17459e08a43Srillig }
17559e08a43Srillig
17659e08a43Srillig void
fold_shl(void)17759e08a43Srillig fold_shl(void)
17859e08a43Srillig {
179dd848decSrillig /* expect+1: warning: '16777216 << 24' overflows 'int' [141] */
18059e08a43Srillig take_int(1 << 24 << 24);
18159e08a43Srillig
182dd848decSrillig /* expect+1: warning: '16777216 << 24' overflows 'unsigned int' [141] */
18359e08a43Srillig take_uint(1U << 24 << 24);
18459e08a43Srillig
18559e08a43Srillig /* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'unsigned int' [122] */
18659e08a43Srillig take_uint(1U << 24 << 104);
18759e08a43Srillig }
18859e08a43Srillig
18959e08a43Srillig void
fold_shr(void)19059e08a43Srillig fold_shr(void)
19159e08a43Srillig {
19259e08a43Srillig take_int(16777216 >> 24);
19359e08a43Srillig
19459e08a43Srillig take_int(16777216 >> 25);
19559e08a43Srillig
19659e08a43Srillig /* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'int' [122] */
19759e08a43Srillig take_int(16777216 >> 104);
19859e08a43Srillig }
19959e08a43Srillig
20059e08a43Srillig void
fold_lt(void)20159e08a43Srillig fold_lt(void)
20259e08a43Srillig {
20359e08a43Srillig take_bool(1 < 3);
20459e08a43Srillig take_bool(3 < 1);
20559e08a43Srillig }
20659e08a43Srillig
20759e08a43Srillig void
fold_le(void)20859e08a43Srillig fold_le(void)
20959e08a43Srillig {
21059e08a43Srillig take_bool(1 <= 3);
21159e08a43Srillig take_bool(3 <= 1);
21259e08a43Srillig }
21359e08a43Srillig
21459e08a43Srillig void
fold_ge(void)21559e08a43Srillig fold_ge(void)
21659e08a43Srillig {
21759e08a43Srillig take_bool(1 >= 3);
21859e08a43Srillig take_bool(3 >= 1);
21959e08a43Srillig }
22059e08a43Srillig
22159e08a43Srillig void
fold_gt(void)22259e08a43Srillig fold_gt(void)
22359e08a43Srillig {
22459e08a43Srillig take_bool(1 > 3);
22559e08a43Srillig take_bool(3 > 1);
22659e08a43Srillig }
22759e08a43Srillig
22859e08a43Srillig void
fold_eq(void)22959e08a43Srillig fold_eq(void)
23059e08a43Srillig {
23159e08a43Srillig take_bool(1 == 3);
23259e08a43Srillig take_bool(3 == 1);
23359e08a43Srillig }
23459e08a43Srillig
23559e08a43Srillig void
fold_ne(void)23659e08a43Srillig fold_ne(void)
23759e08a43Srillig {
23859e08a43Srillig take_bool(1 != 3);
23959e08a43Srillig take_bool(3 != 1);
24059e08a43Srillig }
24159e08a43Srillig
24259e08a43Srillig void
fold_bitand(void)24359e08a43Srillig fold_bitand(void)
24459e08a43Srillig {
24559e08a43Srillig take_bool(1 & 3);
24659e08a43Srillig take_bool(3 & 1);
24759e08a43Srillig }
24859e08a43Srillig
24959e08a43Srillig void
fold_bitxor(void)25059e08a43Srillig fold_bitxor(void)
25159e08a43Srillig {
25259e08a43Srillig take_bool(1 ^ 3);
25359e08a43Srillig take_bool(3 ^ 1);
25459e08a43Srillig }
25559e08a43Srillig
25659e08a43Srillig void
fold_bitor(void)25759e08a43Srillig fold_bitor(void)
25859e08a43Srillig {
25959e08a43Srillig take_bool(1 | 3);
26059e08a43Srillig take_bool(3 | 1);
26159e08a43Srillig }
26254836453Srillig
26354836453Srillig /*
26454836453Srillig * The following expression originated in vndcompress.c 1.29 from 2017-07-29,
26554836453Srillig * where line 310 contained a seemingly harmless compile-time assertion that
26654836453Srillig * expanded to a real monster expression.
26754836453Srillig *
26854836453Srillig * __CTASSERT(MUL_OK(uint64_t, MAX_N_BLOCKS, MAX_BLOCKSIZE));
269a8096716Srillig *
270a8096716Srillig * Before tree.c 1.345 from 2021-08-22, lint wrongly assumed that the result
271a8096716Srillig * of all binary operators were the common arithmetic type, but that was
272a8096716Srillig * wrong for the comparison operators. The expression '1ULL < 2ULL' does not
273a8096716Srillig * have type 'unsigned long long' but 'int' in default mode, or '_Bool' in
274a8096716Srillig * strict bool mode.
27554836453Srillig */
27654836453Srillig struct ctassert5_struct {
27754836453Srillig unsigned int member:
27854836453Srillig /*CONSTCOND*/
27954836453Srillig 0xfffffffeU
28054836453Srillig <=
28154836453Srillig ((1ULL << 63) + 1 < 1 ? ~(1ULL << 63) : ~0ULL) / 0xfffffe00U
28254836453Srillig ? 1
28354836453Srillig : -1;
28454836453Srillig };
285598b5fa3Srillig
286598b5fa3Srillig /*
287598b5fa3Srillig * Since Makefile.inc 1.21 from 2022-04-08 (which added -ftrapv) and before
288598b5fa3Srillig * tree.c 1.436 from 2022-04-20, lint crashed with an integer overflow when
289ad4700f6Srillig * calculating '-(uint64_t)INT64_MIN' in val_t.u.integer.
290598b5fa3Srillig */
291598b5fa3Srillig void
unary_minus_overflow(unsigned long long val)292598b5fa3Srillig unary_minus_overflow(unsigned long long val)
293598b5fa3Srillig {
294598b5fa3Srillig if (val > -(unsigned long long)(-0x7fffffffffffffffL - 1))
295598b5fa3Srillig return;
296598b5fa3Srillig }
297