From a813ef19b54be2cd264c738632d8168f232de9d4 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Wed, 13 Oct 2021 16:14:38 +0700 Subject: [PATCH] [java-dfa] FieldChecker: correctly find parent method if we are inside static analyzer DfaPsiUtil.getBlockNotNullFields may run DFA for static initializer block. If it happens to be a local/anonymous class inside a method, that outer method was incorrectly used as a context. This caused wrong state of FieldChecker and might eventually lead to StackOverflowError. GitOrigin-RevId: a96b4527cb03d77160be3579935e47d79bfca48c --- .../dataFlow/jvm/FieldChecker.java | 3 ++- .../dataFlow/fixture/StaticFieldInAnonymous.java | 16 ++++++++++++++++ .../codeInspection/DataFlowInspection16Test.java | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/StaticFieldInAnonymous.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/jvm/FieldChecker.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/jvm/FieldChecker.java index bbff36b44aba..d0cec80f8c8a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/jvm/FieldChecker.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/jvm/FieldChecker.java @@ -8,6 +8,7 @@ import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.util.ObjectUtils; import com.siyeh.ig.callMatcher.CallMatcher; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,7 +20,7 @@ public class FieldChecker { private final PsiClass myClass; private FieldChecker(PsiElement context) { - PsiMethod method = context instanceof PsiClass ? null : PsiTreeUtil.getParentOfType(context, PsiMethod.class); + PsiMethod method = ObjectUtils.tryCast(PsiTreeUtil.getNonStrictParentOfType(context, PsiMember.class), PsiMethod.class); PsiClass contextClass = method != null ? method.getContainingClass() : context instanceof PsiClass ? (PsiClass)context : null; myClass = contextClass; if (method == null || myClass == null) { diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/StaticFieldInAnonymous.java b/java/java-tests/testData/inspection/dataFlow/fixture/StaticFieldInAnonymous.java new file mode 100644 index 000000000000..3625f8db1107 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/StaticFieldInAnonymous.java @@ -0,0 +1,16 @@ +public class StaticFieldInAnonymous { + void test() { + Runnable r = new Runnable() { + private static final String s; + + static { + s = "foo"; + } + + @Override + public void run() { + if (s == null) {} + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection16Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection16Test.java index 41b42128b349..9ef2c01a8fc8 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection16Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection16Test.java @@ -38,4 +38,5 @@ public class DataFlowInspection16Test extends DataFlowInspectionTestCase { "public @interface NonnullByDefault {}"); doTest(); } + public void testStaticFieldInAnonymous() { doTest(); } } \ No newline at end of file