mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Added additional type size limits.
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
- Converting between simd/non-simd bool vector would hit a compiler assert. #2691
|
||||
- `i<n>` suffixes were not caught when n < 8, causing an assert.
|
||||
- Parse error in `$defined` was not handled correctly, leading to an assertion.
|
||||
- Assert when struct size would exceed 4 GB.
|
||||
- Assert when struct/array size would exceed 4 GB.
|
||||
- Assert when encountering a malformed module alias.
|
||||
- Assert when encountering a test function with raw vaarg parameters.
|
||||
- `foo.x` was not always handled correctly when `foo` was optional.
|
||||
|
||||
@@ -48,7 +48,7 @@ typedef uint16_t FileId;
|
||||
#define MAX_ALIGNMENT ((ArrayIndex)(((uint64_t)2) << 28))
|
||||
#define MAX_GENERIC_DEPTH 32
|
||||
#define MAX_PRIORITY 0xFFFF
|
||||
#define MAX_TYPE_SIZE UINT32_MAX
|
||||
#define MAX_TYPE_SIZE (2U << 30)
|
||||
#define MAX_GLOBAL_DECL_STACK (65536)
|
||||
#define MAX_MODULE_NAME 31
|
||||
#define MAX_MODULE_PATH 63
|
||||
|
||||
@@ -4586,7 +4586,63 @@ static bool sema_analyse_attributes_for_var(SemaContext *context, Decl *decl, bo
|
||||
if (!sema_analyse_attributes(context, decl, decl->attributes, domain, erase_decl)) return decl_poison(decl);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sema_type_is_valid_size(SemaContext *context, Type *type, SourceSpan span)
|
||||
{
|
||||
Int128 size = i128_from_unsigned(1);
|
||||
RETRY:
|
||||
if (size.high || size.low > (uint64_t)MAX_TYPE_SIZE)
|
||||
{
|
||||
RETURN_SEMA_ERROR_AT(span, "This type would exceed max type size of %u GB.", MAX_TYPE_SIZE >> 30);
|
||||
}
|
||||
switch (type->type_kind)
|
||||
{
|
||||
case TYPE_BITSTRUCT:
|
||||
ASSERT(type->decl->resolve_status == RESOLVE_DONE);
|
||||
type = type->decl->strukt.container_type->type;
|
||||
goto RETRY;
|
||||
case TYPE_TYPEDEF:
|
||||
type = type->decl->distinct->type;
|
||||
goto RETRY;
|
||||
case TYPE_ALIAS:
|
||||
type = type->canonical;
|
||||
goto RETRY;
|
||||
case CT_TYPES:
|
||||
case TYPE_FUNC_RAW:
|
||||
case TYPE_FLEXIBLE_ARRAY:
|
||||
return true;
|
||||
case TYPE_OPTIONAL:
|
||||
type = type->optional;
|
||||
goto RETRY;
|
||||
case TYPE_VOID:
|
||||
return true;
|
||||
case TYPE_BOOL:
|
||||
case TYPE_TYPEID:
|
||||
case ALL_INTS:
|
||||
case ALL_FLOATS:
|
||||
case TYPE_ANYFAULT:
|
||||
case TYPE_INTERFACE:
|
||||
case TYPE_ANY:
|
||||
case TYPE_FUNC_PTR:
|
||||
case TYPE_POINTER:
|
||||
case TYPE_STRUCT:
|
||||
case TYPE_UNION:
|
||||
case TYPE_ENUM:
|
||||
case TYPE_CONST_ENUM:
|
||||
case TYPE_SLICE:
|
||||
size = i128_mult64(size, type_size(type));
|
||||
break;
|
||||
case VECTORS:
|
||||
case TYPE_ARRAY:
|
||||
size = i128_mult64(size, type->array.len);
|
||||
type = type->array.base;
|
||||
goto RETRY;
|
||||
}
|
||||
if (size.high || size.low > (uint64_t)MAX_TYPE_SIZE)
|
||||
{
|
||||
RETURN_SEMA_ERROR_AT(span, "This type would exceed max type size of %u GB.", MAX_TYPE_SIZE >> 30);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static bool sema_analyse_variable_type(SemaContext *context, Type *type, SourceSpan span)
|
||||
{
|
||||
switch (sema_resolve_storage_type(context, type))
|
||||
@@ -4975,6 +5031,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local, bool *c
|
||||
{
|
||||
if (!sema_set_alloca_alignment(context, decl->type, &decl->alignment)) return false;
|
||||
}
|
||||
if (decl->type && !sema_type_is_valid_size(context, decl->type, decl->var.type_info ? type_infoptr(decl->var.type_info)->span : decl->span)) return false;
|
||||
if (decl->var.kind == VARDECL_LOCAL && !is_static && type_size(decl->type) > compiler.build.max_stack_object_size * 1024)
|
||||
{
|
||||
size_t size = type_size(decl->type);
|
||||
|
||||
@@ -87,7 +87,7 @@ bool sema_resolve_array_like_len(SemaContext *context, TypeInfo *type_info, Arra
|
||||
{
|
||||
RETURN_VAL_SEMA_ERROR(type_info_poison(type_info), len_expr, "A vector may not exceed %d in bit width.", compiler.build.max_vector_size);
|
||||
}
|
||||
RETURN_VAL_SEMA_ERROR(type_info_poison(type_info), len_expr, "The array length may not exceed %lld.", MAX_ARRAY_SIZE);
|
||||
RETURN_VAL_SEMA_ERROR(type_info_poison(type_info), len_expr, "The array length may not exceed %lld.", (long long)MAX_ARRAY_SIZE);
|
||||
}
|
||||
// We're done, return the size and mark it as a success.
|
||||
*len_ref = (ArraySize)len.i.low;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#define DEFAULT_MAX_MACRO_ITERATIONS 0xFFFFF
|
||||
#define DEFAULT_VECTOR_WIDTH 4096
|
||||
#define DEFAULT_STACK_OBJECT_SIZE 64
|
||||
#define MAX_ARRAY_SIZE INT64_MAX
|
||||
#define MAX_ARRAY_SIZE (2U * 1024U * 1024U * 1024U)
|
||||
#define MAX_SOURCE_LOCATION_LEN 255
|
||||
#define MAX_STRUCT_SIZE (2U * 1024U * 1024U * 1024U)
|
||||
#define PROJECT_JSON "project.json"
|
||||
|
||||
5
test/test_suite/arrays/array_limit.c3
Normal file
5
test/test_suite/arrays/array_limit.c3
Normal file
@@ -0,0 +1,5 @@
|
||||
fn int main()
|
||||
{
|
||||
int[0x80000000][1] x; // #error: This type would exceed max type size of 2 GB.
|
||||
return 0;
|
||||
}
|
||||
6
test/test_suite/arrays/array_limit_const.c3
Normal file
6
test/test_suite/arrays/array_limit_const.c3
Normal file
@@ -0,0 +1,6 @@
|
||||
const FOO = (int[0x80000000][1]) {}; // #error: This type would exceed max type size of 2 GB.
|
||||
|
||||
fn int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user