expr_fold.c revision 1.5
1/* $NetBSD: expr_fold.c,v 1.5 2021/08/23 06:50:01 rillig Exp $ */ 2# 3 "expr_fold.c" 3 4/* 5 * Test folding of constant expressions. 6 */ 7 8/* lint1-extra-flags: -h */ 9 10/* 11 * On ILP32 platforms, the integer constant 2147483648 cannot be represented 12 * as 'int' or 'long', therefore it becomes 'long long'. This would 13 * influence the type names in the diagnostics. 14 */ 15/* lint1-only-if: lp64 */ 16 17void take_bool(_Bool); 18void take_int(int); 19void take_uint(unsigned int); 20 21/* 22 * C99 6.4.4.1p5 defines that decimal integer constants without suffix get 23 * one of the signed integer types. On the other hand, octal and hexadecimal 24 * constants get either a signed or unsigned type, whichever fits first. 25 */ 26 27void 28fold_uplus(void) 29{ 30 take_int(+(0)); 31 take_int(+(2147483647)); 32 /* XXX: one of these two messages is redundant */ 33 /* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */ 34 /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */ 35 take_int(+(2147483648)); 36 /* XXX: one of these two messages is redundant */ 37 /* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */ 38 /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */ 39 take_int(+(4294967295)); 40 41 take_uint(+(0)); 42 take_uint(+(2147483647)); 43 /* expect+1: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */ 44 take_uint(+(2147483648)); 45 /* expect+1: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */ 46 take_uint(+(4294967295)); 47 48 /* 49 * Hexadecimal constants and constants with the suffix 'U' get either 50 * a signed or an unsigned integer type, so no warning here. 51 */ 52 take_uint(+(2147483648U)); 53 take_uint(+(0x80000000)); 54 take_uint(+(0x80000000U)); 55} 56 57void 58fold_uminus(void) 59{ 60 take_int(-(0)); 61 take_int(-(2147483647)); 62 63 /* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */ 64 take_int(-(2147483648)); 65 66 /* The '-' is an operator, it is not part of the integer constant. */ 67 /* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */ 68 take_int(-2147483648); 69 70 /* expect+2: warning: integer overflow detected, op '+' [141] */ 71 /* expect+1: warning: integer overflow detected, op '-' [141] */ 72 take_int(-(2147483647 + 1)); 73 /* expect+1: warning: integer overflow detected, op '-' [141] */ 74 take_int(-(-2147483647 - 1)); 75 /* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */ 76 /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */ 77 take_int(-(4294967295)); 78 79 take_uint(-(0)); 80 /* expect+2: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 81 /* expect+1: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */ 82 take_uint(-(2147483647)); 83 /* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */ 84 /* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 85 take_uint(-(2147483648)); 86 /* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */ 87 /* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 88 take_uint(-(4294967295)); 89} 90 91void 92fold_compl(void) 93{ 94 take_int(~(0)); 95 take_int(~(2147483647)); 96 /* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */ 97 /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */ 98 take_int(~(2147483648)); 99 /* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */ 100 /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */ 101 take_int(~(4294967295)); 102 103 /* expect+2: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 104 /* expect+1: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */ 105 take_uint(~(0)); 106 /* expect+2: warning: argument #1 is converted from 'int' to 'unsigned int' due to prototype [259] */ 107 /* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 108 take_uint(~(2147483647)); 109 /* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */ 110 /* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 111 take_uint(~(2147483648)); 112 /* expect+2: warning: argument #1 is converted from 'long' to 'unsigned int' due to prototype [259] */ 113 /* expect+1: warning: conversion of negative constant to unsigned type, arg #1 [296] */ 114 take_uint(~(4294967295)); 115} 116 117void 118fold_mult(void) 119{ 120 take_int(32767 * 65536); 121 /* expect+1: warning: integer overflow detected, op '*' [141] */ 122 take_int(32768 * 65536); 123 /* expect+1: warning: integer overflow detected, op '*' [141] */ 124 take_int(65536 * 65536); 125 126 take_uint(32767 * 65536U); 127 take_uint(32768 * 65536U); 128 /* expect+1: warning: integer overflow detected, op '*' [141] */ 129 take_uint(65536 * 65536U); 130} 131 132void 133fold_div(void) 134{ 135 /* expect+3: error: division by 0 [139] */ 136 /* XXX: The following message is redundant. */ 137 /* expect+1: warning: integer overflow detected, op '/' [141] */ 138 take_int(0 / 0); 139 140 /* expect+2: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */ 141 /* expect+1: warning: conversion of 'long' to 'int' is out of range, arg #1 [295] */ 142 take_int(-2147483648 / -1); 143} 144 145void 146fold_mod(void) 147{ 148 /* expect+1: error: modulus by 0 [140] */ 149 take_int(0 % 0); 150 /* expect+1: error: modulus by 0 [140] */ 151 take_int(0 % 0U); 152 /* expect+1: error: modulus by 0 [140] */ 153 take_int(0U % 0); 154 /* expect+1: error: modulus by 0 [140] */ 155 take_int(0U % 0U); 156 157 /* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */ 158 take_int(-2147483648 % -1); 159} 160 161void 162fold_plus(void) 163{ 164 /* expect+1: warning: integer overflow detected, op '+' [141] */ 165 take_int(2147483647 + 1); 166 167 /* Assume two's complement, so no overflow. */ 168 take_int(-2147483647 + -1); 169 170 /* expect+1: warning: integer overflow detected, op '+' [141] */ 171 take_int(-2147483647 + -2); 172 173 /* 174 * No overflow since one of the operands is unsigned, therefore the 175 * other operand is converted to unsigned as well. 176 * See C99 6.3.1.8p1, paragraph 8 of 10. 177 */ 178 /* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */ 179 take_uint(2147483647 + 1U); 180 /* wrong integer overflow warning before tree.c 1.338 from 2021-08-19 */ 181 take_uint(2147483647U + 1); 182} 183 184void 185fold_minus(void) 186{ 187 /* expect+1: warning: integer overflow detected, op '-' [141] */ 188 take_int(2147483647 - -1); 189 /* Assume two's complement. */ 190 take_int(-2147483647 - 1); 191 /* expect+1: warning: integer overflow detected, op '-' [141] */ 192 take_int(-2147483647 - 2); 193 194 /* expect+1: warning: argument #1 is converted from 'long' to 'int' due to prototype [259] */ 195 take_int(0 - 2147483648); 196 /* expect+1: warning: integer overflow detected, op '-' [141] */ 197 take_uint(0 - 2147483648U); 198} 199 200void 201fold_shl(void) 202{ 203 /* expect+1: warning: integer overflow detected, op '<<' [141] */ 204 take_int(1 << 24 << 24); 205 206 /* expect+1: warning: integer overflow detected, op '<<' [141] */ 207 take_uint(1U << 24 << 24); 208 209 /* FIXME: undefined behavior in 'fold' at 'uint64_t << 104'. */ 210 /* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'unsigned int' [122] */ 211 take_uint(1U << 24 << 104); 212} 213 214void 215fold_shr(void) 216{ 217 take_int(16777216 >> 24); 218 219 take_int(16777216 >> 25); 220 221 /* FIXME: undefined behavior in 'fold' at 'uint64_t >> 104'. */ 222 /* expect+1: warning: shift amount 104 is greater than bit-size 32 of 'int' [122] */ 223 take_int(16777216 >> 104); 224} 225 226void 227fold_lt(void) 228{ 229 take_bool(1 < 3); 230 take_bool(3 < 1); 231} 232 233void 234fold_le(void) 235{ 236 take_bool(1 <= 3); 237 take_bool(3 <= 1); 238} 239 240void 241fold_ge(void) 242{ 243 take_bool(1 >= 3); 244 take_bool(3 >= 1); 245} 246 247void 248fold_gt(void) 249{ 250 take_bool(1 > 3); 251 take_bool(3 > 1); 252} 253 254void 255fold_eq(void) 256{ 257 take_bool(1 == 3); 258 take_bool(3 == 1); 259} 260 261void 262fold_ne(void) 263{ 264 take_bool(1 != 3); 265 take_bool(3 != 1); 266} 267 268void 269fold_bitand(void) 270{ 271 take_bool(1 & 3); 272 take_bool(3 & 1); 273} 274 275void 276fold_bitxor(void) 277{ 278 take_bool(1 ^ 3); 279 take_bool(3 ^ 1); 280} 281 282void 283fold_bitor(void) 284{ 285 take_bool(1 | 3); 286 take_bool(3 | 1); 287} 288 289/* 290 * The following expression originated in vndcompress.c 1.29 from 2017-07-29, 291 * where line 310 contained a seemingly harmless compile-time assertion that 292 * expanded to a real monster expression. 293 * 294 * __CTASSERT(MUL_OK(uint64_t, MAX_N_BLOCKS, MAX_BLOCKSIZE)); 295 * 296 * Before tree.c 1.345 from 2021-08-22, lint wrongly assumed that the result 297 * of all binary operators were the common arithmetic type, but that was 298 * wrong for the comparison operators. The expression '1ULL < 2ULL' does not 299 * have type 'unsigned long long' but 'int' in default mode, or '_Bool' in 300 * strict bool mode. 301 */ 302struct ctassert5_struct { 303 unsigned int member: 304 /*CONSTCOND*/ 305 0xfffffffeU 306 <= 307 ((1ULL << 63) + 1 < 1 ? ~(1ULL << 63) : ~0ULL) / 0xfffffe00U 308 ? 1 309 : -1; 310}; 311