expr_fold.c revision 1.5
11.5Srillig/*	$NetBSD: expr_fold.c,v 1.5 2021/08/23 06:50:01 rillig Exp $	*/
21.1Srillig# 3 "expr_fold.c"
31.1Srillig
41.1Srillig/*
51.1Srillig * Test folding of constant expressions.
61.1Srillig */
71.1Srillig
81.1Srillig/* lint1-extra-flags: -h */
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	/* XXX: one of these two messages is redundant */
331.1Srillig	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
341.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
351.1Srillig	take_int(+(2147483648));
361.1Srillig	/* XXX: one of these two messages is redundant */
371.1Srillig	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
381.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
391.1Srillig	take_int(+(4294967295));
401.1Srillig
411.1Srillig	take_uint(+(0));
421.1Srillig	take_uint(+(2147483647));
431.1Srillig	/* expect+1: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
441.1Srillig	take_uint(+(2147483648));
451.1Srillig	/* expect+1: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
461.1Srillig	take_uint(+(4294967295));
471.1Srillig
481.1Srillig	/*
491.1Srillig	 * Hexadecimal constants and constants with the suffix 'U' get either
501.1Srillig	 * a signed or an unsigned integer type, so no warning here.
511.1Srillig	 */
521.1Srillig	take_uint(+(2147483648U));
531.1Srillig	take_uint(+(0x80000000));
541.1Srillig	take_uint(+(0x80000000U));
551.1Srillig}
561.1Srillig
571.1Srilligvoid
581.1Srilligfold_uminus(void)
591.1Srillig{
601.1Srillig	take_int(-(0));
611.1Srillig	take_int(-(2147483647));
621.1Srillig
631.1Srillig	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
641.1Srillig	take_int(-(2147483648));
651.1Srillig
661.1Srillig	/* The '-' is an operator, it is not part of the integer constant. */
671.1Srillig	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
681.1Srillig	take_int(-2147483648);
691.1Srillig
701.5Srillig	/* expect+2: warning: integer overflow detected, op '+' [141] */
711.5Srillig	/* expect+1: warning: integer overflow detected, op '-' [141] */
721.1Srillig	take_int(-(2147483647 + 1));
731.5Srillig	/* expect+1: warning: integer overflow detected, op '-' [141] */
741.1Srillig	take_int(-(-2147483647 - 1));
751.1Srillig	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
761.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
771.1Srillig	take_int(-(4294967295));
781.1Srillig
791.1Srillig	take_uint(-(0));
801.1Srillig	/* expect+2: warning: conversion of negative constant to unsigned type, arg #1 [296] */
811.1Srillig	/* expect+1: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */
821.1Srillig	take_uint(-(2147483647));
831.1Srillig	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
841.1Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
851.1Srillig	take_uint(-(2147483648));
861.1Srillig	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
871.1Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
881.1Srillig	take_uint(-(4294967295));
891.1Srillig}
901.1Srillig
911.1Srilligvoid
921.1Srilligfold_compl(void)
931.1Srillig{
941.1Srillig	take_int(~(0));
951.1Srillig	take_int(~(2147483647));
961.1Srillig	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
971.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
981.1Srillig	take_int(~(2147483648));
991.1Srillig	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
1001.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
1011.1Srillig	take_int(~(4294967295));
1021.1Srillig
1031.1Srillig	/* expect+2: warning: conversion of negative constant to unsigned type, arg #1 [296] */
1041.1Srillig	/* expect+1: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */
1051.1Srillig	take_uint(~(0));
1061.1Srillig	/* expect+2: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */
1071.1Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
1081.1Srillig	take_uint(~(2147483647));
1091.1Srillig	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
1101.1Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
1111.1Srillig	take_uint(~(2147483648));
1121.1Srillig	/* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */
1131.1Srillig	/* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */
1141.1Srillig	take_uint(~(4294967295));
1151.1Srillig}
1161.1Srillig
1171.1Srilligvoid
1181.1Srilligfold_mult(void)
1191.1Srillig{
1201.1Srillig	take_int(32767 * 65536);
1211.5Srillig	/* expect+1: warning: integer overflow detected, op '*' [141] */
1221.1Srillig	take_int(32768 * 65536);
1231.5Srillig	/* expect+1: warning: integer overflow detected, op '*' [141] */
1241.1Srillig	take_int(65536 * 65536);
1251.1Srillig
1261.1Srillig	take_uint(32767 * 65536U);
1271.1Srillig	take_uint(32768 * 65536U);
1281.5Srillig	/* expect+1: warning: integer overflow detected, op '*' [141] */
1291.1Srillig	take_uint(65536 * 65536U);
1301.1Srillig}
1311.1Srillig
1321.1Srilligvoid
1331.1Srilligfold_div(void)
1341.1Srillig{
1351.1Srillig	/* expect+3: error: division by 0 [139] */
1361.1Srillig	/* XXX: The following message is redundant. */
1371.5Srillig	/* expect+1: warning: integer overflow detected, op '/' [141] */
1381.1Srillig	take_int(0 / 0);
1391.1Srillig
1401.1Srillig	/* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
1411.1Srillig	/* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */
1421.1Srillig	take_int(-2147483648 / -1);
1431.1Srillig}
1441.1Srillig
1451.1Srilligvoid
1461.1Srilligfold_mod(void)
1471.1Srillig{
1481.1Srillig	/* expect+1: error: modulus by 0 [140] */
1491.1Srillig	take_int(0 % 0);
1501.1Srillig	/* expect+1: error: modulus by 0 [140] */
1511.1Srillig	take_int(0 % 0U);
1521.1Srillig	/* expect+1: error: modulus by 0 [140] */
1531.1Srillig	take_int(0U % 0);
1541.1Srillig	/* expect+1: error: modulus by 0 [140] */
1551.1Srillig	take_int(0U % 0U);
1561.1Srillig
1571.1Srillig	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
1581.1Srillig	take_int(-2147483648 % -1);
1591.1Srillig}
1601.1Srillig
1611.1Srilligvoid
1621.1Srilligfold_plus(void)
1631.1Srillig{
1641.5Srillig	/* expect+1: warning: integer overflow detected, op '+' [141] */
1651.1Srillig	take_int(2147483647 + 1);
1661.1Srillig
1671.1Srillig	/* Assume two's complement, so no overflow. */
1681.1Srillig	take_int(-2147483647 + -1);
1691.1Srillig
1701.5Srillig	/* expect+1: warning: integer overflow detected, op '+' [141] */
1711.1Srillig	take_int(-2147483647 + -2);
1721.1Srillig
1731.1Srillig	/*
1741.1Srillig	 * No overflow since one of the operands is unsigned, therefore the
1751.1Srillig	 * other operand is converted to unsigned as well.
1761.1Srillig	 * See C99 6.3.1.8p1, paragraph 8 of 10.
1771.1Srillig	 */
1781.2Srillig	/* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */
1791.1Srillig	take_uint(2147483647 + 1U);
1801.2Srillig	/* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */
1811.1Srillig	take_uint(2147483647U + 1);
1821.1Srillig}
1831.1Srillig
1841.1Srilligvoid
1851.1Srilligfold_minus(void)
1861.1Srillig{
1871.5Srillig	/* expect+1: warning: integer overflow detected, op '-' [141] */
1881.1Srillig	take_int(2147483647 - -1);
1891.1Srillig	/* Assume two's complement. */
1901.1Srillig	take_int(-2147483647 - 1);
1911.5Srillig	/* expect+1: warning: integer overflow detected, op '-' [141] */
1921.1Srillig	take_int(-2147483647 - 2);
1931.1Srillig
1941.1Srillig	/* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */
1951.1Srillig	take_int(0 - 2147483648);
1961.5Srillig	/* expect+1: warning: integer overflow detected, op '-' [141] */
1971.1Srillig	take_uint(0 - 2147483648U);
1981.1Srillig}
1991.1Srillig
2001.1Srilligvoid
2011.1Srilligfold_shl(void)
2021.1Srillig{
2031.5Srillig	/* expect+1: warning: integer overflow detected, op '<<' [141] */
2041.1Srillig	take_int(1 << 24 << 24);
2051.1Srillig
2061.5Srillig	/* expect+1: warning: integer overflow detected, op '<<' [141] */
2071.1Srillig	take_uint(1U << 24 << 24);
2081.1Srillig
2091.1Srillig	/* FIXME: undefined behavior in 'fold' at 'uint64_t << 104'. */
2101.1Srillig	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'unsigned int' [122] */
2111.1Srillig	take_uint(1U << 24 << 104);
2121.1Srillig}
2131.1Srillig
2141.1Srilligvoid
2151.1Srilligfold_shr(void)
2161.1Srillig{
2171.1Srillig	take_int(16777216 >> 24);
2181.1Srillig
2191.1Srillig	take_int(16777216 >> 25);
2201.1Srillig
2211.1Srillig	/* FIXME: undefined behavior in 'fold' at 'uint64_t >> 104'. */
2221.1Srillig	/* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'int' [122] */
2231.1Srillig	take_int(16777216 >> 104);
2241.1Srillig}
2251.1Srillig
2261.1Srilligvoid
2271.1Srilligfold_lt(void)
2281.1Srillig{
2291.1Srillig	take_bool(1 < 3);
2301.1Srillig	take_bool(3 < 1);
2311.1Srillig}
2321.1Srillig
2331.1Srilligvoid
2341.1Srilligfold_le(void)
2351.1Srillig{
2361.1Srillig	take_bool(1 <= 3);
2371.1Srillig	take_bool(3 <= 1);
2381.1Srillig}
2391.1Srillig
2401.1Srilligvoid
2411.1Srilligfold_ge(void)
2421.1Srillig{
2431.1Srillig	take_bool(1 >= 3);
2441.1Srillig	take_bool(3 >= 1);
2451.1Srillig}
2461.1Srillig
2471.1Srilligvoid
2481.1Srilligfold_gt(void)
2491.1Srillig{
2501.1Srillig	take_bool(1 > 3);
2511.1Srillig	take_bool(3 > 1);
2521.1Srillig}
2531.1Srillig
2541.1Srilligvoid
2551.1Srilligfold_eq(void)
2561.1Srillig{
2571.1Srillig	take_bool(1 == 3);
2581.1Srillig	take_bool(3 == 1);
2591.1Srillig}
2601.1Srillig
2611.1Srilligvoid
2621.1Srilligfold_ne(void)
2631.1Srillig{
2641.1Srillig	take_bool(1 != 3);
2651.1Srillig	take_bool(3 != 1);
2661.1Srillig}
2671.1Srillig
2681.1Srilligvoid
2691.1Srilligfold_bitand(void)
2701.1Srillig{
2711.1Srillig	take_bool(1 & 3);
2721.1Srillig	take_bool(3 & 1);
2731.1Srillig}
2741.1Srillig
2751.1Srilligvoid
2761.1Srilligfold_bitxor(void)
2771.1Srillig{
2781.1Srillig	take_bool(1 ^ 3);
2791.1Srillig	take_bool(3 ^ 1);
2801.1Srillig}
2811.1Srillig
2821.1Srilligvoid
2831.1Srilligfold_bitor(void)
2841.1Srillig{
2851.1Srillig	take_bool(1 | 3);
2861.1Srillig	take_bool(3 | 1);
2871.1Srillig}
2881.3Srillig
2891.3Srillig/*
2901.3Srillig * The following expression originated in vndcompress.c 1.29 from 2017-07-29,
2911.3Srillig * where line 310 contained a seemingly harmless compile-time assertion that
2921.3Srillig * expanded to a real monster expression.
2931.3Srillig *
2941.3Srillig * __CTASSERT(MUL_OK(uint64_t, MAX_N_BLOCKS, MAX_BLOCKSIZE));
2951.4Srillig *
2961.4Srillig * Before tree.c 1.345 from 2021-08-22, lint wrongly assumed that the result
2971.4Srillig * of all binary operators were the common arithmetic type, but that was
2981.4Srillig * wrong for the comparison operators.  The expression '1ULL < 2ULL' does not
2991.4Srillig * have type 'unsigned long long' but 'int' in default mode, or '_Bool' in
3001.4Srillig * strict bool mode.
3011.3Srillig */
3021.3Srilligstruct ctassert5_struct {
3031.3Srillig	unsigned int member:
3041.3Srillig	    /*CONSTCOND*/
3051.3Srillig	    0xfffffffeU
3061.3Srillig	    <=
3071.3Srillig		((1ULL << 63) + 1 < 1 ? ~(1ULL << 63) : ~0ULL) / 0xfffffe00U
3081.3Srillig		? 1
3091.3Srillig		: -1;
3101.3Srillig};
311