aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-06-27 13:38:11 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-06-27 13:38:11 +0200
commit025a60e1e9bfa02be082a072967795fe34b9d85b (patch)
tree936e5fe319d736f4e67a03124ddaf8311f10a9b8
parentc0895afd99c8befd0d89580bfaa71bb532ba9c7f (diff)
Fix some bugs related to unsigned integers
-rw-r--r--src/codegen.c15
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);