diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
index df5f8a45394b..0e540eaa944f 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
+++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
@@ -34,10 +34,7 @@ import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
class ControlFlowAnalyzer extends JavaElementVisitor {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer");
@@ -639,28 +636,37 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
for (int i = myCatchStack.size() - 1; i >= 0; i--) {
CatchDescriptor cd = myCatchStack.get(i);
if (cd.isFinally()) {
- pushUnknown();
- final ConditionalGotoInstruction branch = new ConditionalGotoInstruction(-1, false, null);
- addInstruction(branch);
- addInstruction(new EmptyStackInstruction());
- addInstruction(new GosubInstruction(cd.getJumpOffset()));
- addInstruction(new ReturnInstruction());
- branch.setOffset(myCurrentFlow.getInstructionCount());
+ addConditionalRuntimeThrow(cd, false);
+ continue;
}
- else if (cd.getType() instanceof PsiClassType &&
- ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)cd.getType())) {
- pushUnknown();
- final ConditionalGotoInstruction branch = new ConditionalGotoInstruction(-1, false, null);
- addInstruction(branch);
- addInstruction(new EmptyStackInstruction());
- addInstruction(new PushInstruction(myFactory.getNotNullFactory().create(myRuntimeException), null));
- addGotoCatch(cd);
- branch.setOffset(myCurrentFlow.getInstructionCount());
- return;
+
+ PsiType type = cd.getType();
+ if (type instanceof PsiDisjunctionType) {
+ type = ((PsiDisjunctionType)type).getLeastUpperBound();
+ }
+ if (type instanceof PsiClassType && ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)type)) {
+ addConditionalRuntimeThrow(cd, true);
+ break;
}
}
}
+ private void addConditionalRuntimeThrow(CatchDescriptor cd, boolean forCatch) {
+ pushUnknown();
+ final ConditionalGotoInstruction branch = new ConditionalGotoInstruction(-1, false, null);
+ addInstruction(branch);
+ addInstruction(new EmptyStackInstruction());
+ if (forCatch) {
+ addInstruction(new PushInstruction(myFactory.getNotNullFactory().create(myRuntimeException), null));
+ addGotoCatch(cd);
+ }
+ else {
+ addInstruction(new GosubInstruction(cd.getJumpOffset()));
+ addInstruction(new ReturnInstruction());
+ }
+ branch.setOffset(myCurrentFlow.getInstructionCount());
+ }
+
private void addThrowCode(PsiType exceptionClass) {
if (exceptionClass == null) return;
for (int i = myCatchStack.size() - 1; i >= 0; i--) {
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/CatchRuntimeException.java b/java/java-tests/testData/inspection/dataFlow/fixture/CatchRuntimeException.java
index 1967eb4478ae..193b3bcf81c4 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/CatchRuntimeException.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/CatchRuntimeException.java
@@ -3,8 +3,8 @@ import org.jetbrains.annotations.NotNull;
public class BrokenAlignment {
@NotNull
- Object test(){
- try{
+ Object test1() {
+ try {
bar(null);
return null;
}
@@ -13,6 +13,28 @@ public class BrokenAlignment {
}
}
+ @NotNull
+ Object test2() {
+ try {
+ bar(null);
+ return null;
+ }
+ catch (IllegalArgumentException | IllegalStateException e) {
+ return null;
+ }
+ }
+
+ @NotNull
+ Object test3() {
+ try {
+ bar(null);
+ return null;
+ }
+ catch (AssertionError | IllegalStateException e) {
+ return null;
+ }
+ }
+
public void bar(@NotNull Object foo) {
assert foo != null;
}