expr_fold.c revision 1.12
11.12Srillig/*	$NetBSD: expr_fold.c,v 1.12 2024/03/09 23:55:11 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.10Srillig	/* expect+2: warning: operator '+' produces integer overflow [141] */
631.10Srillig	/* expect+1: warning: operator '-' produces integer overflow [141] */
641.1Srillig	take_int(-(2147483647 + 1));
651.10Srillig	/* expect+1: warning: operator '-' produces integer overflow [141] */
661.1Srillig	take_int(-(-2147483647 - 1));
671.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
681.1Srillig	take_int(-(4294967295));
691.1Srillig
701.1Srillig	take_uint(-(0));
711.6Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
721.1Srillig	take_uint(-(2147483647));
731.1Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
741.1Srillig	take_uint(-(2147483648));
751.1Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
761.1Srillig	take_uint(-(4294967295));
771.1Srillig}
781.1Srillig
791.1Srilligvoid
801.1Srilligfold_compl(void)
811.1Srillig{
821.1Srillig	take_int(~(0));
831.1Srillig	take_int(~(2147483647));
841.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
851.1Srillig	take_int(~(2147483648));
861.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
871.1Srillig	take_int(~(4294967295));
881.1Srillig
891.6Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
901.1Srillig	take_uint(~(0));
911.1Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
921.1Srillig	take_uint(~(2147483647));
931.1Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
941.1Srillig	take_uint(~(2147483648));
951.1Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
961.1Srillig	take_uint(~(4294967295));
971.1Srillig}
981.1Srillig
991.1Srilligvoid
1001.1Srilligfold_mult(void)
1011.1Srillig{
1021.1Srillig	take_int(32767 * 65536);
1031.10Srillig	/* expect+1: warning: operator '*' produces integer overflow [141] */
1041.1Srillig	take_int(32768 * 65536);
1051.10Srillig	/* expect+1: warning: operator '*' produces integer overflow [141] */
1061.1Srillig	take_int(65536 * 65536);
1071.1Srillig
1081.1Srillig	take_uint(32767 * 65536U);
1091.1Srillig	take_uint(32768 * 65536U);
1101.10Srillig	/* expect+1: warning: operator '*' produces integer overflow [141] */
1111.1Srillig	take_uint(65536 * 65536U);
1121.1Srillig}
1131.1Srillig
1141.1Srilligvoid
1151.1Srilligfold_div(void)
1161.1Srillig{
1171.12Srillig	/* expect+1: error: division by 0 [139] */
1181.1Srillig	take_int(0 / 0);
1191.1Srillig
1201.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
1211.1Srillig	take_int(-2147483648 / -1);
1221.1Srillig}
1231.1Srillig
1241.1Srilligvoid
1251.1Srilligfold_mod(void)
1261.1Srillig{
1271.1Srillig	/* expect+1: error: modulus by 0 [140] */
1281.1Srillig	take_int(0 % 0);
1291.1Srillig	/* expect+1: error: modulus by 0 [140] */
1301.1Srillig	take_int(0 % 0U);
1311.1Srillig	/* expect+1: error: modulus by 0 [140] */
1321.1Srillig	take_int(0U % 0);
1331.1Srillig	/* expect+1: error: modulus by 0 [140] */
1341.1Srillig	take_int(0U % 0U);
1351.1Srillig
1361.1Srillig	take_int(-2147483648 % -1);
1371.1Srillig}
1381.1Srillig
1391.1Srilligvoid
1401.1Srilligfold_plus(void)
1411.1Srillig{
1421.10Srillig	/* expect+1: warning: operator '+' produces integer overflow [141] */
1431.1Srillig	take_int(2147483647 + 1);
1441.1Srillig
1451.1Srillig	/* Assume two's complement, so no overflow. */
1461.1Srillig	take_int(-2147483647 + -1);
1471.1Srillig
1481.10Srillig	/* expect+1: warning: operator '+' produces integer overflow [141] */
1491.1Srillig	take_int(-2147483647 + -2);
1501.1Srillig
1511.1Srillig	/*
1521.1Srillig	 * No overflow since one of the operands is unsigned, therefore the
1531.1Srillig	 * other operand is converted to unsigned as well.
1541.1Srillig	 * See C99 6.3.1.8p1, paragraph 8 of 10.
1551.1Srillig	 */
1561.2Srillig	/* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */
1571.1Srillig	take_uint(2147483647 + 1U);
1581.2Srillig	/* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */
1591.1Srillig	take_uint(2147483647U + 1);
1601.1Srillig}
1611.1Srillig
1621.1Srilligvoid
1631.1Srilligfold_minus(void)
1641.1Srillig{
1651.10Srillig	/* expect+1: warning: operator '-' produces integer overflow [141] */
1661.1Srillig	take_int(2147483647 - -1);
1671.1Srillig	/* Assume two's complement. */
1681.1Srillig	take_int(-2147483647 - 1);
1691.10Srillig	/* expect+1: warning: operator '-' produces integer overflow [141] */
1701.1Srillig	take_int(-2147483647 - 2);
1711.1Srillig
1721.1Srillig	take_int(0 - 2147483648);
1731.10Srillig	/* expect+1: warning: operator '-' produces integer overflow [141] */
1741.1Srillig	take_uint(0 - 2147483648U);
1751.1Srillig}
1761.1Srillig
1771.1Srilligvoid
1781.1Srilligfold_shl(void)
1791.1Srillig{
1801.10Srillig	/* expect+1: warning: operator '<<' produces integer overflow [141] */
1811.1Srillig	take_int(1 << 24 << 24);
1821.1Srillig
1831.10Srillig	/* expect+1: warning: operator '<<' produces integer overflow [141] */
1841.1Srillig	take_uint(1U << 24 << 24);
1851.1Srillig
1861.1Srillig	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'unsigned int' [122] */
1871.1Srillig	take_uint(1U << 24 << 104);
1881.1Srillig}
1891.1Srillig
1901.1Srilligvoid
1911.1Srilligfold_shr(void)
1921.1Srillig{
1931.1Srillig	take_int(16777216 >> 24);
1941.1Srillig
1951.1Srillig	take_int(16777216 >> 25);
1961.1Srillig
1971.1Srillig	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'int' [122] */
1981.1Srillig	take_int(16777216 >> 104);
1991.1Srillig}
2001.1Srillig
2011.1Srilligvoid
2021.1Srilligfold_lt(void)
2031.1Srillig{
2041.1Srillig	take_bool(1 < 3);
2051.1Srillig	take_bool(3 < 1);
2061.1Srillig}
2071.1Srillig
2081.1Srilligvoid
2091.1Srilligfold_le(void)
2101.1Srillig{
2111.1Srillig	take_bool(1 <= 3);
2121.1Srillig	take_bool(3 <= 1);
2131.1Srillig}
2141.1Srillig
2151.1Srilligvoid
2161.1Srilligfold_ge(void)
2171.1Srillig{
2181.1Srillig	take_bool(1 >= 3);
2191.1Srillig	take_bool(3 >= 1);
2201.1Srillig}
2211.1Srillig
2221.1Srilligvoid
2231.1Srilligfold_gt(void)
2241.1Srillig{
2251.1Srillig	take_bool(1 > 3);
2261.1Srillig	take_bool(3 > 1);
2271.1Srillig}
2281.1Srillig
2291.1Srilligvoid
2301.1Srilligfold_eq(void)
2311.1Srillig{
2321.1Srillig	take_bool(1 == 3);
2331.1Srillig	take_bool(3 == 1);
2341.1Srillig}
2351.1Srillig
2361.1Srilligvoid
2371.1Srilligfold_ne(void)
2381.1Srillig{
2391.1Srillig	take_bool(1 != 3);
2401.1Srillig	take_bool(3 != 1);
2411.1Srillig}
2421.1Srillig
2431.1Srilligvoid
2441.1Srilligfold_bitand(void)
2451.1Srillig{
2461.1Srillig	take_bool(1 & 3);
2471.1Srillig	take_bool(3 & 1);
2481.1Srillig}
2491.1Srillig
2501.1Srilligvoid
2511.1Srilligfold_bitxor(void)
2521.1Srillig{
2531.1Srillig	take_bool(1 ^ 3);
2541.1Srillig	take_bool(3 ^ 1);
2551.1Srillig}
2561.1Srillig
2571.1Srilligvoid
2581.1Srilligfold_bitor(void)
2591.1Srillig{
2601.1Srillig	take_bool(1 | 3);
2611.1Srillig	take_bool(3 | 1);
2621.1Srillig}
2631.3Srillig
2641.3Srillig/*
2651.3Srillig * The following expression originated in vndcompress.c 1.29 from 2017-07-29,
2661.3Srillig * where line 310 contained a seemingly harmless compile-time assertion that
2671.3Srillig * expanded to a real monster expression.
2681.3Srillig *
2691.3Srillig * __CTASSERT(MUL_OK(uint64_t, MAX_N_BLOCKS, MAX_BLOCKSIZE));
2701.4Srillig *
2711.4Srillig * Before tree.c 1.345 from 2021-08-22, lint wrongly assumed that the result
2721.4Srillig * of all binary operators were the common arithmetic type, but that was
2731.4Srillig * wrong for the comparison operators.  The expression '1ULL < 2ULL' does not
2741.4Srillig * have type 'unsigned long long' but 'int' in default mode, or '_Bool' in
2751.4Srillig * strict bool mode.
2761.3Srillig */
2771.3Srilligstruct ctassert5_struct {
2781.3Srillig	unsigned int member:
2791.3Srillig	    /*CONSTCOND*/
2801.3Srillig	    0xfffffffeU
2811.3Srillig	    <=
2821.3Srillig		((1ULL << 63) + 1 < 1 ? ~(1ULL << 63) : ~0ULL) / 0xfffffe00U
2831.3Srillig		? 1
2841.3Srillig		: -1;
2851.3Srillig};
2861.7Srillig
2871.7Srillig/*
2881.7Srillig * Since Makefile.inc 1.21 from 2022-04-08 (which added -ftrapv) and before
2891.7Srillig * tree.c 1.436 from 2022-04-20, lint crashed with an integer overflow when
2901.9Srillig * calculating '-(uint64_t)INT64_MIN' in val_t.u.integer.
2911.7Srillig */
2921.7Srilligvoid
2931.7Srilligunary_minus_overflow(unsigned long long val)
2941.7Srillig{
2951.10Srillig	/* expect+1: warning: operator '-' produces integer overflow [141] */
2961.7Srillig	if (val > -(unsigned long long)(-0x7fffffffffffffffL - 1))
2971.7Srillig		return;
2981.7Srillig}
299