Skip to content

Add explicit integer-width casts and improve pointer arithmetic#125

Merged
Xor-el merged 3 commits into
masterfrom
chore/fix-some-fpc-hints
Jun 30, 2026
Merged

Add explicit integer-width casts and improve pointer arithmetic#125
Xor-el merged 3 commits into
masterfrom
chore/fix-some-fpc-hints

Conversation

@Xor-el

@Xor-el Xor-el commented Jun 30, 2026

Copy link
Copy Markdown
Owner

No description provided.

Xor-el added 3 commits June 30, 2026 21:04
Add explicit width casts at sites where FPC's "Converting the operands to
Int64 before doing the add/subtract/multiply" and "Mixing signed expressions
and longwords gives a 64bit result" hints fire because a narrow (32-bit)
sub-operation feeds a wider expression. The casts make the intended width
explicit and silence the hints on both 32-bit and 64-bit; the computed values
are unchanged on every word size.

- ClpMlDsaCore.pas (NTT): Int64(LZeta) * (Int64(LA0) - Int64(LA1)) so the
  coefficient subtract widens before the multiply.
- ClpMlKemCore.pas (compress): (Int64(LC shl n) + (MlKemQ shr 8)) so the inner
  add runs in Int64; (decompress) cast the leading shift operand to UInt32 so
  the bit-packing OR no longer mixes a signed Int32 with a longword.
- ClpPoly1305.pas: (Int64(Int32(H4 shr 26)) - 1) * 5 so the subtract is Int64.
- ClpDateTimeUtilities.pas: Int64(LOffsetHours) * 60 + LOffsetMinutes for the
  UTC offset (IncMinute already takes Int64).

Deliberately left untouched: TMod.Inverse32, TX448Field.Sub, and the ML-DSA
eta=2 mod-5 reduction. Their hints are 32-bit-only false positives over
intentional fixed-width (UInt32) modular arithmetic; FPC flags any
UInt32*UInt32 / UInt32+UInt32 on a 32-bit target regardless of casts, and
widening to Int64 would be wrong for Inverse32 (it relies on mod-2^32
wraparound). These are left as the original code rather than suppressed.
FPC flags "Conversion between ordinals and pointers is not portable" at sites
that cast a pointer through NativeUInt. These are false positives (NativeUInt is
pointer-sized on all targets, so the conversions are size-safe on Delphi/FPC and
32/64-bit), but the sites that only need address arithmetic or comparison can
drop the integer round-trip entirely, since {$POINTERMATH ON} is global.

- ClpOcbBlockCipher.pas: compute the block-0 lookahead pointer with pointer
  arithmetic, PByte(@ainput[AInOff]) - BLOCK_SIZE, instead of
  Pointer(NativeUInt(@ainput[AInOff]) - BLOCK_SIZE). Removes the hint and the
  warning; same address.
- ClpAesEngineX86.pas (ProcessBlock / ProcessFourBlocks / ProcessEightBlocks):
  do the disjoint-vs-overlap test by comparing the PByte arguments directly
  (AOutput >= AInput, AOutput < AInput + N) and drop the now-unused
  LSrcAddr/LDstAddr NativeUInt locals. Pointer relational comparison is the same
  unsigned address comparison the NativeUInt casts performed.

Left untouched: the alignment fast-path tests in ClpBinaryPrimitives.Swap*,
ClpByteUtilities.Xor/XorTo, and TAesEngineX86.AllocAlignedKeys. These genuinely
need the address as an integer for `and`-masking, so their (harmless) hints
remain - no type alias, no suppression.
@Xor-el Xor-el merged commit 4fe7655 into master Jun 30, 2026
36 checks passed
@Xor-el Xor-el deleted the chore/fix-some-fpc-hints branch June 30, 2026 23:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant