diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java index 58ad1e3f4444..8a6fbac53fc5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java @@ -306,7 +306,8 @@ public class StandardInstructionVisitor extends InstructionVisitor { public DfaInstructionState[] visitTypeCast(TypeCastInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { PsiType type = instruction.getCastTo(); final DfaValueFactory factory = runner.getFactory(); - if (PsiUtil.resolveClassInType(type) != null && !memState.castTopOfStack(factory.createDfaType(type))) { + PsiType fromType = instruction.getCasted().getType(); + if (fromType != null && type.isConvertibleFrom(fromType) && !memState.castTopOfStack(factory.createDfaType(type))) { onInstructionProducesCCE(instruction); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraint.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraint.java index 77933e6aca2f..a445899d05c4 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraint.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TypeConstraint.java @@ -16,10 +16,7 @@ package com.intellij.codeInspection.dataFlow; import com.intellij.codeInspection.dataFlow.value.DfaPsiType; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiClassType; -import com.intellij.psi.PsiPrimitiveType; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; import com.intellij.util.containers.ContainerUtil; import one.util.streamex.EntryStream; import one.util.streamex.MoreCollectors; @@ -84,7 +81,11 @@ public final class TypeConstraint { @Nullable public TypeConstraint withInstanceofValue(@NotNull DfaPsiType type) { - if (type.getPsiType() instanceof PsiPrimitiveType) return this; + PsiType psiType = type.getPsiType(); + if (psiType instanceof PsiPrimitiveType || psiType instanceof PsiLambdaExpressionType || + psiType instanceof PsiMethodReferenceType) { + return this; + } if (!checkInstanceofValue(type)) { return null; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java index 0c0f8a960811..b45088a16d17 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java @@ -84,9 +84,14 @@ public class DfaValueFactory { @NotNull public DfaPsiType createDfaType(@NotNull PsiType psiType) { + int dimensions = psiType.getArrayDimensions(); + psiType = psiType.getDeepComponentType(); if (psiType instanceof PsiClassType) { psiType = ((PsiClassType)psiType).rawType(); } + while (dimensions-- > 0) { + psiType = psiType.createArrayType(); + } DfaPsiType dfaType = myDfaTypes.get(psiType); if (dfaType == null) { myDfaTypes.put(psiType, dfaType = new DfaPsiType(psiType, myAssignableCache, myConvertibleCache)); @@ -205,9 +210,7 @@ public class DfaValueFactory { final PsiJavaCodeReferenceElement thisQualifier = ((PsiQualifiedExpression)qualifier).getQualifier(); if (thisQualifier == null) return true; final PsiClass innerMostClass = PsiTreeUtil.getParentOfType(refExpression, PsiClass.class); - if (innerMostClass == thisQualifier.resolve()) { - return true; - } + return innerMostClass == thisQualifier.resolve(); } return false; } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/CastInstanceOf.java b/java/java-tests/testData/inspection/dataFlow/fixture/CastInstanceOf.java index 561e0dd76e22..b20f5e680de5 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/CastInstanceOf.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/CastInstanceOf.java @@ -21,4 +21,24 @@ class Test { } } } + + void testUncheckedCast(List list) { + List l = (List)(List)list; + } + + void testArrayCast(List[] arr) { + List[] arr2 = (List[])(List[])arr; + } + + void testTwoObj(boolean b, Object o1, Object o2) { + if((b && o1 instanceof String) || o2 instanceof String) { + String x = (String)(b ? o1 : o2); + } + } + + void method(Object obj) {} + + void testLambdaExpression() { + method((Runnable) () -> {}); + } } diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java index 400c46249a95..b3cb2f649e5f 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java @@ -206,4 +206,5 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase { doTest(); } + public void testCastInstanceOf() { doTest(); } } \ 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 cedf2b972de1..61270d7f0835 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -549,5 +549,4 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testTryWithResourceExpressions() { doTest(); } public void testArrayStoreProblems() { doTest(); } - public void testCastInstanceOf() { doTest(); } }