bound constant arguments before range-checking them

This commit is contained in:
kalsprite
2026-08-11 18:08:32 -07:00
parent 549bedcff9
commit 882be52d66

View File

@@ -1691,6 +1691,11 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
return false;
}
// convert constant from BigInt to a type before `exact_value_to_i64`
convert_to_typed(c, &y, t_int);
if (y.mode == Addressing_Invalid) {
return false;
}
n = exact_value_to_u64(y.value);
}
@@ -1936,6 +1941,11 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
error(n.expr, "'%.*s' expected a constant integer divisible by the count of the #simd vector", LIT(builtin_name));
return false;
}
// convert constant from BigInt to a type before `exact_value_to_i64`; here it also sets the return arity
convert_to_typed(c, &n, t_int);
if (n.mode == Addressing_Invalid) {
return false;
}
i64 divisor = exact_value_to_i64(n.value);
if (divisor < 1 || divisor > max_count || (max_count % divisor != 0)) {
error(n.expr, "'%.*s' expected a constant integer divisible by the count of the #simd vector , got %lld, which must have been divisible by %lld", LIT(builtin_name), cast(long long)divisor, cast(long long)max_count);
@@ -1972,6 +1982,11 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
gb_string_free(xs);
return false;
}
// convert constant from BigInt to a type before `exact_value_to_i64`
convert_to_typed(c, x+i, t_int);
if (x[i].mode == Addressing_Invalid) {
return false;
}
i64 val = exact_value_to_i64(x[i].value);
if (val < 0 || val > 3) {
error(x[i].expr, "'%.*s' expected a constant integer in the range 0..<4, got %lld", LIT(builtin_name), cast(long long)val);
@@ -6016,6 +6031,12 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
return false;
}
// convert constant from BigInt to a type before `exact_value_to_i64`
convert_to_typed(c, &len, t_int);
if (len.mode == Addressing_Invalid) {
return false;
}
if (len.mode == Addressing_Constant) {
i64 n = exact_value_to_i64(len.value);
if (n < 0) {
@@ -6058,6 +6079,12 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
return false;
}
// convert constant from BigInt to a type before `exact_value_to_i64`
convert_to_typed(c, &len, t_int);
if (len.mode == Addressing_Invalid) {
return false;
}
if (len.mode == Addressing_Constant) {
i64 n = exact_value_to_i64(len.value);
if (n < 0) {
@@ -6586,6 +6613,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
error(z.expr, "Expected a constant integer for the scale in '%.*s'", LIT(builtin_name));
return false;
}
// convert constant from BigInt to a type before `exact_value_to_i64`
convert_to_typed(c, &z, t_int);
if (z.mode == Addressing_Invalid) {
return false;
}
i64 n = exact_value_to_i64(z.value);
if (n <= 0) {
error(z.expr, "Scale parameter in '%.*s' must be positive, got %lld", LIT(builtin_name), n);
@@ -6713,6 +6745,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
error(y.expr, "Second argument to '%.*s' representing the locality must be an integer in the range 0..=3", LIT(builtin_name));
return false;
}
// convert constant from BigInt to a type before `exact_value_to_i64`
convert_to_typed(c, &y, t_int);
if (y.mode == Addressing_Invalid) {
return false;
}
i64 locality = exact_value_to_i64(y.value);
if (!(0 <= locality && locality <= 3)) {
error(y.expr, "Second argument to '%.*s' representing the locality must be an integer in the range 0..=3", LIT(builtin_name));
@@ -7754,6 +7791,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
return false;
}
// convert constant from BigInt to a type before `exact_value_to_i64`
convert_to_typed(c, &op, t_int);
if (op.mode == Addressing_Invalid) {
return false;
}
i64 index = exact_value_to_i64(op.value);
if (index < 0) {
error(op.expr, "Expected a non-negative integer for the index of procedure parameter value, got %lld", cast(long long)index);
@@ -7813,6 +7855,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
return false;
}
// convert constant from BigInt to a type before `exact_value_to_i64`
convert_to_typed(c, &op, t_int);
if (op.mode == Addressing_Invalid) {
return false;
}
i64 index = exact_value_to_i64(op.value);
if (index < 0) {
error(op.expr, "Expected a non-negative integer for the index of procedure parameter value, got %lld", cast(long long)index);
@@ -7907,6 +7954,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
return false;
}
// convert constant from BigInt to a type before `exact_value_to_i64`
convert_to_typed(c, &op, t_int);
if (op.mode == Addressing_Invalid) {
return false;
}
i64 index = exact_value_to_i64(op.value);
if (index < 0) {
error(op.expr, "Expected a non-negative integer for the index of record parameter value, got %lld", cast(long long)index);