diff --git a/releasenotes.md b/releasenotes.md index d1d893dcd..c58468172 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -81,6 +81,7 @@ - Fix issue where recursively creating a dir would be incorrectly marked as a failure the first time. - `@format` did not work correctly with macros #2341. - Crash when parsing recursive type declaration #2345. +- Remove unnecessary "ret" in naked functions #2344. ### Stdlib changes - Improve contract for readline. #2280 diff --git a/src/compiler/llvm_codegen_function.c b/src/compiler/llvm_codegen_function.c index 7c62805a7..8a0b41995 100644 --- a/src/compiler/llvm_codegen_function.c +++ b/src/compiler/llvm_codegen_function.c @@ -516,7 +516,14 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, FunctionPrototype *pro // Insert a return (and defer) if needed. if (c->current_block && !LLVMGetBasicBlockTerminator(c->current_block)) { - llvm_emit_return_implicit(c); + if (signature) + { + llvm_emit_return_implicit(c); + } + else + { + llvm_emit_unreachable(c); + } } LLVMBasicBlockRef last_block = LLVMGetLastBasicBlock(c->cur_func.ref); diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index e663ea9e8..9dd66406d 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -3353,7 +3353,7 @@ bool sema_analyse_function_body(SemaContext *context, Decl *func) bool is_naked = func->func_decl.attr_naked; if (!is_naked) sema_append_contract_asserts(assert_first, body); Type *canonical_rtype = type_no_optional(prototype->rtype)->canonical; - if (has_ensures && type_is_void(canonical_rtype)) + if (!is_naked && has_ensures && type_is_void(canonical_rtype)) { AstId* append_pos = &body->compound_stmt.first_stmt; if (*append_pos) diff --git a/test/test_suite/asm/naked.c3t b/test/test_suite/asm/naked.c3t index a820f7f17..913eeab89 100644 --- a/test/test_suite/asm/naked.c3t +++ b/test/test_suite/asm/naked.c3t @@ -14,6 +14,6 @@ fn void start() @export("_start") @naked @nostrip { define void @_start() #0 { entry: call void asm sideeffect alignstack "movq $$60, %rax\0Amovq $$42, %rdi\0Asyscall \0A", "~{cc},~{rax},~{rcx},~{r8},~{r11},~{flags},~{dirflag},~{fspr}"() - ret void + unreachable } diff --git a/test/test_suite/asm/syscall.c3t b/test/test_suite/asm/syscall.c3t index bc2cabd9e..70d5a70cb 100644 --- a/test/test_suite/asm/syscall.c3t +++ b/test/test_suite/asm/syscall.c3t @@ -12,6 +12,6 @@ fn void start() @export("_start") @naked @nostrip { define void @_start() #0 { entry: call void asm sideeffect alignstack "syscall \0A", "~{cc},~{rax},~{rcx},~{r11},~{flags},~{dirflag},~{fspr}"() - ret void + unreachable } diff --git a/test/test_suite/functions/naked_function.c3t b/test/test_suite/functions/naked_function.c3t index 91c545b61..fdcc6569c 100644 --- a/test/test_suite/functions/naked_function.c3t +++ b/test/test_suite/functions/naked_function.c3t @@ -9,7 +9,7 @@ fn void test(int i) @naked define void @naked_function.test(i32 %0) #0 { entry: - ret void + unreachable } attributes #0 = { naked nounwind uwtable "no-trapping-math"="true" "stack-protector-buffer-size"="8" }