fix(compiler): exit --emit-ir path through normal cleanup, not Halt(0)

The --emit-ir branch in main wrote the IR and immediately called Halt(0),
which lowers to libc exit().  libc exit() runs atexit handlers (so the leak
report still prints) but unwinds no Pascal stack frame, so the main block's
scope-exit ARC releases never run — any local not freed in the finally block
leaked silently, and the leak tracker could not see it.

Restructure so --emit-ir writes the IR and falls through to the end of the
program, letting the main block's scope-exit cleanup release its locals
before the process returns normally.  The native-compile path is now the
else branch.  IR output is byte-identical (verified: fixpoint clean,
2260 tests pass).
This commit is contained in:
Graeme Geldenhuys 2026-06-02 00:31:08 +01:00
parent 5b10bdab7b
commit 5e45c50503

View file

@ -526,31 +526,35 @@ begin
Source.Free;
end;
{ --emit-ir: write the IR to stdout and fall through to normal program
exit so the main block's scope-exit ARC cleanup runs. Calling Halt(0)
here would lower to libc exit(), which skips every Pascal stack frame and
leaves main's locals unreleased — defeating the leak tracker and leaking
anything not freed in the finally block above. }
if EmitIR then
Write(IR)
else
begin
Write(IR);
Halt(0);
end;
IRFile := ChangeFileExt(OutputFile, '.ssa');
try
Source := TStringList.Create;
IRFile := ChangeFileExt(OutputFile, '.ssa');
try
Source.Text := IR;
Source.SaveToFile(IRFile);
finally
Source.Free;
Source := TStringList.Create();
try
Source.Text := IR;
Source.SaveToFile(IRFile);
finally
Source.Free();
end;
except
on E: Exception do
begin
WriteLn(StdErr, 'Error writing IR: ', Exception(E).Message);
Halt(1);
end;
end;
except
on E: Exception do
begin
WriteLn(StdErr, 'Error writing IR: ', Exception(E).Message);
Halt(1);
end;
end;
CompileToNative(IRFile, OutputFile, OPDFAsmFile);
DeleteFile(IRFile);
if OPDFAsmFile <> '' then
DeleteFile(OPDFAsmFile);
CompileToNative(IRFile, OutputFile, OPDFAsmFile);
DeleteFile(IRFile);
if OPDFAsmFile <> '' then
DeleteFile(OPDFAsmFile);
end;
end.