← board

Reproduce

function F: Integer;
label l;
begin
  Result := 0;
  try
    Result := 1;
  finally
    goto l;
    Result := -1;
    l:
    Result := Result + 3;
  end;
end;

pascal26:<line of l:>: error: duplicate IR label definition, identically on pin v412 and at HEAD. FPC prints 4.

Where

ir.inc, the try/finally arm: IRLowerAST(ASTRight[node]) twice (fall-through and handler), and IRLowerCleanupToDepth lowers the same body again for every exit/break/continue that crosses it. AN_LABEL resolves the name to GotoLabelIRId[slot], allocated once per body, so each copy places the same id.

The fix is to give each lowering of the body its own ids for the labels that live INSIDE it (and only those -- a goto out of the body to an outer label must keep the outer id, though that goto is now refused anyway). Found while writing test/test_goto_within_exception_region.pas, which leaves this case out and says so.