What has to be decided, not just written
PXXMemCmp itself is small. The judgement is which runs are padding-free,
and getting that wrong reintroduces the defect the whole family exists for.
A run is safe to byte-compare when every byte in it is part of a field's value. That holds for an array of a scalar whose element size equals its storage size, and it does NOT hold for:
- an array of RECORDS, unless the element record is itself gap-free
(
sum of field spans = RecSize, recursively) — anarray[0..99] of record b: Byte; y: Int64 endhas 7 undefined bytes per element - an array of
AnsiStringor any managed type — a handle compare is identity, not content, which is the thing the field-wise walk fixed - any run that crosses a field boundary where the compiler inserted alignment padding
So the deliverable is a predicate — "is this field, or this contiguous span of
fields, gap-free" — and it belongs beside RecFieldCmpSpan in ir.inc, which
already computes the spans the overlap test uses.
A gap-free predicate is also worth more than this one caller. The same
question decides whether a record can be hashed or serialised as bytes, and
RecordHasManagedFields is the existing shape to model it on.
Acceptance
record v: array[0..999] of Integer end, differing at the LAST element,
expected FALSE on every target, and the emitted code must NOT grow with the
element count — measure it the way REC_CMP_UNROLL_MAX's comment records
(executables, ~20 comparison sites per build to clear the page quantum;
--emit-obj objects report a constant 64 bytes and measure nothing).
The must-fail row is the padded one: record v: array[0..999] of record b: Byte; y: Int64 end end with identical field values must still compare EQUAL.
If a byte-compare is taken over that run it answers FALSE, and that is the
defect this ticket must not reintroduce.