expr_fold.c revision 1.15
11.15Srillig/* $NetBSD: expr_fold.c,v 1.15 2024/03/10 19:45:14 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.6Srillig /* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 711.1Srillig take_uint(-(2147483647)); 721.1Srillig /* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 731.1Srillig take_uint(-(2147483648)); 741.1Srillig /* expect+1: warning: conversion of negative constant to unsigned type, 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.6Srillig /* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 891.1Srillig take_uint(~(0)); 901.1Srillig /* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 911.1Srillig take_uint(~(2147483647)); 921.1Srillig /* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 931.1Srillig take_uint(~(2147483648)); 941.1Srillig /* expect+1: warning: conversion of negative constant to unsigned type, 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 /*CONSTCOND*/ 2791.3Srillig 0xfffffffeU 2801.3Srillig <= 2811.3Srillig ((1ULL << 63) + 1 < 1 ? ~(1ULL << 63) : ~0ULL) / 0xfffffe00U 2821.3Srillig ? 1 2831.3Srillig : -1; 2841.3Srillig}; 2851.7Srillig 2861.7Srillig/* 2871.7Srillig * Since Makefile.inc 1.21 from 2022-04-08 (which added -ftrapv) and before 2881.7Srillig * tree.c 1.436 from 2022-04-20, lint crashed with an integer overflow when 2891.9Srillig * calculating '-(uint64_t)INT64_MIN' in val_t.u.integer. 2901.7Srillig */ 2911.7Srilligvoid 2921.7Srilligunary_minus_overflow(unsigned long long val) 2931.7Srillig{ 2941.7Srillig if (val > -(unsigned long long)(-0x7fffffffffffffffL - 1)) 2951.7Srillig return; 2961.7Srillig} 297