Fix goto to label connection in inlined functions

This commit is contained in:
drmortalwombat 2024-06-25 21:56:36 +02:00
parent 715f295f5e
commit fe736289e6
2 changed files with 43 additions and 34 deletions

View File

@ -1348,6 +1348,45 @@ void InterCodeGenerator::UnwindDestructStack(Declaration* procType, InterCodePro
mErrors->Error(proc->mLocation, EWARN_DESTRUCTOR_MISMATCH, "Destructor sequence mismatch");
}
void InterCodeGenerator::ConnectGotos(Declaration* procType, InterCodeProcedure* proc, GotoNode* gotos, InlineMapper* inlineMapper)
{
GotoNode* gl = gotos;
while (gl)
{
GotoNode* g = gotos;
while (g && !(g != gl && g->mExpr->mType == EX_LABEL && g->mExpr->mDecValue->mIdent == gl->mExpr->mDecValue->mIdent))
g = g->mNext;
if (gl->mExpr->mType == EX_LABEL)
{
if (g)
mErrors->Error(gl->mExpr->mLocation, EERR_DUPLICATE_DEFINITION, "Label defined twice", gl->mExpr->mDecValue->mIdent);
}
else
{
if (g)
{
if (gl->mDestruct)
{
DestructStack* s = gl->mDestruct;
while (s && s != g->mDestruct)
s = s->mNext;
if (s == g->mDestruct)
UnwindDestructStack(procType, proc, gl->mBlock, gl->mDestruct, s, inlineMapper);
else
mErrors->Error(gl->mExpr->mLocation, ERRR_INVALID_GOTO, "Invalid got bypass constructor");
}
gl->mBlock->Close(g->mBlock, nullptr);
}
else
mErrors->Error(gl->mExpr->mLocation, EERR_UNDEFINED_OBJECT, "Undefined label", gl->mExpr->mDecValue->mIdent);
}
gl = gl->mNext;
}
}
Location InterCodeGenerator::MapLocation(Expression* exp, InlineMapper* inlineMapper)
{
if (inlineMapper)
@ -1535,6 +1574,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
block->Close(nmapper.mReturn, nullptr);
block = nmapper.mReturn;
ConnectGotos(ftype, proc, igotos, &nmapper);
// Unwind inner destruct stack
UnwindDestructStack(ftype, proc, block, idestack, nullptr, &nmapper);
@ -5644,40 +5685,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
TranslateExpression(dec->mBase, proc, exitBlock, exp, destack, gotos, BranchTarget(), BranchTarget(), nullptr);
GotoNode* gl = gotos;
while (gl)
{
GotoNode* g = gotos;
while (g && !(g != gl && g->mExpr->mType == EX_LABEL && g->mExpr->mDecValue->mIdent == gl->mExpr->mDecValue->mIdent))
g = g->mNext;
if (gl->mExpr->mType == EX_LABEL)
{
if (g)
mErrors->Error(gl->mExpr->mLocation, EERR_DUPLICATE_DEFINITION, "Label defined twice", gl->mExpr->mDecValue->mIdent);
}
else
{
if (g)
{
if (gl->mDestruct)
{
DestructStack* s = gl->mDestruct;
while (s && s != g->mDestruct)
s = s->mNext;
if (s == g->mDestruct)
UnwindDestructStack(dec->mBase, proc, gl->mBlock, gl->mDestruct, s, nullptr);
else
mErrors->Error(gl->mExpr->mLocation, ERRR_INVALID_GOTO, "Invalid got bypass constructor");
}
gl->mBlock->Close(g->mBlock, nullptr);
}
else
mErrors->Error(gl->mExpr->mLocation, EERR_UNDEFINED_OBJECT, "Undefined label", gl->mExpr->mDecValue->mIdent);
}
gl = gl->mNext;
}
ConnectGotos(dec->mBase, proc, gotos, nullptr);
UnwindDestructStack(dec->mBase, proc, exitBlock, destack, nullptr, nullptr);

View File

@ -101,6 +101,7 @@ protected:
void CopyStructSimple(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock * block, InlineMapper* inlineMapper, ExValue vl, ExValue vr);
void StoreValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue vl, ExValue vr);
void ConnectGotos(Declaration* procType, InterCodeProcedure* proc, GotoNode* gotos, InlineMapper* inlineMapper);
void UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack * bottom, InlineMapper* inlineMapper);
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable);
};