diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/dataFlow/ConstantValueInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/dataFlow/ConstantValueInspection.java
index 9776b7b24423..4b7cbc2f62bf 100644
--- a/java/java-impl-inspections/src/com/intellij/codeInspection/dataFlow/ConstantValueInspection.java
+++ b/java/java-impl-inspections/src/com/intellij/codeInspection/dataFlow/ConstantValueInspection.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
+import com.intellij.psi.controlFlow.DefUseUtil;
import com.intellij.psi.impl.source.PsiFieldImpl;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
@@ -429,6 +430,10 @@ public class ConstantValueInspection extends AbstractBaseJavaLocalInspectionTool
if (PsiUtil.skipParenthesizedExprUp(psiAnchor.getParent()) instanceof PsiAssignmentExpression assignment &&
PsiTreeUtil.isAncestor(assignment.getLExpression(), psiAnchor, false)) {
+ IElementType tokenType = assignment.getOperationTokenType();
+ if (tokenType.equals(JavaTokenType.ANDEQ) || tokenType.equals(JavaTokenType.OREQ)) {
+ if (isFlagSetChain(assignment.getLExpression(), tokenType.equals(JavaTokenType.ANDEQ))) return;
+ }
reporter.registerProblem(
psiAnchor,
JavaAnalysisBundle.message("dataflow.message.pointless.assignment.expression", Boolean.toString(evaluatesToTrue)),
@@ -456,6 +461,18 @@ public class ConstantValueInspection extends AbstractBaseJavaLocalInspectionTool
reporter.registerProblem(psiAnchor, message, fixes.toArray(LocalQuickFix.EMPTY_ARRAY));
}
+ private static boolean isFlagSetChain(@NotNull PsiExpression expression, boolean isAnd) {
+ PsiLocalVariable local = ExpressionUtils.resolveLocalVariable(expression);
+ if (local == null) return false;
+ PsiExpression initializer = local.getInitializer();
+ if (!ExpressionUtils.isLiteral(initializer, isAnd)) return false;
+ if (!(PsiUtil.getVariableCodeBlock(local, null) instanceof PsiCodeBlock block)) return false;
+ PsiElement[] defs = DefUseUtil.getDefs(block, local, expression.getParent());
+ // boolean x = false; x|=something;
+ return defs.length == 1 && defs[0] == local &&
+ VariableAccessUtils.getVariableReferences(local, block).stream().filter(PsiUtil::isAccessedForWriting).limit(2).count() > 1;
+ }
+
private static @Nullable LocalQuickFix createSimplifyBooleanExpressionFix(PsiElement element, final boolean value) {
LocalQuickFixOnPsiElement fix = createSimplifyBooleanFix(element, value);
if (fix == null) return null;
diff --git a/java/java-tests/testData/inspection/dataFlow/ancient/AndEq.java b/java/java-tests/testData/inspection/dataFlow/ancient/AndEq.java
index fce099daa2c1..065cc91db952 100644
--- a/java/java-tests/testData/inspection/dataFlow/ancient/AndEq.java
+++ b/java/java-tests/testData/inspection/dataFlow/ancient/AndEq.java
@@ -1,7 +1,7 @@
class Test {
public void foo(boolean x, boolean y, boolean z) {
boolean r = true;
- r &= x;
+ r &= x;
r &= y;
r &= z;
}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/BooleanOrEquals.java b/java/java-tests/testData/inspection/dataFlow/fixture/BooleanOrEquals.java
new file mode 100644
index 000000000000..6f80de67991a
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/BooleanOrEquals.java
@@ -0,0 +1,22 @@
+// IDEA-304296
+class BooleanOrEquals {
+ boolean test() {
+ boolean result = false;
+ result |= check1();
+ result |= check2();
+ result |= check3();
+ return result;
+ }
+
+ boolean testWrong() {
+ boolean result = true;
+ result |= check1();
+ result |= check2();
+ result |= check3();
+ return result;
+ }
+
+ native boolean check1();
+ native boolean check2();
+ native boolean check3();
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java
index dc8d471812c2..b377c0809034 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java
@@ -722,4 +722,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
public void testSuppression() { doTest(); }
public void testRewiringSubclassMethod() { doTest(); }
public void testTryWithResourcesCloseThrows() { doTest(); }
+ public void testBooleanOrEquals() { doTest(); }
}