From 3188d4d8582758ed3dfebc9eb11f512a3affed29 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 23 Jul 2024 21:20:40 +0200 Subject: [PATCH] Reference parameter doesn't work with vector subscript #1250. --- releasenotes.md | 1 + src/compiler/sema_expr.c | 9 +++++- test/test_suite/macros/ref_vector.c3t | 40 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test/test_suite/macros/ref_vector.c3t diff --git a/releasenotes.md b/releasenotes.md index 7732c7f00..34b2199e8 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -51,6 +51,7 @@ - Stdlib nolibc code bugs fixed. - Regression: duplicate symbols with static variable declared in macro #1248. - Unsplat with named parameters was accidentally disallowed. +- Reference parameter doesn't work with vector subscript #1250. ### Stdlib changes - Added `remove_first_item` `remove_last_item` and `remove_item` as aliases for the `match` functions. diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 1a3e8d2f2..73f0b6fc1 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -1537,14 +1537,20 @@ static bool sema_analyse_parameter(SemaContext *context, Expr *arg, Decl *param, switch (kind) { case VARDECL_PARAM_REF: + { // &foo + bool is_subscript = arg->expr_kind == EXPR_SUBSCRIPT; + if (is_subscript) + { + arg->expr_kind = EXPR_SUBSCRIPT_ADDR; + } if (!sema_analyse_expr_lvalue(context, arg)) return false; if (sema_arg_is_pass_through_ref(arg) && !sema_expr_check_assign(context, arg)) { SEMA_NOTE(definition, "The definition is here."); return false; } - expr_insert_addr(arg); + if (!is_subscript) expr_insert_addr(arg); *optional_ref |= IS_OPTIONAL(arg); if (!sema_call_check_contract_param_match(context, param, arg)) { @@ -1573,6 +1579,7 @@ static bool sema_analyse_parameter(SemaContext *context, Expr *arg, Decl *param, } } break; + } case VARDECL_PARAM: // foo if (!sema_analyse_expr_rhs(context, type, arg, true, no_match_ref)) return false; diff --git a/test/test_suite/macros/ref_vector.c3t b/test/test_suite/macros/ref_vector.c3t new file mode 100644 index 000000000..2ee05ce85 --- /dev/null +++ b/test/test_suite/macros/ref_vector.c3t @@ -0,0 +1,40 @@ +// #target: macos-x64 +module test; + +fn int main() { + int[<4>] vec; + @foo(vec[0]); + @foo(vec[2]); + assert(vec[0] == 1); + assert(vec[2] == 1); + return 1; +} + +macro @foo(&ref) { + *ref += 1; +} + +/* #expect: test.ll + + +define i32 @main() #0 { +entry: + %vec = alloca <4 x i32>, align 16 + store <4 x i32> zeroinitializer, ptr %vec, align 16 + %0 = load i32, ptr %vec, align 4 + %add = add i32 %0, 1 + store i32 %add, ptr %vec, align 4 + %ptradd = getelementptr inbounds i8, ptr %vec, i64 8 + %1 = load i32, ptr %ptradd, align 4 + %add1 = add i32 %1, 1 + store i32 %add1, ptr %ptradd, align 4 + %2 = load <4 x i32>, ptr %vec, align 16 + %3 = extractelement <4 x i32> %2, i64 0 + %eq = icmp eq i32 %3, 1 + call void @llvm.assume(i1 %eq) + %4 = load <4 x i32>, ptr %vec, align 16 + %5 = extractelement <4 x i32> %4, i64 2 + %eq2 = icmp eq i32 %5, 1 + call void @llvm.assume(i1 %eq2) + ret i32 1 +}