Skip to content

Commit 05c4b0d

Browse files
committed
Fix FPs around binary expressions in PlatformDependentTruncation
1 parent 66b6c55 commit 05c4b0d

File tree

3 files changed

+92
-5
lines changed

3 files changed

+92
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Fixed
1111

1212
- Various intrinsic routines had incorrect signatures around dynamic and open arrays.
13+
- False positives around platform-dependent binary expressions in `PlatformDependentTruncation`.
1314

1415
## [1.12.0] - 2024-12-02
1516

delphi-checks/src/main/java/au/com/integradev/delphi/checks/PlatformDependentTruncationCheck.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.sonar.plugins.communitydelphi.api.ast.ArgumentListNode;
2424
import org.sonar.plugins.communitydelphi.api.ast.ArgumentNode;
2525
import org.sonar.plugins.communitydelphi.api.ast.AssignmentStatementNode;
26+
import org.sonar.plugins.communitydelphi.api.ast.BinaryExpressionNode;
2627
import org.sonar.plugins.communitydelphi.api.ast.ExpressionNode;
2728
import org.sonar.plugins.communitydelphi.api.ast.NameReferenceNode;
2829
import org.sonar.plugins.communitydelphi.api.ast.Node;
@@ -44,7 +45,7 @@ public class PlatformDependentTruncationCheck extends DelphiCheck {
4445

4546
@Override
4647
public DelphiCheckContext visit(AssignmentStatementNode assignment, DelphiCheckContext context) {
47-
if (isViolation(assignment.getValue().getType(), assignment.getAssignee().getType())) {
48+
if (isViolation(assignment.getValue(), assignment.getAssignee().getType())) {
4849
reportIssue(context, assignment, MESSAGE);
4950
}
5051
return super.visit(assignment, context);
@@ -66,7 +67,7 @@ public DelphiCheckContext visit(ArgumentListNode argumentList, DelphiCheckContex
6667
List<Parameter> parameters = procedural.parameters();
6768
for (int i = 0; i < arguments.size() && i < parameters.size(); ++i) {
6869
ExpressionNode argument = arguments.get(i).getExpression();
69-
if (isViolation(argument.getType(), parameters.get(i).getType())) {
70+
if (isViolation(argument, parameters.get(i).getType())) {
7071
reportIssue(context, argument, MESSAGE);
7172
}
7273
}
@@ -84,16 +85,26 @@ private static ProceduralType getProceduralType(NameReferenceNode reference) {
8485
return null;
8586
}
8687

87-
private static boolean isViolation(Type from, Type to) {
88-
if (!from.isInteger() || !to.isInteger()) {
88+
private static boolean isViolation(ExpressionNode from, Type to) {
89+
if (!from.getType().isInteger() || !to.isInteger()) {
8990
return false;
9091
}
9192

9293
if (isNativeInteger(from) == isNativeInteger(to)) {
9394
return false;
9495
}
9596

96-
return (isNativeInteger(from) && to.size() < 8) || (isNativeInteger(to) && from.size() > 4);
97+
return (isNativeInteger(from) && to.size() < 8)
98+
|| (isNativeInteger(to) && from.getType().size() > 4);
99+
}
100+
101+
private static boolean isNativeInteger(ExpressionNode expression) {
102+
expression = expression.skipParentheses();
103+
if (expression instanceof BinaryExpressionNode) {
104+
BinaryExpressionNode binary = (BinaryExpressionNode) expression;
105+
return isNativeInteger(binary.getLeft()) || isNativeInteger(binary.getRight());
106+
}
107+
return isNativeInteger(expression.getType());
97108
}
98109

99110
private static boolean isNativeInteger(Type type) {

delphi-checks/src/test/java/au/com/integradev/delphi/checks/PlatformDependentTruncationCheckTest.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import au.com.integradev.delphi.builders.DelphiTestUnitBuilder;
2222
import au.com.integradev.delphi.checks.verifier.CheckVerifier;
2323
import au.com.integradev.delphi.compiler.CompilerVersion;
24+
import au.com.integradev.delphi.compiler.Toolchain;
2425
import org.junit.jupiter.params.ParameterizedTest;
2526
import org.junit.jupiter.params.provider.ValueSource;
2627

@@ -207,4 +208,78 @@ void testNativeIntArgumentToNativeIntParameterShouldNotAddIssue(String versionSy
207208
.appendImpl("end;"))
208209
.verifyNoIssues();
209210
}
211+
212+
@ParameterizedTest
213+
@ValueSource(strings = {VERSION_ALEXANDRIA, VERSION_ATHENS})
214+
void testNativeIntAssignmentInBinaryExpressionShouldNotAddIssue(String versionSymbol) {
215+
CheckVerifier.newVerifier()
216+
.withCheck(new PlatformDependentTruncationCheck())
217+
.withCompilerVersion(CompilerVersion.fromVersionSymbol(versionSymbol))
218+
.withToolchain(Toolchain.DCC64)
219+
.onFile(
220+
new DelphiTestUnitBuilder()
221+
.appendImpl("procedure Foo;")
222+
.appendImpl("var")
223+
.appendImpl(" Nat: NativeInt;")
224+
.appendImpl("begin")
225+
.appendImpl(" Nat := Nat + 1;")
226+
.appendImpl("end;"))
227+
.verifyNoIssues();
228+
}
229+
230+
@ParameterizedTest
231+
@ValueSource(strings = {VERSION_ALEXANDRIA, VERSION_ATHENS})
232+
void testNativeIntArgumentInBinaryExpressionShouldNotAddIssue(String versionSymbol) {
233+
CheckVerifier.newVerifier()
234+
.withCheck(new PlatformDependentTruncationCheck())
235+
.withCompilerVersion(CompilerVersion.fromVersionSymbol(versionSymbol))
236+
.withToolchain(Toolchain.DCC64)
237+
.onFile(
238+
new DelphiTestUnitBuilder()
239+
.appendDecl("procedure Bar(Nat: NativeInt);")
240+
.appendImpl("procedure Foo;")
241+
.appendImpl("var")
242+
.appendImpl(" Nat: NativeInt;")
243+
.appendImpl("begin")
244+
.appendImpl(" Bar(Nat + 1);")
245+
.appendImpl("end;"))
246+
.verifyNoIssues();
247+
}
248+
249+
@ParameterizedTest
250+
@ValueSource(strings = {VERSION_ALEXANDRIA, VERSION_ATHENS})
251+
void testNativeIntAssignmentInNestedBinaryExpressionShouldNotAddIssue(String versionSymbol) {
252+
CheckVerifier.newVerifier()
253+
.withCheck(new PlatformDependentTruncationCheck())
254+
.withCompilerVersion(CompilerVersion.fromVersionSymbol(versionSymbol))
255+
.withToolchain(Toolchain.DCC64)
256+
.onFile(
257+
new DelphiTestUnitBuilder()
258+
.appendImpl("procedure Foo;")
259+
.appendImpl("var")
260+
.appendImpl(" Nat: NativeInt;")
261+
.appendImpl("begin")
262+
.appendImpl(" Nat := (Nat + 1) + 1;")
263+
.appendImpl("end;"))
264+
.verifyNoIssues();
265+
}
266+
267+
@ParameterizedTest
268+
@ValueSource(strings = {VERSION_ALEXANDRIA, VERSION_ATHENS})
269+
void testPlatformDependentCastInBinaryExpressionShouldNotAddIssue(String versionSymbol) {
270+
CheckVerifier.newVerifier()
271+
.withCheck(new PlatformDependentTruncationCheck())
272+
.withCompilerVersion(CompilerVersion.fromVersionSymbol(versionSymbol))
273+
.withToolchain(Toolchain.DCC64)
274+
.onFile(
275+
new DelphiTestUnitBuilder()
276+
.appendImpl("procedure Foo;")
277+
.appendImpl("var")
278+
.appendImpl(" Int: Integer;")
279+
.appendImpl(" Nat: NativeInt;")
280+
.appendImpl("begin")
281+
.appendImpl(" Int := Integer(Nat) + 1;")
282+
.appendImpl("end;"))
283+
.verifyNoIssues();
284+
}
210285
}

0 commit comments

Comments
 (0)