Skip to content

SONARJAVA-6874 S9351: Fix FPs on null checks and normalized scales - #6057

Merged
nathsou merged 2 commits into
masterfrom
nathan/rc-289-fix-bigdecimal-fps
Aug 28, 2026
Merged

SONARJAVA-6874 S9351: Fix FPs on null checks and normalized scales#6057
nathsou merged 2 commits into
masterfrom
nathan/rc-289-fix-bigdecimal-fps

Conversation

@nathsou

@nathsou nathsou commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Fixes SONARJAVA-6874.

Summary

  • Ignore Objects.equals and Guava Objects.equal calls when either operand is a null literal.
  • Ignore equality comparisons between two resolved BigDecimal.setScale calls with the same compile-time scale.
  • Keep one-sided, differing-scale, runtime-scale, and unresolved cases noncompliant.

Test

  • mvn -pl java-checks -Dtest=BigDecimalEqualsCheckTest test

@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

RC-289

@nathsou nathsou self-assigned this Aug 28, 2026
@gitar-bot

gitar-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 3 resolved / 3 findings

Fixes false positives in S9351 by ignoring Objects.equals/Objects.equal calls with null-literal operands and equality comparisons between two BigDecimal.setScale calls with matching compile-time scales. Inherited setScale calls now resolve correctly. Update the rule description's Exceptions section in S9351.html to document the two new exemptions so the published rule doc matches the implementation.

✅ 3 resolved
Bug: SET_SCALE uses ofTypes, so subclass receivers keep the FP

📄 java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java:54-60 📄 java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java:105-111 📄 java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java:80-88 📄 java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java:85-88
SET_SCALE is built with .ofTypes(BIG_DECIMAL), and MethodMatchersBuilder.ofTypes tests type.is(name) against the call-site (receiver) type, so setScale invoked on a declared subtype of BigDecimal never matches. Concrete trigger: with class MyBigDecimal extends BigDecimal (already present in the sample file), myBd.setScale(2).equals(other.setScale(2)) — where other is also a MyBigDecimal — still reports an issue, even though it is exactly the normalized-scale pattern this PR set out to exempt; INSTANCE_EQUALS deliberately uses ofSubTypes, so the two matchers now disagree about what a BigDecimal is. Use .ofSubTypes(BIG_DECIMAL) for SET_SCALE and add a subclass same-scale case to the compliant test block.

Bug: Null-literal exception not applied to instance equals(null)

📄 java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java:73-87 📄 java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java:36-40
hasNullArgument is only consulted on the STATIC_EQUALS branch, so a.equals(null) (where a is a BigDecimal) is still reported, and the reported remediation — a.compareTo(null) == 0 — throws NullPointerException, making the advice actively wrong. This is the same null-check false positive the PR fixes for Objects.equals/Objects.equal, left on the old form for the instance form; apply hasNullArgument(mit.arguments()) to the INSTANCE_EQUALS branch too and add res = a.equals(null); to the compliant test block.

Quality: S9351 Exceptions section omits the two new exemptions

📄 java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java:81-83
The rule description's "Exceptions" section documents only the equals(Object)-declaration exemption, but this PR adds two more behaviours users will observe: null-literal operands of Objects.equals/Objects.equal are ignored, and equality between two setScale(...) calls with the same compile-time scale is ignored. Leaving the HTML unchanged means the published rule doc contradicts the implementation (a reader would expect a.setScale(2).equals(b.setScale(2)) to raise). Add both exemptions to the Exceptions section of S9351.html.

Implementation Status ✅ 4 of 4 objectives covered
RC-289 - 2 of 2 objectives covered

This PR covers both objectives by avoiding false positives on null checks in static equality helpers and scale-normalized BigDecimal equals calls.

✅ 2 covered here
  • ✅ Do not report java.util.Objects.equals or com.google.common.base.Objects.equal calls when either argument is a null literal or null type
  • ✅ Do not report BigDecimal.equals or static equality helper calls when both operands are resolved invocations of java.math.BigDecimal.setScale with the same integer constant scale
SONARJAVA-6874 - 2 of 2 objectives covered

This PR covers both objectives by skipping S9351 reports on static equality helpers with null arguments and on equals comparisons where both operands are setScale calls with identical constant scales.

✅ 2 covered here
  • ✅ Do not report java.util.Objects.equals and com.google.common.base.Objects.equal calls when either argument is the null literal or null type
  • ✅ Do not report instance or static BigDecimal equals calls when both operands are resolved invocations of java.math.BigDecimal.setScale with the same integer constant scale
Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqube-next

Copy link
Copy Markdown
Contributor

@nathsou nathsou changed the title RC-289 S9351: Fix FPs on null checks and normalized scales SONARJAVA-6874 S9351: Fix FPs on null checks and normalized scales Aug 28, 2026
@nathsou
nathsou merged commit d5e595e into master Aug 28, 2026
21 checks passed
@nathsou
nathsou deleted the nathan/rc-289-fix-bigdecimal-fps branch August 28, 2026 14:25
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