← board

A set of char typed constant corrupts Ord(char-var) codegen

Symptom

When a program declares a typed constant of a set of char type, codegen for plain char variables in the same program goes wrong: Ord(c) returns garbage (an address-like value), and c in C returns the wrong membership.

program p;
type T = set of char;
const C: T = [#65];          { any set-of-char const: [#65], ['A'..'Z'], ... }
var c: char;
begin
  c := #65;
  writeln(Ord(c));           { prints 4226039 (garbage); must be 65 }
end.

Isolation (stable v50):

Hex-independent (decimal #65 reproduces), so this is NOT the recently-fixed #$ hex-char literal bug — it is a separate codegen issue tied to the presence of a set of char typed constant.

Likely area

The set of char constant's data emission / addressing appears to clobber or mis-base the char-variable access (the garbage looks like an address). Suspect the constant-pool / global-data layout for set constants, or Ord/char load picking up the set const's base. Reproduces with a single set const + single char var, so it should reduce cleanly.

Indexing/typed-const issues that smell like the same const-data handling — record here, split out if they prove independent:

Done when

Resolution (2026-06-25, v57)

Not a set of char codegen bug — a case-insensitive name collision. The repro names the const C and the char var c; in this dialect they are the same identifier. Two compounding causes:

  1. ParseConstSection allocated a phantom var symbol for a typed set const (cIdx := AllocVar(name, tySet)) whose storage the comment already noted was "unused" — so C became a real tySet (32-byte aggregate) symbol that shadowed the char var.
  2. ParseFactor consulted FindSetConst(name) (case-insensitive) before the resolved variable symbol idx, so even without the phantom var the set const C would win over the char var c. Ord(c)/write(c) then loaded the set's address (aggregate by-ref) → garbage / segfault.

Fix (parser.inc):

Set-const usage (c in Vowels, untyped ['0'..'9']) still resolves via AN_SET_CONST_REF. Regression test/test_set_of_char_const.pas under make test. Self-host byte-identical; pinned v57.

The two "related const-codegen quirks" (untyped string const indexing; typed string const initializer) proved independent and are split to [[bug-string-const-index-and-typed-init]] in backlog.