[java-inspection] IJ-CR-177592 IDEA-375813 It seems dataflow join works wrong for branching with division by zero

- added descriptions and a new option

GitOrigin-RevId: 4d105d96b1b8fd0bae8560134479c959aaaa7d20
This commit is contained in:
Mikhail Pyltsin
2025-10-06 13:15:06 +00:00
committed by intellij-monorepo-bot
parent f62c5ebc02
commit 789fdc06c6
3 changed files with 30 additions and 3 deletions
@@ -849,6 +849,9 @@ comparison.of.short.and.char.problem.descriptor=Equality comparison <code>#ref</
big.decimal.equals.problem.descriptor=<code>#ref()</code> between BigDecimal values should probably be 'compareTo()' #loc
divide.by.zero.problem.descriptor=Division by zero #loc
divide.by.zero.problem.may.descriptor=Maybe division by zero #loc
divide.by.zero.problem.may.option=Report conditional divide-by-zero
divide.by.zero.problem.may.option.description=Highlights divisions that can become zero in some execution branches
divide.by.zero.problem.may.option.disabled=Don't suggest conditional divide-by-zero problems
non.reproducible.math.call.problem.descriptor=<code>Math.#ref()</code> may produce non-reproducible results #loc
constant.math.call.problem.descriptor=Constant call to <code>#ref()</code> can be simplified #loc
floating.point.equality.problem.descriptor=<code>#ref</code>: floating-point values compared for exact equality #loc
@@ -17,10 +17,12 @@ package com.siyeh.ig.numeric;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.UpdateInspectionOptionFix;
import com.intellij.codeInspection.dataFlow.CommonDataflow;
import com.intellij.codeInspection.dataFlow.rangeSet.LongRangeSet;
import com.intellij.codeInspection.dataFlow.types.DfIntType;
import com.intellij.codeInspection.dataFlow.types.DfType;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
import com.intellij.openapi.project.Project;
@@ -41,8 +43,23 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
import static com.intellij.codeInspection.options.OptPane.checkbox;
import static com.intellij.codeInspection.options.OptPane.pane;
public final class DivideByZeroInspection extends BaseInspection {
@SuppressWarnings("PublicField")
public boolean reportMayBeZero = true;
@Override
public @NotNull OptPane getOptionsPane() {
return pane(
checkbox("reportMayBeZero",
InspectionGadgetsBundle.message("divide.by.zero.problem.may.option"))
.description(InspectionGadgetsBundle.message("divide.by.zero.problem.may.option.description")));
}
@Pattern(VALID_ID_PATTERN)
@Override
public @NotNull String getID() {
@@ -69,6 +86,11 @@ public final class DivideByZeroInspection extends BaseInspection {
}
}
}
if (infos.length > 1 && infos[1] instanceof ThreeState threeState && threeState == ThreeState.UNSURE) {
return LocalQuickFix.from(new UpdateInspectionOptionFix(
this, "reportMayBeZero",
InspectionGadgetsBundle.message("divide.by.zero.problem.may.option.disabled", false), false));
}
return null;
}
@@ -77,7 +99,7 @@ public final class DivideByZeroInspection extends BaseInspection {
return new DivisionByZeroVisitor();
}
private static class DivisionByZeroVisitor extends BaseInspectionVisitor {
private class DivisionByZeroVisitor extends BaseInspectionVisitor {
@Override
public void visitPolyadicExpression(@NotNull PsiPolyadicExpression expression) {
@@ -112,7 +134,7 @@ public final class DivideByZeroInspection extends BaseInspection {
}
}
private static ThreeState isZero(PsiExpression expression) {
private ThreeState isZero(PsiExpression expression) {
final Object value = ConstantExpressionUtil.computeCastTo(expression, PsiTypes.doubleType());
if (value instanceof Double) {
final double constantValue = ((Double)value).doubleValue();
@@ -123,6 +145,7 @@ public final class DivideByZeroInspection extends BaseInspection {
if (val != null) {
return val.doubleValue() == 0.0 ? ThreeState.YES : ThreeState.NO;
}
if(!reportMayBeZero) return ThreeState.NO;
if (dfType instanceof DfIntType dfIntType) {
LongRangeSet range = dfIntType.getRange();
List<LongRangeSet> ranges = range.asRanges();
@@ -5,6 +5,7 @@ Such expressions will produce an <code>Infinity</code>, <code>-Infinity</code> o
and will throw an <code>ArithmeticException</code> for integers.
<p>When the expression has a <code>NaN</code> result, the fix suggests replacing the division expression with the <code>NaN</code> constant.
<!-- tooltip end -->
<p>Use the <b>Report conditional divide-by-zero</b> option to report divisions where the divisor may be zero in some execution paths.
This may occasionally produce false positives.
</body>
</html>