Skip to content

Fix FPs around binary expressions in PlatformDependentTruncation #320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 6, 2024

Conversation

cirras
Copy link
Collaborator

@cirras cirras commented Dec 5, 2024

Problem

Under 64-bit toolchains, PlatformDependentTruncation currently produces false positives around binary expressions with platform-dependent operands.

Example

procedure Test(Nat: NativeInt);
begin
  Nat := Nat + 1;
end;
  • On a 64-bit toolchain, the expression Nat + 1 has result type Int64 because the Int64 overload of the Add operator intrinsic is selected.
  • On a 64-bit toolchain, the assignment expression is <NativeInt> = <Int64>, and so the rule says "hey, Int64 doesn't fit into NativeInt on 32-bit, that will truncate!"
  • What the rule doesn't understand is that, on a 32-bit toolchain, a different overload of the Add operator intrinsic will be selected and the result type will be Integer - giving us an effective expression of <32-bit NativeInt> = <Integer> on that toolchain.

Solution

Recursively check the operands of binary expression for platform-dependent operands - the whole expression is considered platform-dependent if any of the operands are.

Is this the right solution?

Kind of. It's certainly the right solution for solving this narrowly-scoped problem with binary expressions.

In the grand scheme it's more of a half-measure that covers common cases like NativeInt + 1 "decaying" to Integer/Int64 and causing really stupid-looking false positives.

There are still holes in this rule's reasoning that we should try to tackle at some stage, but it's non-trivial and would require some solid heuristics - or support for emulating name resolution in a granular way on different toolchains from within rule implementations.

What kind of holes?

procedure GetPlatformIndependentType(Int: Integer): Integer; overload;
begin
  Result := Int;
end;

procedure GetPlatformIndependentType(I64: Int64): Integer; overload;
begin
  Result := I64;
end;

procedure Test(Nat: NativeInt);
begin
  Nat := GetPlatformIndependentType(Nat); // This will cause false positives on 64-bit toolchains.
end;

@cirras cirras requested a review from fourls December 5, 2024 08:28
Copy link
Collaborator

@fourls fourls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@cirras cirras merged commit 05c4b0d into master Dec 6, 2024
5 checks passed
@cirras cirras deleted the nativeint_decay branch December 6, 2024 00:18
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.

2 participants