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