← board

bug: untyped string constants are not SCOPED — a method's local const leaks to every later routine

What

The untyped-string-constant table (FindStrConst / StrConstSOff / StrConstSLen) is FLAT. A constant declared inside a routine:

function A: string;
const
  S = 'A string';      { LOCAL to A -- Pascal says it is invisible outside A }
begin
  A := S;
end;

stays visible to every routine parsed AFTER it. So a later routine sees S as that constant even though it went out of scope at A's end.

Why b313 is not the fix

b313 makes a VARIABLE in scope win over a same-named constant (Pascal's innermost-wins rule), which is what fcl-json's testjsondata.pp needed — a const S in one method and a var S : TJSONString in a later one. But a leaked constant still wins over:

Both are silent-wrong-behaviour, not diagnostics gaps, so this is a bug-, not a compat-.

Repro (the second form — a leaked const shadowing a later const)

program leak;
function A: string;
const S = 'first';
begin A := S; end;

function B: string;
const S = 'second';
begin B := S; end;

function C: string;      { S is NOT in scope here -- must be an error }
begin C := S; end;
begin writeln(A); writeln(B); writeln(C); end.

FPC: rejects C ("Identifier not found"). Check what pxx does with B and C.

Where

compiler/parser.inc, FindStrConst and the const-declaration parser. The table needs a scope/owner column (the CurProc that declared it, 0 = unit/global) and FindStrConst must search innermost-first and skip entries owned by a routine that is not the current one (or an enclosing one, for nested routines). Mirrors what the symbol table already does.

Log