disallow GOTO when it could corrupt the estack

- this occurs inside a FOR or CASE statement
- GOTO out of a WHILE or REPEAT loop  works
This commit is contained in:
slederer 2025-02-20 01:35:12 +01:00
parent 42d8df9b85
commit dd1e1f7b41
2 changed files with 36 additions and 7 deletions

View file

@ -5813,6 +5813,19 @@ begin
matchToken(ColonToken);
end;
procedure parseGotoStatement;
var aLabl: LablRef;
begin
readNextToken;
matchToken(IdentToken);
aLabl := findLabel(curProcedure, lastToken.tokenText);
if aLabl = nil then
errorExit2('GOTO to undefined label', lastToken.tokenText);
if curProcedure^.estackCleanup > 0 then
errorExit2('GOTO not allowed inside FOR or CASE', '');
emitLabelJump(aLabl);
end;
procedure parseStatement;
var sym: SymblRef;
cnst: ConstRef;
@ -5838,13 +5851,7 @@ begin
end;
if checkToken(GotoToken) then
begin
readNextToken;
matchToken(IdentToken);
aLabl := findLabel(curProcedure, lastToken.tokenText);
if aLabl = nil then errorExit2('GOTO to undefined label', lastToken.tokenText);
emitLabelJump(aLabl);
end
parseGotoStatement
else
if checkToken(IfToken) then
parseIfStatement

22
tests/gototest.pas Normal file
View file

@ -0,0 +1,22 @@
program gototest;
var i:integer;
label l1,l2;
begin
goto l1;
writeln('skipped');
l1: writeln('goto destination 1');
{
for i := 1 to 10 do
begin
goto l2;
end;
}
{
case i of
1: writeln('1');
2: goto l2;
3..10: writeln('3 - 10');
end;
l2: writeln('goto destination 2');
}
end.