diff --git a/releasenotes.md b/releasenotes.md index 27e40afa0..bd4e6ba2e 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -34,6 +34,7 @@ - `any_to_int` checks value to be int and no longer works with enum. - Add check in formatter printing "%c". - Fix bug where `!!` and `!` was not recognized to jump out of the current scope. +- Fix bug when including compile time parameters in trailing body more than once. ### Stdlib changes - Increase BitWriter.write_bits limit up to 32 bits. diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 01058036c..334d43baa 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -2474,7 +2474,7 @@ static bool sema_call_analyse_body_expansion(SemaContext *macro_context, Expr *c bool success; bool ends_in_jump; SCOPE_START - + unsigned ct_context = sema_context_push_ct_stack(context); if (macro_defer) { Ast *macro_defer_ast = astptr(macro_defer); @@ -2488,11 +2488,19 @@ static bool sema_call_analyse_body_expansion(SemaContext *macro_context, Expr *c } FOREACH(Decl *, param, params) { - if (!sema_add_local(context, param)) return SCOPE_POP_ERROR(); + if (!sema_add_local(context, param)) + { + sema_context_pop_ct_stack(context, ct_context); + return SCOPE_POP_ERROR(); + } } Ast *ast = copy_ast_single(macro_context->yield_body); call->body_expansion_expr.first_stmt = astid(ast); - if (!sema_analyse_statement(context, ast)) return SCOPE_POP_ERROR(); + if (!sema_analyse_statement(context, ast)) + { + sema_context_pop_ct_stack(context, ct_context); + return SCOPE_POP_ERROR(); + } ASSERT_SPAN(call, ast->ast_kind == AST_COMPOUND_STMT); if (context->active_scope.jump_end) { @@ -2503,9 +2511,11 @@ static bool sema_call_analyse_body_expansion(SemaContext *macro_context, Expr *c first_defer->defer_stmt.prev_defer = 0; context->active_scope.defer_last = last_defer; } + sema_context_pop_ct_stack(context, ct_context); SCOPE_END; return true; + } void sema_expr_convert_enum_to_int(SemaContext *context, Expr *expr) diff --git a/test/test_suite/macros/trailing_body_const.c3t b/test/test_suite/macros/trailing_body_const.c3t new file mode 100644 index 000000000..acc6e66b1 --- /dev/null +++ b/test/test_suite/macros/trailing_body_const.c3t @@ -0,0 +1,31 @@ +// #target: macos-x64 +module test; +import std::io; +macro @test(;@body($val)) +{ + @body(1); + @body(2); +} + +fn void main() +{ + int a; + @test(;int $num) + { + a += $num; + }; +} + +/* #expect: test.ll + +entry: + %a = alloca i32, align 4 + store i32 0, ptr %a, align 4 + %0 = load i32, ptr %a, align 4 + %add = add i32 %0, 1 + store i32 %add, ptr %a, align 4 + %1 = load i32, ptr %a, align 4 + %add1 = add i32 %1, 2 + store i32 %add1, ptr %a, align 4 + ret void +}