diff --git a/oscar64/Errors.h b/oscar64/Errors.h index 91211e8..ef52501 100644 --- a/oscar64/Errors.h +++ b/oscar64/Errors.h @@ -25,6 +25,7 @@ enum ErrorID EWARN_OPTIMIZER_LOCKED, EWARN_LOOP_UNROLL_IGNORED, EWARN_USE_OF_UNINITIALIZED_VARIABLE, + EWARN_MISSING_RETURN_STATEMENT, EERR_GENERIC = 3000, EERR_FILE_NOT_FOUND, diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 9ab2b26..caecb5c 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -12104,6 +12104,27 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati } } +void InterCodeBasicBlock::CheckValueReturn(InterCodeProcedure* proc) +{ + if (!mVisited) + { + mVisited = true; + + for (int i = 0; i < mInstructions.Size(); i++) + { + InterInstruction* ins = mInstructions[i]; + if (ins->mCode == IC_ASSEMBLER) + return; + else if (ins->mCode == IC_RETURN) + proc->mModule->mErrors->Error(ins->mLocation, EWARN_MISSING_RETURN_STATEMENT, "Missing return statement"); + } + + if (mTrueJump) mTrueJump->CheckValueReturn(proc); + if (mFalseJump) mFalseJump->CheckValueReturn(proc); + } +} + + void InterCodeBasicBlock::WarnUsedUndefinedVariables(InterCodeProcedure* proc) { if (!mVisited) @@ -12438,7 +12459,7 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l mIdent(ident), mLinkerObject(linkerObject), mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false), mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), - mSaveTempsLinkerObject(nullptr) + mSaveTempsLinkerObject(nullptr), mValueReturn(false) { mID = mModule->mProcedures.Size(); mModule->mProcedures.Push(this); @@ -13807,6 +13828,12 @@ void InterCodeProcedure::Close(void) MapCallerSavedTemps(); + if (mValueReturn) + { + ResetVisited(); + mEntryBlock->CheckValueReturn(this); + } + if (mSaveTempsLinkerObject && mTempSize > 16) mSaveTempsLinkerObject->AddSpace(mTempSize - 16); } diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 5ee8b36..d8db31f 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -508,6 +508,8 @@ public: bool SameExitCode(const InterCodeBasicBlock* block) const; void WarnUsedUndefinedVariables(InterCodeProcedure* proc); + void CheckValueReturn(InterCodeProcedure* proc); + }; class InterCodeModule; @@ -529,7 +531,7 @@ public: GrowingIntArray mTempOffset, mTempSizes; int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps; bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure; - bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled; + bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn; GrowingInterCodeProcedurePtrArray mCalledFunctions; InterCodeModule * mModule; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 7e06af1..d8d08e7 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -3550,6 +3550,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - BC_REG_FPARAMS; } + if (dec->mBase->mBase->mType != DT_TYPE_VOID) + proc->mValueReturn = true; + InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock(); proc->Append(entryBlock); diff --git a/samples/games/snake.c b/samples/games/snake.c index 88440e1..22bca3e 100644 --- a/samples/games/snake.c +++ b/samples/games/snake.c @@ -152,7 +152,7 @@ bool snake_advance(Snake * s) } // flash the snake after collision -bool snake_flash(Snake * s, char c) +void snake_flash(Snake * s, char c) { // Loop over all tail elements for(char i=0; ilength; i++)