From c949bd3108178e2188a19aa204000ed2fd937127 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 29 Dec 2025 22:24:41 +0100 Subject: [PATCH] Assert when struct size would exceed 4 GB. --- releasenotes.md | 1 + src/compiler/sema_decls.c | 2 ++ src/utils/common.h | 1 + test/test_suite/struct/struct_too_large.c3 | 12 ++++++++++++ 4 files changed, 16 insertions(+) create mode 100644 test/test_suite/struct/struct_too_large.c3 diff --git a/releasenotes.md b/releasenotes.md index cc43652b3..a46fc33d1 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -38,6 +38,7 @@ - Converting between simd/non-simd bool vector would hit a compiler assert. #2691 - `i` 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. ### Stdlib changes - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads. diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index a3a992856..6fcad4f7b 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -637,7 +637,9 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl) offset = align_offset; member->offset = offset; + AlignSize sz = offset; offset += type_size(member->type); + if (offset < sz || offset > MAX_STRUCT_SIZE) RETURN_SEMA_ERROR(member, "Struct member '%s' would cause the struct to become too large (exceeding 2 GB).", member->name); } // Set the alignment: diff --git a/src/utils/common.h b/src/utils/common.h index 899fe152e..6b86cc982 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -29,6 +29,7 @@ #define DEFAULT_STACK_OBJECT_SIZE 64 #define MAX_ARRAY_SIZE INT64_MAX #define MAX_SOURCE_LOCATION_LEN 255 +#define MAX_STRUCT_SIZE (2U * 1024U * 1024U * 1024U) #define PROJECT_JSON "project.json" #define PROJECT_JSON5 "project.json5" diff --git a/test/test_suite/struct/struct_too_large.c3 b/test/test_suite/struct/struct_too_large.c3 new file mode 100644 index 000000000..7b80726e1 --- /dev/null +++ b/test/test_suite/struct/struct_too_large.c3 @@ -0,0 +1,12 @@ +import std; +struct Foo +{ + int a; + int[int.max] b; // #error: "Struct member 'b' would cause the struct to become too large +} + +fn int main() +{ + Foo c = (Foo){}; + return 0; +}