expr_fold.c revision 1.10
11.10Srillig/* $NetBSD: expr_fold.c,v 1.10 2023/07/09 11:01:27 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.1Srillig /* expect+3: error: division by 0 [139] */ 1181.1Srillig /* XXX: The following message is redundant. */ 1191.10Srillig /* expect+1: warning: operator '/' produces integer overflow [141] */ 1201.1Srillig take_int(0 / 0); 1211.1Srillig 1221.1Srillig /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */ 1231.1Srillig take_int(-2147483648 / -1); 1241.1Srillig} 1251.1Srillig 1261.1Srilligvoid 1271.1Srilligfold_mod(void) 1281.1Srillig{ 1291.1Srillig /* expect+1: error: modulus by 0 [140] */ 1301.1Srillig take_int(0 % 0); 1311.1Srillig /* expect+1: error: modulus by 0 [140] */ 1321.1Srillig take_int(0 % 0U); 1331.1Srillig /* expect+1: error: modulus by 0 [140] */ 1341.1Srillig take_int(0U % 0); 1351.1Srillig /* expect+1: error: modulus by 0 [140] */ 1361.1Srillig take_int(0U % 0U); 1371.1Srillig 1381.1Srillig take_int(-2147483648 % -1); 1391.1Srillig} 1401.1Srillig 1411.1Srilligvoid 1421.1Srilligfold_plus(void) 1431.1Srillig{ 1441.10Srillig /* expect+1: warning: operator '+' produces integer overflow [141] */ 1451.1Srillig take_int(2147483647 + 1); 1461.1Srillig 1471.1Srillig /* Assume two's complement, so no overflow. */ 1481.1Srillig take_int(-2147483647 + -1); 1491.1Srillig 1501.10Srillig /* expect+1: warning: operator '+' produces integer overflow [141] */ 1511.1Srillig take_int(-2147483647 + -2); 1521.1Srillig 1531.1Srillig /* 1541.1Srillig * No overflow since one of the operands is unsigned, therefore the 1551.1Srillig * other operand is converted to unsigned as well. 1561.1Srillig * See C99 6.3.1.8p1, paragraph 8 of 10. 1571.1Srillig */ 1581.2Srillig /* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */ 1591.1Srillig take_uint(2147483647 + 1U); 1601.2Srillig /* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */ 1611.1Srillig take_uint(2147483647U + 1); 1621.1Srillig} 1631.1Srillig 1641.1Srilligvoid 1651.1Srilligfold_minus(void) 1661.1Srillig{ 1671.10Srillig /* expect+1: warning: operator '-' produces integer overflow [141] */ 1681.1Srillig take_int(2147483647 - -1); 1691.1Srillig /* Assume two's complement. */ 1701.1Srillig take_int(-2147483647 - 1); 1711.10Srillig /* expect+1: warning: operator '-' produces integer overflow [141] */ 1721.1Srillig take_int(-2147483647 - 2); 1731.1Srillig 1741.1Srillig take_int(0 - 2147483648); 1751.10Srillig /* expect+1: warning: operator '-' produces integer overflow [141] */ 1761.1Srillig take_uint(0 - 2147483648U); 1771.1Srillig} 1781.1Srillig 1791.1Srilligvoid 1801.1Srilligfold_shl(void) 1811.1Srillig{ 1821.10Srillig /* expect+1: warning: operator '<<' produces integer overflow [141] */ 1831.1Srillig take_int(1 << 24 << 24); 1841.1Srillig 1851.10Srillig /* expect+1: warning: operator '<<' produces integer overflow [141] */ 1861.1Srillig take_uint(1U << 24 << 24); 1871.1Srillig 1881.1Srillig /* FIXME: undefined behavior in 'fold' at 'uint64_t << 104'. */ 1891.1Srillig /* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'unsigned int' [122] */ 1901.1Srillig take_uint(1U << 24 << 104); 1911.1Srillig} 1921.1Srillig 1931.1Srilligvoid 1941.1Srilligfold_shr(void) 1951.1Srillig{ 1961.1Srillig take_int(16777216 >> 24); 1971.1Srillig 1981.1Srillig take_int(16777216 >> 25); 1991.1Srillig 2001.1Srillig /* FIXME: undefined behavior in 'fold' at 'uint64_t >> 104'. */ 2011.1Srillig /* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'int' [122] */ 2021.1Srillig take_int(16777216 >> 104); 2031.1Srillig} 2041.1Srillig 2051.1Srilligvoid 2061.1Srilligfold_lt(void) 2071.1Srillig{ 2081.1Srillig take_bool(1 < 3); 2091.1Srillig take_bool(3 < 1); 2101.1Srillig} 2111.1Srillig 2121.1Srilligvoid 2131.1Srilligfold_le(void) 2141.1Srillig{ 2151.1Srillig take_bool(1 <= 3); 2161.1Srillig take_bool(3 <= 1); 2171.1Srillig} 2181.1Srillig 2191.1Srilligvoid 2201.1Srilligfold_ge(void) 2211.1Srillig{ 2221.1Srillig take_bool(1 >= 3); 2231.1Srillig take_bool(3 >= 1); 2241.1Srillig} 2251.1Srillig 2261.1Srilligvoid 2271.1Srilligfold_gt(void) 2281.1Srillig{ 2291.1Srillig take_bool(1 > 3); 2301.1Srillig take_bool(3 > 1); 2311.1Srillig} 2321.1Srillig 2331.1Srilligvoid 2341.1Srilligfold_eq(void) 2351.1Srillig{ 2361.1Srillig take_bool(1 == 3); 2371.1Srillig take_bool(3 == 1); 2381.1Srillig} 2391.1Srillig 2401.1Srilligvoid 2411.1Srilligfold_ne(void) 2421.1Srillig{ 2431.1Srillig take_bool(1 != 3); 2441.1Srillig take_bool(3 != 1); 2451.1Srillig} 2461.1Srillig 2471.1Srilligvoid 2481.1Srilligfold_bitand(void) 2491.1Srillig{ 2501.1Srillig take_bool(1 & 3); 2511.1Srillig take_bool(3 & 1); 2521.1Srillig} 2531.1Srillig 2541.1Srilligvoid 2551.1Srilligfold_bitxor(void) 2561.1Srillig{ 2571.1Srillig take_bool(1 ^ 3); 2581.1Srillig take_bool(3 ^ 1); 2591.1Srillig} 2601.1Srillig 2611.1Srilligvoid 2621.1Srilligfold_bitor(void) 2631.1Srillig{ 2641.1Srillig take_bool(1 | 3); 2651.1Srillig take_bool(3 | 1); 2661.1Srillig} 2671.3Srillig 2681.3Srillig/* 2691.3Srillig * The following expression originated in vndcompress.c 1.29 from 2017-07-29, 2701.3Srillig * where line 310 contained a seemingly harmless compile-time assertion that 2711.3Srillig * expanded to a real monster expression. 2721.3Srillig * 2731.3Srillig * __CTASSERT(MUL_OK(uint64_t, MAX_N_BLOCKS, MAX_BLOCKSIZE)); 2741.4Srillig * 2751.4Srillig * Before tree.c 1.345 from 2021-08-22, lint wrongly assumed that the result 2761.4Srillig * of all binary operators were the common arithmetic type, but that was 2771.4Srillig * wrong for the comparison operators. The expression '1ULL < 2ULL' does not 2781.4Srillig * have type 'unsigned long long' but 'int' in default mode, or '_Bool' in 2791.4Srillig * strict bool mode. 2801.3Srillig */ 2811.3Srilligstruct ctassert5_struct { 2821.3Srillig unsigned int member: 2831.3Srillig /*CONSTCOND*/ 2841.3Srillig 0xfffffffeU 2851.3Srillig <= 2861.3Srillig ((1ULL << 63) + 1 < 1 ? ~(1ULL << 63) : ~0ULL) / 0xfffffe00U 2871.3Srillig ? 1 2881.3Srillig : -1; 2891.3Srillig}; 2901.7Srillig 2911.7Srillig/* 2921.7Srillig * Since Makefile.inc 1.21 from 2022-04-08 (which added -ftrapv) and before 2931.7Srillig * tree.c 1.436 from 2022-04-20, lint crashed with an integer overflow when 2941.9Srillig * calculating '-(uint64_t)INT64_MIN' in val_t.u.integer. 2951.7Srillig */ 2961.7Srilligvoid 2971.7Srilligunary_minus_overflow(unsigned long long val) 2981.7Srillig{ 2991.10Srillig /* expect+1: warning: operator '-' produces integer overflow [141] */ 3001.7Srillig if (val > -(unsigned long long)(-0x7fffffffffffffffL - 1)) 3011.7Srillig return; 3021.7Srillig} 303