From 3bdeec3bc249873f6555c128fa31f9de2bf628e1 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sun, 18 Jun 2023 23:25:33 +0200 Subject: [PATCH] Incorrect defer/return value ordering in some cases. --- releasenotes.md | 1 + src/compiler/llvm_codegen_stmt.c | 14 +++++++++++--- src/version.h | 2 +- test/test_suite/defer/defer_and_expr_block.c3t | 4 +--- test/test_suite/errors/macro_err2.c3t | 6 +++--- test/test_suite/macros/macro_defer_exit.c3t | 18 ++++++------------ test/test_suite/macros/macro_defer_scope.c3t | 3 +-- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/releasenotes.md b/releasenotes.md index f117d9ede..b0e01a884 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -123,6 +123,7 @@ - Added `Clock` and `DateTime`. ### Fixes +- Fixed defer/return value ordering in certain cases. - Fixes to the x64 ABI. - Updates to how variadics are implemented. - Fixes to shift checks. diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index 4a3a3ba7b..7b0c6fd7d 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -174,7 +174,11 @@ static inline void llvm_emit_return(GenContext *c, Ast *ast) { BEValue be_value; llvm_emit_expr(c, &be_value, expr->inner_expr); - llvm_emit_statement_chain(c, ast->return_stmt.cleanup_fail); + if (ast->return_stmt.cleanup_fail) + { + llvm_value_rvalue(c, &be_value); + llvm_emit_statement_chain(c, ast->return_stmt.cleanup_fail); + } llvm_emit_return_abi(c, NULL, &be_value); return; } @@ -200,7 +204,11 @@ static inline void llvm_emit_return(GenContext *c, Ast *ast) POP_OPT(); - llvm_emit_statement_chain(c, ast->return_stmt.cleanup); + if (ast->return_stmt.cleanup || ast->return_stmt.cleanup_fail) + { + if (has_return_value) llvm_value_rvalue(c, &return_value); + llvm_emit_statement_chain(c, ast->return_stmt.cleanup); + } // Are we in an expression block? if (!has_return_value) @@ -257,11 +265,11 @@ static inline void llvm_emit_block_exit_return(GenContext *c, Ast *ast) AstId cleanup = ast->return_stmt.cleanup; AstId cleanup_fail = ast->return_stmt.cleanup_fail; AstId err_cleanup = err_cleanup_block && cleanup_fail ? astid(copy_ast_defer(astptr(cleanup_fail))) : 0; - llvm_emit_statement_chain(c, cleanup); if (exit->block_return_out && return_value.value) { llvm_store_to_ptr_aligned(c, exit->block_return_out, &return_value, type_alloca_alignment(return_value.type)); } + llvm_emit_statement_chain(c, cleanup); if (err_cleanup_block) { diff --git a/src/version.h b/src/version.h index 708376ee2..6d998765f 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.530" \ No newline at end of file +#define COMPILER_VERSION "0.4.531" \ No newline at end of file diff --git a/test/test_suite/defer/defer_and_expr_block.c3t b/test/test_suite/defer/defer_and_expr_block.c3t index af90a083e..0bc9a09c7 100644 --- a/test/test_suite/defer/defer_and_expr_block.c3t +++ b/test/test_suite/defer/defer_and_expr_block.c3t @@ -24,13 +24,11 @@ define void @foo.main() #0 { entry: %blockret = alloca i32, align 4 br label %if.then - if.then: ; preds = %entry + store i32 12, ptr %blockret, align 4 call void (ptr, ...) @printf(ptr @.str) call void (ptr, ...) @printf(ptr @.str.1) - store i32 12, ptr %blockret, align 4 br label %expr_block.exit - expr_block.exit: ; preds = %if.then call void (ptr, ...) @printf(ptr @.str.5) call void (ptr, ...) @printf(ptr @.str.6) diff --git a/test/test_suite/errors/macro_err2.c3t b/test/test_suite/errors/macro_err2.c3t index 3ea96be61..da045fa3f 100644 --- a/test/test_suite/errors/macro_err2.c3t +++ b/test/test_suite/errors/macro_err2.c3t @@ -36,9 +36,9 @@ entry: br i1 %1, label %after_check, label %opt_block_cleanup after_check: ; preds = %entry - %2 = call i32 (ptr, ...) @printf(ptr @.str.1) - %3 = load i32, ptr %retparam, align 4 - store i32 %3, ptr %blockret, align 4 + %2 = load i32, ptr %retparam, align 4 + store i32 %2, ptr %blockret, align 4 + %3 = call i32 (ptr, ...) @printf(ptr @.str.1) br label %expr_block.exit opt_block_cleanup: ; preds = %entry diff --git a/test/test_suite/macros/macro_defer_exit.c3t b/test/test_suite/macros/macro_defer_exit.c3t index 207c9ecf8..e52bdd5bb 100644 --- a/test/test_suite/macros/macro_defer_exit.c3t +++ b/test/test_suite/macros/macro_defer_exit.c3t @@ -33,24 +33,21 @@ entry: %1 = load i32, ptr %x, align 4 %gt = icmp sgt i32 %1, 100 br i1 %gt, label %if.then, label %if.exit - if.then: ; preds = %entry %2 = load i32, ptr %x, align 4 %sub = sub i32 %2, 100 store i32 %sub, ptr %x, align 4 + store i32 %sub, ptr %blockret, align 4 %3 = load i32, ptr %x, align 4 call void (ptr, ...) @printf(ptr @.str, i32 %3) - store i32 %sub, ptr %blockret, align 4 br label %expr_block.exit - if.exit: ; preds = %entry call void (ptr, ...) @printf(ptr @.str.1) %4 = load i32, ptr %x, align 4 - call void (ptr, ...) @printf(ptr @.str.2, i32 %4) + store i32 %4, ptr %blockret, align 4 %5 = load i32, ptr %x, align 4 - store i32 %5, ptr %blockret, align 4 + call void (ptr, ...) @printf(ptr @.str.2, i32 %5) br label %expr_block.exit - expr_block.exit: ; preds = %if.exit, %if.then store i32 3, ptr %x1, align 4 %6 = load i32, ptr %x1, align 4 @@ -59,24 +56,21 @@ expr_block.exit: ; preds = %if.exit, %if.then %7 = load i32, ptr %x1, align 4 %gt4 = icmp sgt i32 %7, 100 br i1 %gt4, label %if.then5, label %if.exit7 - if.then5: ; preds = %expr_block.exit %8 = load i32, ptr %x1, align 4 %sub6 = sub i32 %8, 100 store i32 %sub6, ptr %x1, align 4 + store i32 %sub6, ptr %blockret2, align 4 %9 = load i32, ptr %x1, align 4 call void (ptr, ...) @printf(ptr @.str.3, i32 %9) - store i32 %sub6, ptr %blockret2, align 4 br label %expr_block.exit8 - if.exit7: ; preds = %expr_block.exit call void (ptr, ...) @printf(ptr @.str.4) %10 = load i32, ptr %x1, align 4 - call void (ptr, ...) @printf(ptr @.str.5, i32 %10) + store i32 %10, ptr %blockret2, align 4 %11 = load i32, ptr %x1, align 4 - store i32 %11, ptr %blockret2, align 4 + call void (ptr, ...) @printf(ptr @.str.5, i32 %11) br label %expr_block.exit8 - expr_block.exit8: ; preds = %if.exit7, %if.then5 call void (ptr, ...) @printf(ptr @.str.6) ret void diff --git a/test/test_suite/macros/macro_defer_scope.c3t b/test/test_suite/macros/macro_defer_scope.c3t index 0fb766794..a347d8a0c 100644 --- a/test/test_suite/macros/macro_defer_scope.c3t +++ b/test/test_suite/macros/macro_defer_scope.c3t @@ -32,10 +32,9 @@ entry: %add2 = add i32 %1, 1 store i32 %add2, ptr %x, align 4 %add3 = add i32 %add, %add2 - %2 = call i32 (ptr, ...) @printf(ptr @.str) store i32 %add3, ptr %blockret, align 4 + %2 = call i32 (ptr, ...) @printf(ptr @.str) br label %expr_block.exit - expr_block.exit: ; preds = %entry %3 = load i32, ptr %x, align 4 %4 = call i32 (ptr, ...) @printf(ptr @.str.1, i32 %3)