return 0 from Run when it doesn't specify a return value (#7180)

https://carbon.compiler-explorer.com/z/88K9Kh5Wo shows the program
exiting with a garbage value copied from uninitialized memory.

This PR modifies `lower` to detect if the function lowered is the
entry point and doesn't specify a return type. If so, it emits
different LLVM IR to return int32 0, and modifies the lowered
function signature to match the int32 return type.
This commit is contained in:
Lucile Rose Nihlen
2026-05-08 19:00:47 +00:00
committed by GitHub
parent 3e36f7d43c
commit bc1ae703c3
22 changed files with 618 additions and 444 deletions
+10
View File
@@ -13,6 +13,7 @@
#include "llvm/Support/Casting.h"
#include "toolchain/lower/function_context.h"
#include "toolchain/sem_ir/builtin_function_kind.h"
#include "toolchain/sem_ir/entry_point.h"
#include "toolchain/sem_ir/expr_info.h"
#include "toolchain/sem_ir/function.h"
#include "toolchain/sem_ir/inst.h"
@@ -261,6 +262,15 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::Return /*inst*/) -> void {
// The 'Run()' entry point does not need to specify a return type, but
// the C runtime and system ABI expects the entry point to return an `int`.
// In this situation we modify the lowered IR to return `0`
// with the expected LLVM type that corresponds to the `int` type.
if (SemIR::IsEntryPoint(context.specific_sem_ir(),
context.specific_sem_ir_function_id())) {
context.builder().CreateRet(context.builder().getInt32(0));
return;
}
context.builder().CreateRetVoid();
}