mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 20:41:06 +01:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user