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