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 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 /* 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 57 void 58 fold_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 91 void 92 fold_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 117 void 118 fold_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 132 void 133 fold_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 145 void 146 fold_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 161 void 162 fold_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 184 void 185 fold_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 200 void 201 fold_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 214 void 215 fold_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 226 void 227 fold_lt(void) 228 { 229 take_bool(1 < 3); 230 take_bool(3 < 1); 231 } 232 233 void 234 fold_le(void) 235 { 236 take_bool(1 <= 3); 237 take_bool(3 <= 1); 238 } 239 240 void 241 fold_ge(void) 242 { 243 take_bool(1 >= 3); 244 take_bool(3 >= 1); 245 } 246 247 void 248 fold_gt(void) 249 { 250 take_bool(1 > 3); 251 take_bool(3 > 1); 252 } 253 254 void 255 fold_eq(void) 256 { 257 take_bool(1 == 3); 258 take_bool(3 == 1); 259 } 260 261 void 262 fold_ne(void) 263 { 264 take_bool(1 != 3); 265 take_bool(3 != 1); 266 } 267 268 void 269 fold_bitand(void) 270 { 271 take_bool(1 & 3); 272 take_bool(3 & 1); 273 } 274 275 void 276 fold_bitxor(void) 277 { 278 take_bool(1 ^ 3); 279 take_bool(3 ^ 1); 280 } 281 282 void 283 fold_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 */ 302 struct 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