From 93640699be70d55411e1b0c8abfada7e48049920 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 17 Jun 2025 16:49:46 +0200 Subject: [PATCH] Support distrinct types as the base type of bitstructs. #2218 --- releasenotes.md | 1 + src/compiler/sema_decls.c | 4 +- .../bitstruct/bitstruct_with_distinct.c3t | 48 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 test/test_suite/bitstruct/bitstruct_with_distinct.c3t diff --git a/releasenotes.md b/releasenotes.md index cffb42753..a74cc319e 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -22,6 +22,7 @@ - The form-feed character '\f' is no longer valid white space. - Show code that caused unreachable code #2207 - Allow generics over distinct types #2216. +- Support distrinct types as the base type of bitstructs. #2218 ### Fixes - `-2147483648`, MIN literals work correctly. diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index dab5074d6..89d6f777d 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1061,8 +1061,8 @@ static bool sema_analyse_bitstruct(SemaContext *context, Decl *decl, bool *erase if (*erase_decl) return true; DEBUG_LOG("Beginning analysis of %s.", decl->name ? decl->name : ".anon"); if (!sema_resolve_type_info(context, decl->strukt.container_type, RESOLVE_TYPE_DEFAULT)) return false; - Type *type = decl->strukt.container_type->type->canonical; - Type *base_type = type->type_kind == TYPE_ARRAY ? type->array.base : type; + Type *type = type_flatten(decl->strukt.container_type->type->canonical); + Type *base_type = type->type_kind == TYPE_ARRAY ? type_flatten(type->array.base) : type; if (!type_is_integer(base_type)) { SEMA_ERROR(decl->strukt.container_type, "The type of the bitstruct cannot be %s but must be an integer or an array of integers.", diff --git a/test/test_suite/bitstruct/bitstruct_with_distinct.c3t b/test/test_suite/bitstruct/bitstruct_with_distinct.c3t new file mode 100644 index 000000000..f06f7f479 --- /dev/null +++ b/test/test_suite/bitstruct/bitstruct_with_distinct.c3t @@ -0,0 +1,48 @@ +// #target: macos-x64 +module test; +typedef Foo = int; + +bitstruct Bar : Foo +{ + bool a : 0; + Foo x : 1..4; +} + +typedef Baz = char; + +bitstruct Bar2 : Baz[3] +{ + bool x; +} + +fn int main() +{ + Bar x; + Bar2 y; + x.a = true; + x.x = 100; + return 0; +} + +/* #expect: test.ll + +define i32 @main() #0 { +entry: + %x = alloca i32, align 4 + %y = alloca [3 x i8], align 1 + store i32 0, ptr %x, align 4 + store i8 0, ptr %y, align 1 + %ptradd = getelementptr inbounds i8, ptr %y, i64 1 + store i8 0, ptr %ptradd, align 1 + %ptradd1 = getelementptr inbounds i8, ptr %y, i64 2 + store i8 0, ptr %ptradd1, align 1 + %0 = load i32, ptr %x, align 4 + %1 = and i32 %0, -2 + %2 = or i32 %1, 1 + store i32 %2, ptr %x, align 4 + %3 = load i32, ptr %x, align 4 + %4 = and i32 %3, -31 + %5 = or i32 %4, 8 + store i32 %5, ptr %x, align 4 + ret i32 0 +}