From 8d6dabf65c6df420b9030bc049f5ce3092cec01c Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 30 Jul 2024 02:45:40 +0200 Subject: [PATCH] Struct members declared in a single line declaration were not sharing attributes. #1266 --- releasenotes.md | 4 ++++ src/compiler/parse_global.c | 20 +++++++++++++++++ .../struct/multi_member_attributes.c3t | 22 +++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 test/test_suite/struct/multi_member_attributes.c3t diff --git a/releasenotes.md b/releasenotes.md index 5efe5be79..e38f7d73c 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -3,6 +3,7 @@ ## 0.6.2 Change list ### Changes / improvements + - Updated LLVM passes - Added `is_substruct` type property. - Scalar -> vector not implicit in call or assign. @@ -17,12 +18,15 @@ - Add `--show-backtrace` option to disable backtrace for even smaller binary. ### Fixes + - Broken WASM library code. - Regression: Invalid is_random implementation due to changes in 0.6. - `dbghelp.lib` was linked even on nolibc on Windows. - Fix incorrect linker selection on some platforms. +- Struct members declared in a single line declaration were not sharing attributes. #1266 ### Stdlib changes + None ## 0.6.1 Change list diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index e7a9037cd..f300cc2a7 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -1495,6 +1495,7 @@ bool parse_struct_body(ParseContext *c, Decl *parent) } ASSIGN_TYPE_OR_RET(TypeInfo *type, parse_type(c), false); + unsigned first_member_index = vec_size(parent->strukt.members); while (1) { if (!tok_is(c, TOKEN_IDENT)) RETURN_PRINT_ERROR_HERE("A valid member name was expected here."); @@ -1516,6 +1517,25 @@ bool parse_struct_body(ParseContext *c, Decl *parent) RETURN_PRINT_ERROR_AT(false, member, "'inline' can only be applied to a single member, so please define it on its own line."); } } + Decl **members = parent->strukt.members; + unsigned last_index = vec_size(members) - 1; + if (last_index != first_member_index) + { + Decl *last_member = members[last_index]; + Attr **attributes = last_member->attributes; + if (attributes) + { + // Copy attributes + bool is_cond = last_member->is_cond; + for (unsigned i = first_member_index; i < last_index; i++) + { + Decl *member = members[i]; + if (is_cond) member->is_cond = true; + assert(!member->attributes); + member->attributes = copy_attributes_single(attributes); + } + } + } CONSUME_EOS_OR_RET(false); } advance_and_verify(c, TOKEN_RBRACE); diff --git a/test/test_suite/struct/multi_member_attributes.c3t b/test/test_suite/struct/multi_member_attributes.c3t new file mode 100644 index 000000000..73d8880c7 --- /dev/null +++ b/test/test_suite/struct/multi_member_attributes.c3t @@ -0,0 +1,22 @@ +// #target: macos-x64 + +module test; + +char x, y, z @align(64); + +struct Vector3 +{ + char x, y, z @align(8); // Issue #1266 +} + +Vector3 a = { 6, 8, 16 }; + +/* #expect: test.ll + + +%Vector3 = type { i8, [7 x i8], i8, [7 x i8], i8, [7 x i8] } + +@test.x = local_unnamed_addr global i8 0, align 64 +@test.y = local_unnamed_addr global i8 0, align 64 +@test.z = local_unnamed_addr global i8 0, align 64 +@test.a = local_unnamed_addr global %Vector3 { i8 6, [7 x i8] undef, i8 8, [7 x i8] undef, i8 16, [7 x i8] undef }, align 8