← board

var section before a constructor/destructor impl fails — ctor/dtor eaten as a var name

Symptom

A var section immediately followed by a constructor/destructor method implementation at program (or unit) level fails:

program p;
type TFoo = class destructor Destroy; override; end;
var g: Integer;
destructor TFoo.Destroy; begin g := 1; inherited Destroy; end;   { pascal26:4: error: unexpected token }
begin end.

A procedure/function method impl in the same position compiles fine, and a ctor/dtor impl before the var section compiles fine — so it looked like an odd ordering rule.

Root cause

constructor/destructor are soft identifiers in this dialect (tkIdent with SVal 'constructor'/'destructor'), not dedicated tokens like tkProcedure/tkFunction. ParseVarSection's entry loop (while CurTok.Kind = tkIdent and not <section-word>) stopped only at implementation/initialization/finalization. So when a var section was followed by destructor TFoo.Destroy, the loop read destructor as the next variable name, then hit TFoo where it expected :/, → "unexpected token". procedure/function are real tokens, so the CurTok.Kind = tkIdent guard already stopped the loop for them — hence the asymmetry.

Fix

Extend ParseVarSection's stop-list to the full set of soft-identifier declaration-introducers that may follow a var section, matching the top-level decl loop: constructor, destructor, generic, specialize, operator, label (added to the existing implementation/initialization/finalization). Verified none of these are used as a variable name in lib/**, compiler/**, or test/**. One-site change; front-end only.

Verified