aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/CodeGen.cc8
-rw-r--r--lib/CodeGen/FunctionGen.cc4
2 files changed, 12 insertions, 0 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc
index e45a3db..772dc82 100644
--- a/lib/CodeGen/CodeGen.cc
+++ b/lib/CodeGen/CodeGen.cc
@@ -77,6 +77,14 @@ CodeGen::CodeGen() {
activateStackObject(registerStackObject(Addr, TypeName, Line));
});
+ FuncGen->setMissingReturnHandler([this](int Line, const std::string &Name) {
+ Value *Msg = Builder->CreateGlobalString("[Fatal] line %d: FUNCTION %s ended without RETURN\n",
+ "err_missing_return", 0, TheModule.get());
+ Value *NameStr = Builder->CreateGlobalString(Name, "function_name", 0, TheModule.get());
+ RuntimeChecker->emitStderr(Msg, {RuntimeChecker->lineValue(Line), NameStr});
+ Exceptions->emitThrow();
+ });
+
SetupExternalFunctions();
}
diff --git a/lib/CodeGen/FunctionGen.cc b/lib/CodeGen/FunctionGen.cc
index 48c9978..c233205 100644
--- a/lib/CodeGen/FunctionGen.cc
+++ b/lib/CodeGen/FunctionGen.cc
@@ -444,6 +444,10 @@ Function *FunctionGen::emitFunctionDef(FunctionDefAST *FuncAST,
if (!Builder.GetInsertBlock()->hasTerminator()) {
if (sameIdentifier(Proto->getReturnType(), "VOID")) {
Exceptions.recordExit(Builder.CreateRetVoid());
+ } else if (MissingReturn && !(!IsMethod && sameIdentifier(Proto->getName(), "MAIN"))) {
+ // Falling off the end of a FUNCTION is a runtime error, not a zero value.
+ // The handler ends the block with a throw (unreachable).
+ MissingReturn(FuncAST->getLine(), Proto->getName());
} else {
Exceptions.recordExit(Builder.CreateRet(Constant::getNullValue(TheFunction->getReturnType())));
}