Merge pull request #7310 from kalsprite/matrix_mul_limit

matrix: enforce the element limit on multiplication and on overflowing dimensions
This commit is contained in:
gingerBill
2026-08-12 13:22:39 +02:00
committed by GitHub
2 changed files with 29 additions and 4 deletions

View File

@@ -4268,8 +4268,22 @@ gb_internal void check_binary_matrix(CheckerContext *c, Token const &op, Operand
x->type = y->type;
}
} else {
// the result takes its rows from one operand and its columns from the other,
// so it can be larger than either. Each dimension is at least
// MATRIX_ELEMENT_COUNT_MIN, so testing them first keeps the product in range.
i64 row_count = xt->Matrix.row_count;
i64 column_count = yt->Matrix.column_count;
if (row_count > MATRIX_ELEMENT_COUNT_MAX ||
column_count > MATRIX_ELEMENT_COUNT_MAX ||
row_count*column_count > MATRIX_ELEMENT_COUNT_MAX) {
error(x->expr, "Matrix multiplication result exceeds the maximum matrix element count, got %lld, expected a maximum of %d", cast(long long)(row_count*column_count), MATRIX_ELEMENT_COUNT_MAX);
x->mode = Addressing_Invalid;
x->type = t_invalid;
return;
}
bool is_row_major = xt->Matrix.is_row_major && yt->Matrix.is_row_major;
x->type = alloc_type_matrix(xt->Matrix.elem, xt->Matrix.row_count, yt->Matrix.column_count, nullptr, nullptr, is_row_major);
x->type = alloc_type_matrix(xt->Matrix.elem, row_count, column_count, nullptr, nullptr, is_row_major);
}
goto matrix_success;
} else if (yt->kind == Type_Array) {

View File

@@ -3131,9 +3131,20 @@ gb_internal void check_matrix_type(CheckerContext *ctx, Type **type, Ast *node)
}
}
if ((generic_row == nullptr && generic_column == nullptr) && row_count*column_count > MATRIX_ELEMENT_COUNT_MAX) {
i64 element_count = row_count*column_count;
error(node, "Matrix types are limited to a maximum of %d elements, got %lld", MATRIX_ELEMENT_COUNT_MAX, cast(long long)element_count);
if (generic_row == nullptr && generic_column == nullptr) {
// row_count*column_count can overflow and wrap back under the limit, so test the
// dimensions first; each is at least MATRIX_ELEMENT_COUNT_MIN. Either one exceeding
// the maximum means the product does too
if (row_count > MATRIX_ELEMENT_COUNT_MAX || column_count > MATRIX_ELEMENT_COUNT_MAX ||
row_count*column_count > MATRIX_ELEMENT_COUNT_MAX) {
// the element count is only printable when the multiply cannot overflow, which is
// exactly the case the dimension test above catches
if (row_count != 0 && column_count > I64_MAX/row_count) {
error(node, "Matrix types are limited to a maximum of %d elements, got %lld by %lld", MATRIX_ELEMENT_COUNT_MAX, cast(long long)row_count, cast(long long)column_count);
} else {
error(node, "Matrix types are limited to a maximum of %d elements, got %lld by %lld (%lld elements)", MATRIX_ELEMENT_COUNT_MAX, cast(long long)row_count, cast(long long)column_count, cast(long long)(row_count*column_count));
}
}
}