boolean (PsiBinaryExpression binaryExpression) { final PsiType type = binaryExpression.getType(); if (type == null) return true; if (PsiTypes.floatType().equals(type) || PsiTypes.doubleType().equals(type)) { // Difference of floats and doubles never overflows. // It may lose a precision, but it's not the case when we compare the result with zero PsiElement parent = PsiUtil.skipParenthesizedExprUp(binaryExpression.getParent()); if(parent instanceof PsiTypeCastExpression) { PsiType castType = ((PsiTypeCastExpression)parent).getType(); if(PsiTypes.intType().equals(castType) || PsiTypes.longType().equals(castType)) { // Precision is lost if result is cast to int/long (e.g. (int)(1.0 - 0.5) == 0) return false; } } return true; } if (ExpressionUtils.isEvaluatedAtCompileTime(binaryExpression)) { // If compile time expression overflows, we have separate NumericOverflowInspection for this return true; } final PsiExpression lhs = binaryExpression.getLOperand(); final PsiExpression rhs = binaryExpression.getROperand(); if (rhs == null) return true; final PsiType lhsType = lhs.getType(); final PsiType rhsType = rhs.getType(); if (lhsType == null || rhsType == null) { return false; } if ((PsiTypes.byteType().equals(lhsType) || PsiTypes.shortType().equals(lhsType) || PsiTypes.charType().equals(lhsType)) && (PsiTypes.byteType().equals(rhsType) || PsiTypes.shortType().equals(rhsType) || PsiTypes.charType().equals(rhsType))) { return true; } if (isSafeOperand(lhs) && isSafeOperand(rhs)) return true; LongRangeSet leftRange = CommonDataflow.getExpressionRange(lhs); LongRangeSet rightRange = CommonDataflow.getExpressionRange(rhs); if (leftRange != null && !leftRange.isEmpty() && rightRange != null && !rightRange.isEmpty()) { if (!leftRange.subtractionMayOverflow(rightRange, JvmPsiRangeSetUtil.getLongRangeType(type))) return true; } return false; }