diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java index b9c3bd20501f..da18515c6cc9 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCatchSectionImpl.java @@ -128,7 +128,12 @@ public class PsiCatchSectionImpl extends CompositePsiElement implements PsiCatch // ... and T is assignable to Ej ... List types = new ArrayList<>(); for (PsiType type : uncaughtTypes) { - if (declaredType.isAssignableFrom(type) || type instanceof PsiClassType && ExceptionUtil.isUncheckedException((PsiClassType)type)) { + if (declaredType.isAssignableFrom(type) || + // from 11.2.3 exception checking + // It is a compile-time error if a catch clause can catch checked exception class E1 and it is not the case that the try block corresponding to the catch clause can + // throw a checked exception class that is a subclass or superclass of E1, unless E1 is Exception or a superclass of Exception. + // so here unchecked exception can sneak throw Exception or Throwable catch type only + ExceptionUtil.isGeneralExceptionType(declaredType) && type instanceof PsiClassType && ExceptionUtil.isUncheckedException((PsiClassType)type)) { types.add(type); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PreciseRethrowWithRuntimeExceptionDeclared.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PreciseRethrowWithRuntimeExceptionDeclared.java new file mode 100644 index 000000000000..abbb42b75061 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/PreciseRethrowWithRuntimeExceptionDeclared.java @@ -0,0 +1,19 @@ + +import java.io.FileNotFoundException; +import java.io.IOException; + +class MyTest { + + public void foo() { + try { + bar(); + } + catch (FileNotFoundException e) { + throw e; + } + catch (IOException ignored) { } + } + + private void bar() throws IOException, RuntimeException { } +} + diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingJdk7Test.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingJdk7Test.java index d7ae4346b7ae..fe0369d1936a 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingJdk7Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingJdk7Test.java @@ -143,6 +143,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { public void testPreciseRethrow() { doTest(false, false); } public void testPreciseRethrowNonAssignableToException() { doTest(false, false); } public void testPreciseRethrowOfOneExceptionInTheBlock() { doTest(false, false); } + public void testPreciseRethrowWithRuntimeExceptionDeclared() { doTest(false, false); } public void testImprovedCatchAnalysis() { doTest(true, false); } public void testPolymorphicTypeCast() { doTest(true, false); } public void testTypeCastInInstanceof() { doTest(true, false); }