mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-14 01:34:35 +00:00
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:
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user