expr_fold.c revision 1.17
11.17Srillig/*	$NetBSD: expr_fold.c,v 1.17 2025/04/10 20:37:48 rillig Exp $	*/
21.1Srillig# 3 "expr_fold.c"
31.1Srillig
41.1Srillig/*
51.1Srillig * Test folding of constant expressions.
61.1Srillig */
71.1Srillig
81.8Srillig/* lint1-extra-flags: -h -X 351 */
91.1Srillig
101.1Srillig/*
111.1Srillig * On ILP32 platforms, the integer constant 2147483648 cannot be represented
121.1Srillig * as 'int' or 'long', therefore it becomes 'long long'.  This would
131.1Srillig * influence the type names in the diagnostics.
141.1Srillig */
151.1Srillig/* lint1-only-if: lp64 */
161.1Srillig
171.1Srilligvoid take_bool(_Bool);
181.1Srilligvoid take_int(int);
191.1Srilligvoid take_uint(unsigned int);
201.1Srillig
211.1Srillig/*
221.1Srillig * C99 6.4.4.1p5 defines that decimal integer constants without suffix get
231.1Srillig * one of the signed integer types. On the other hand, octal and hexadecimal
241.1Srillig * constants get either a signed or unsigned type, whichever fits first.
251.1Srillig */
261.1Srillig
271.1Srilligvoid
281.1Srilligfold_uplus(void)
291.1Srillig{
301.1Srillig	take_int(+(0));
311.1Srillig	take_int(+(2147483647));
321.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
331.1Srillig	take_int(+(2147483648));
341.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
351.1Srillig	take_int(+(4294967295));
361.1Srillig
371.1Srillig	take_uint(+(0));
381.1Srillig	take_uint(+(2147483647));
391.1Srillig	take_uint(+(2147483648));
401.1Srillig	take_uint(+(4294967295));
411.1Srillig
421.1Srillig	/*
431.1Srillig	 * Hexadecimal constants and constants with the suffix 'U' get either
441.1Srillig	 * a signed or an unsigned integer type, so no warning here.
451.1Srillig	 */
461.1Srillig	take_uint(+(2147483648U));
471.1Srillig	take_uint(+(0x80000000));
481.1Srillig	take_uint(+(0x80000000U));
491.1Srillig}
501.1Srillig
511.1Srilligvoid
521.1Srilligfold_uminus(void)
531.1Srillig{
541.1Srillig	take_int(-(0));
551.1Srillig	take_int(-(2147483647));
561.1Srillig
571.1Srillig	take_int(-(2147483648));
581.1Srillig
591.1Srillig	/* The '-' is an operator, it is not part of the integer constant. */
601.1Srillig	take_int(-2147483648);
611.1Srillig
621.15Srillig	/* expect+1: warning: '2147483647 + 1' overflows 'int' [141] */
631.1Srillig	take_int(-(2147483647 + 1));
641.15Srillig	/* expect+1: warning: '-(-2147483648)' overflows 'int' [141] */
651.1Srillig	take_int(-(-2147483647 - 1));
661.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
671.1Srillig	take_int(-(4294967295));
681.1Srillig
691.1Srillig	take_uint(-(0));
701.16Srillig	/* expect+1: warning: conversion of negative constant -2147483647 to unsigned type 'unsigned int', arg #1 [296] */
711.1Srillig	take_uint(-(2147483647));
721.16Srillig	/* expect+1: warning: conversion of negative constant -2147483648 to unsigned type 'unsigned int', arg #1 [296] */
731.1Srillig	take_uint(-(2147483648));
741.16Srillig	/* expect+1: warning: conversion of negative constant -4294967295 to unsigned type 'unsigned int', arg #1 [296] */
751.1Srillig	take_uint(-(4294967295));
761.1Srillig}
771.1Srillig
781.1Srilligvoid
791.1Srilligfold_compl(void)
801.1Srillig{
811.1Srillig	take_int(~(0));
821.1Srillig	take_int(~(2147483647));
831.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
841.1Srillig	take_int(~(2147483648));
851.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
861.1Srillig	take_int(~(4294967295));
871.1Srillig
881.16Srillig	/* expect+1: warning: conversion of negative constant -1 to unsigned type 'unsigned int', arg #1 [296] */
891.1Srillig	take_uint(~(0));
901.16Srillig	/* expect+1: warning: conversion of negative constant -2147483648 to unsigned type 'unsigned int', arg #1 [296] */
911.1Srillig	take_uint(~(2147483647));
921.16Srillig	/* expect+1: warning: conversion of negative constant -2147483649 to unsigned type 'unsigned int', arg #1 [296] */
931.1Srillig	take_uint(~(2147483648));
941.16Srillig	/* expect+1: warning: conversion of negative constant -4294967296 to unsigned type 'unsigned int', arg #1 [296] */
951.1Srillig	take_uint(~(4294967295));
961.1Srillig}
971.1Srillig
981.1Srilligvoid
991.1Srilligfold_mult(void)
1001.1Srillig{
1011.1Srillig	take_int(32767 * 65536);
1021.15Srillig	/* expect+1: warning: '32768 * 65536' overflows 'int' [141] */
1031.1Srillig	take_int(32768 * 65536);
1041.15Srillig	/* expect+1: warning: '65536 * 65536' overflows 'int' [141] */
1051.1Srillig	take_int(65536 * 65536);
1061.1Srillig
1071.1Srillig	take_uint(32767 * 65536U);
1081.1Srillig	take_uint(32768 * 65536U);
1091.15Srillig	/* expect+1: warning: '65536 * 65536' overflows 'unsigned int' [141] */
1101.1Srillig	take_uint(65536 * 65536U);
1111.1Srillig}
1121.1Srillig
1131.1Srilligvoid
1141.1Srilligfold_div(void)
1151.1Srillig{
1161.12Srillig	/* expect+1: error: division by 0 [139] */
1171.1Srillig	take_int(0 / 0);
1181.1Srillig
1191.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
1201.1Srillig	take_int(-2147483648 / -1);
1211.1Srillig}
1221.1Srillig
1231.1Srilligvoid
1241.1Srilligfold_mod(void)
1251.1Srillig{
1261.1Srillig	/* expect+1: error: modulus by 0 [140] */
1271.1Srillig	take_int(0 % 0);
1281.1Srillig	/* expect+1: error: modulus by 0 [140] */
1291.1Srillig	take_int(0 % 0U);
1301.1Srillig	/* expect+1: error: modulus by 0 [140] */
1311.1Srillig	take_int(0U % 0);
1321.1Srillig	/* expect+1: error: modulus by 0 [140] */
1331.1Srillig	take_int(0U % 0U);
1341.1Srillig
1351.1Srillig	take_int(-2147483648 % -1);
1361.1Srillig}
1371.1Srillig
1381.1Srilligvoid
1391.1Srilligfold_plus(void)
1401.1Srillig{
1411.15Srillig	/* expect+1: warning: '2147483647 + 1' overflows 'int' [141] */
1421.1Srillig	take_int(2147483647 + 1);
1431.1Srillig
1441.1Srillig	/* Assume two's complement, so no overflow. */
1451.1Srillig	take_int(-2147483647 + -1);
1461.1Srillig
1471.15Srillig	/* expect+1: warning: '-2147483647 + -2' overflows 'int' [141] */
1481.1Srillig	take_int(-2147483647 + -2);
1491.1Srillig
1501.1Srillig	/*
1511.1Srillig	 * No overflow since one of the operands is unsigned, therefore the
1521.1Srillig	 * other operand is converted to unsigned as well.
1531.1Srillig	 * See C99 6.3.1.8p1, paragraph 8 of 10.
1541.1Srillig	 */
1551.2Srillig	/* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */
1561.1Srillig	take_uint(2147483647 + 1U);
1571.2Srillig	/* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */
1581.1Srillig	take_uint(2147483647U + 1);
1591.1Srillig}
1601.1Srillig
1611.1Srilligvoid
1621.1Srilligfold_minus(void)
1631.1Srillig{
1641.15Srillig	/* expect+1: warning: '2147483647 - -1' overflows 'int' [141] */
1651.1Srillig	take_int(2147483647 - -1);
1661.1Srillig	/* Assume two's complement. */
1671.1Srillig	take_int(-2147483647 - 1);
1681.15Srillig	/* expect+1: warning: '-2147483647 - 2' overflows 'int' [141] */
1691.1Srillig	take_int(-2147483647 - 2);
1701.1Srillig
1711.1Srillig	take_int(0 - 2147483648);
1721.15Srillig	/* expect+1: warning: '0 - 2147483648' overflows 'unsigned int' [141] */
1731.1Srillig	take_uint(0 - 2147483648U);
1741.1Srillig}
1751.1Srillig
1761.1Srilligvoid
1771.1Srilligfold_shl(void)
1781.1Srillig{
1791.15Srillig	/* expect+1: warning: '16777216 << 24' overflows 'int' [141] */
1801.1Srillig	take_int(1 << 24 << 24);
1811.1Srillig
1821.15Srillig	/* expect+1: warning: '16777216 << 24' overflows 'unsigned int' [141] */
1831.1Srillig	take_uint(1U << 24 << 24);
1841.1Srillig
1851.1Srillig	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'unsigned int' [122] */
1861.1Srillig	take_uint(1U << 24 << 104);
1871.1Srillig}
1881.1Srillig
1891.1Srilligvoid
1901.1Srilligfold_shr(void)
1911.1Srillig{
1921.1Srillig	take_int(16777216 >> 24);
1931.1Srillig
1941.1Srillig	take_int(16777216 >> 25);
1951.1Srillig
1961.1Srillig	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'int' [122] */
1971.1Srillig	take_int(16777216 >> 104);
1981.1Srillig}
1991.1Srillig
2001.1Srilligvoid
2011.1Srilligfold_lt(void)
2021.1Srillig{
2031.1Srillig	take_bool(1 < 3);
2041.1Srillig	take_bool(3 < 1);
2051.1Srillig}
2061.1Srillig
2071.1Srilligvoid
2081.1Srilligfold_le(void)
2091.1Srillig{
2101.1Srillig	take_bool(1 <= 3);
2111.1Srillig	take_bool(3 <= 1);
2121.1Srillig}
2131.1Srillig
2141.1Srilligvoid
2151.1Srilligfold_ge(void)
2161.1Srillig{
2171.1Srillig	take_bool(1 >= 3);
2181.1Srillig	take_bool(3 >= 1);
2191.1Srillig}
2201.1Srillig
2211.1Srilligvoid
2221.1Srilligfold_gt(void)
2231.1Srillig{
2241.1Srillig	take_bool(1 > 3);
2251.1Srillig	take_bool(3 > 1);
2261.1Srillig}
2271.1Srillig
2281.1Srilligvoid
2291.1Srilligfold_eq(void)
2301.1Srillig{
2311.1Srillig	take_bool(1 == 3);
2321.1Srillig	take_bool(3 == 1);
2331.1Srillig}
2341.1Srillig
2351.1Srilligvoid
2361.1Srilligfold_ne(void)
2371.1Srillig{
2381.1Srillig	take_bool(1 != 3);
2391.1Srillig	take_bool(3 != 1);
2401.1Srillig}
2411.1Srillig
2421.1Srilligvoid
2431.1Srilligfold_bitand(void)
2441.1Srillig{
2451.1Srillig	take_bool(1 & 3);
2461.1Srillig	take_bool(3 & 1);
2471.1Srillig}
2481.1Srillig
2491.1Srilligvoid
2501.1Srilligfold_bitxor(void)
2511.1Srillig{
2521.1Srillig	take_bool(1 ^ 3);
2531.1Srillig	take_bool(3 ^ 1);
2541.1Srillig}
2551.1Srillig
2561.1Srilligvoid
2571.1Srilligfold_bitor(void)
2581.1Srillig{
2591.1Srillig	take_bool(1 | 3);
2601.1Srillig	take_bool(3 | 1);
2611.1Srillig}
2621.3Srillig
2631.3Srillig/*
2641.3Srillig * The following expression originated in vndcompress.c 1.29 from 2017-07-29,
2651.3Srillig * where line 310 contained a seemingly harmless compile-time assertion that
2661.3Srillig * expanded to a real monster expression.
2671.3Srillig *
2681.3Srillig * __CTASSERT(MUL_OK(uint64_t, MAX_N_BLOCKS, MAX_BLOCKSIZE));
2691.4Srillig *
2701.4Srillig * Before tree.c 1.345 from 2021-08-22, lint wrongly assumed that the result
2711.4Srillig * of all binary operators were the common arithmetic type, but that was
2721.4Srillig * wrong for the comparison operators.  The expression '1ULL < 2ULL' does not
2731.4Srillig * have type 'unsigned long long' but 'int' in default mode, or '_Bool' in
2741.4Srillig * strict bool mode.
2751.3Srillig */
2761.3Srilligstruct ctassert5_struct {
2771.3Srillig	unsigned int member:
2781.3Srillig	    0xfffffffeU
2791.3Srillig	    <=
2801.3Srillig		((1ULL << 63) + 1 < 1 ? ~(1ULL << 63) : ~0ULL) / 0xfffffe00U
2811.3Srillig		? 1
2821.3Srillig		: -1;
2831.3Srillig};
2841.7Srillig
2851.7Srillig/*
2861.7Srillig * Since Makefile.inc 1.21 from 2022-04-08 (which added -ftrapv) and before
2871.7Srillig * tree.c 1.436 from 2022-04-20, lint crashed with an integer overflow when
2881.9Srillig * calculating '-(uint64_t)INT64_MIN' in val_t.u.integer.
2891.7Srillig */
2901.7Srilligvoid
2911.7Srilligunary_minus_overflow(unsigned long long val)
2921.7Srillig{
2931.7Srillig	if (val > -(unsigned long long)(-0x7fffffffffffffffL - 1))
2941.7Srillig		return;
2951.7Srillig}
296