diff options
author | Thomas Voss <mail@thomasvoss.com> | 2024-06-27 13:38:11 +0200 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2024-06-27 13:38:11 +0200 |
commit | 025a60e1e9bfa02be082a072967795fe34b9d85b (patch) | |
tree | 936e5fe319d736f4e67a03124ddaf8311f10a9b8 | |
parent | c0895afd99c8befd0d89580bfaa71bb532ba9c7f (diff) |
Fix some bugs related to unsigned integers
-rw-r--r-- | src/codegen.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/codegen.c b/src/codegen.c index 9e9e329..1286131 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -144,6 +144,10 @@ codegentypedexpr(struct cgctx ctx, idx_t i, type_t type, LLVMValueRef *outv) { /* If true, implies numeric constant */ if (MPQ_IS_INIT(ctx.folds[i]) && !type.isfloat) { + /* TODO: Move this kind of range checking to the constant folding stage? */ + if (!type.issigned && mpq_sgn(ctx.folds[i]) == -1) + err("Cannot convert negative value to unsigned type"); + mpz_ptr num, den; num = mpq_numref(ctx.folds[i]); den = mpq_denref(ctx.folds[i]); @@ -151,16 +155,15 @@ codegentypedexpr(struct cgctx ctx, idx_t i, type_t type, LLVMValueRef *outv) err("Invalid integer"); int cmp; - if ((sizeof(unsigned long) >= 8 && type.size <= 8) - || type.size <= 4) - { + assert(type.size != 0); + /* TODO: Can we make the first branch work when the type has the + same size as an unsigned long? */ + if (type.size < sizeof(unsigned long)) { unsigned long x = 1UL << (type.size * 8 - type.issigned); cmp = mpz_cmp_ui(num, x - 1); } else { mpz_t x; - mp_bitcnt_t bits = type.size * 8; - if (type.issigned) - bits--; + mp_bitcnt_t bits = type.size * 8 - type.issigned; mpz_init_set_ui(x, 1); mpz_mul_2exp(x, x, bits); mpz_sub_ui(x, x, 1); |