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
+16 -3
View File
@@ -13,6 +13,7 @@
#include "llvm/IR/DerivedTypes.h"
#include "toolchain/base/kind_switch.h"
#include "toolchain/lower/file_context.h"
#include "toolchain/sem_ir/entry_point.h"
#include "toolchain/sem_ir/file.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/inst.h"
@@ -138,6 +139,15 @@ class FunctionTypeInfoBuilder {
return true;
}
// Modifies the lowered return type of the entry point function to return
// an int32, to conform with expectations from calling programs.
auto SetEntryPointReturnInt32(const FunctionInContext& func_ctx) -> bool {
return_type_ = llvm::Type::getInt32Ty(func_ctx.context->llvm_context());
param_di_types_.push_back(context_->di_builder().createBasicType(
"int", 32, llvm::dwarf::DW_ATE_signed));
return true;
}
// Records that the LLVM function returns by reference, with type
// `return_type_id`.
auto SetReturnByReference(const FunctionInContext& func_ctx,
@@ -269,9 +279,6 @@ class FunctionTypeInfoBuilder {
};
auto FunctionTypeInfoBuilder::Build() && -> FunctionTypeInfo {
// TODO: For the `Run` entry point, remap return type to i32 if it doesn't
// return a value.
// Determine how the parameters are numbered in SemIR, and make sure it's the
// same for all versions of the function.
auto semir_info = GetSemIRIndexInfo(functions_.front());
@@ -325,6 +332,12 @@ auto FunctionTypeInfoBuilder::TryHandleReturnForm(
func_ctx.context->sem_ir().functions().Get(func_ctx.function_id);
auto return_form_inst_id = function.return_form_inst_id;
if (!return_form_inst_id.has_value()) {
// If this is the entry point 'Run()` function, and it doesn't specify a
// return type, we modify the lowered return type to be an int32 and emit IR
// to return 0i32.
if (SemIR::IsEntryPoint(func_ctx.context->sem_ir(), func_ctx.function_id)) {
return SetEntryPointReturnInt32(func_ctx);
}
return SetReturnByCopy(func_ctx, SemIR::TypeId::None);
}