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