SONARJAVA-6838: Fix FP on S9354: ignore subtraction of operands with a provably bounded range - #6002
Conversation
… provably bounded range
This comment has been minimized.
This comment has been minimized.
…ution, add coverage, sync rule HTML
|
❌ Ruling needs updating. A fix PR has been created: #6003 Please review and merge it into your branch. |
Ruling Diff SummaryDetected changes in 1 rule files: 12 issues removed, 0 issues added. S9354 (
|
|
❌ Ruling needs updating. A fix PR has been created: #6003 Please review and merge it into your branch. |
…fy new-code coverage
…ple file Per review feedback, most scenarios are expressible as real compare()/compareTo() bodies and are now tested end-to-end like the rest of the check, instead of via direct AST construction. Only the long-constant case remains a direct unit test, since it is unreachable from any real check call site.
Code Review ✅ Approved 1 resolved / 1 findingsFixes false positives in S9354 by ignoring subtractions of operands with provably bounded ranges, addressing the bitwiseAndRange unsoundness finding. ✅ 1 resolved✅ Edge Case: bitwiseAndRange unsound for int masks with sign bit set
Implementation Status 🟡 0 / 1 issues implemented⬜ SONARJAVA-6838 — 0 / 8 objectivesThe PR contains no file diffs to evaluate the objectives.
OptionsAuto-apply is off → Gitar will not commit updates to this branch. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar |
|




Summary
A Peach false-positive run sampled 366 S9354 issues and found 60 false positives (16.4%). About 45 of them subtract two operands whose value range is provably bounded, so the subtraction cannot overflow: array/String lengths,
Collection/Map.size(),Enum.ordinal(),Integer/Long.bitCount()and related bit-scan intrinsics, values masked with a non-negative bitwiseANDconstant, and compile-time constants. The check previously decided purely from operand type (int/long), so every one of these was reported.BoundedIntegerRange, computing a best-effort[lo, hi]range for an expression and testing whether two ranges make an int subtraction safe (hi - otherLo <= Integer.MAX_VALUE && lo - otherHi >= Integer.MIN_VALUE). This subsumes the existingbyte/short/charexemption and generalizes to any boundedintvalue, including single-write locals resolved via the existingExpressionsHelper.getSingleWriteUsage.IntegerSubtractionInComparisonCheck.replacementForonly for theInteger.comparebranch (both operandsint), leavingLong.comparecases unaffected — none of the sampled false positives involvelongoperands, and exempting boundedlongs (e.g.java.timenanosecond fields) would require API invariants outside the type system.String.length(),Collection.size(),Map.size(),Enum.ordinal(),Integer.bitCount(), masked bytes direct and via locals, single-write local length, literal constants) and noncompliant guard cases for a mixed bounded/unbounded subtraction and an unknown-rangehashCode()subtraction, to catch a regression that would weaken the "both operands must be bounded" requirement to "either operand".Intentionally out of scope, and still reported:
indexOf()results ([-1, size-1], soInteger.MAX_VALUE - (-1)overflows in principle),java.time.Duration/Instantinternal nanosecond fields,java.lang.Enum.ordinalraw field access (only reachable in JDK source, unlike the.ordinal()method call which is now recognized), values from unrelated helper methods, and values bounded only by runtime assertions.Links
AI disclosure