mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-dfa] Assume that pure call may still flush private fields
Fixes IDEA-288570 Constant conditions & exceptions thinks that Iterator.hasNext() cannot modify a private field GitOrigin-RevId: 116a0ca754004574fe6d789db1889a52d9057bfd
This commit is contained in:
committed by
intellij-monorepo-bot
parent
94fdaa6311
commit
744d5ee012
@@ -19,6 +19,7 @@ import com.intellij.codeInspection.dataFlow.java.JavaDfaValueFactory;
|
||||
import com.intellij.codeInspection.dataFlow.memory.DfaMemoryState;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.siyeh.ig.psiutils.MethodCallUtils;
|
||||
@@ -76,6 +77,13 @@ public final class DfaCallArguments {
|
||||
return;
|
||||
}
|
||||
if (myMutation.isPure()) {
|
||||
if (myQualifier instanceof DfaVariableValue) {
|
||||
DfaVariableValue qualifier = (DfaVariableValue)myQualifier;
|
||||
// We assume that even pure call may modify private fields (e.g., to cache something)
|
||||
state.flushVariables(v -> v.getQualifier() == qualifier &&
|
||||
v.getPsiVariable() instanceof PsiMember &&
|
||||
((PsiMember)v.getPsiVariable()).hasModifierProperty(PsiModifier.PRIVATE));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (myMutation == MutationSignature.UNKNOWN || myArguments == null) {
|
||||
|
||||
+4
-1
@@ -152,7 +152,10 @@ public class JavaDfaValueFactory {
|
||||
PsiClass memberClass = ((PsiMember)element).getContainingClass();
|
||||
if (memberClass != null && currentClass != null) {
|
||||
PsiClass target;
|
||||
if (currentClass == memberClass || InheritanceUtil.isInheritorOrSelf(currentClass, memberClass, true)) {
|
||||
PsiElement refName = refExpr.getReferenceNameElement();
|
||||
if (currentClass == memberClass ||
|
||||
(!(refName instanceof PsiKeyword && ((PsiKeyword)refName).getTokenType() == JavaTokenType.SUPER_KEYWORD) &&
|
||||
InheritanceUtil.isInheritorOrSelf(currentClass, memberClass, true))) {
|
||||
target = currentClass;
|
||||
}
|
||||
else {
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import java.util.*;
|
||||
|
||||
class Test implements Iterator<String> {
|
||||
String myNext;
|
||||
|
||||
public boolean hasNext() {
|
||||
myNext = "test";
|
||||
return true;
|
||||
}
|
||||
|
||||
public String next() {
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
return myNext;
|
||||
}
|
||||
|
||||
void test() {
|
||||
int merged = 0;
|
||||
while (hasNext()) {
|
||||
assert myNext != null;
|
||||
merged++;
|
||||
if (<warning descr="Condition 'merged > 50' is always 'false'">merged > 50</warning>) {
|
||||
break;
|
||||
}
|
||||
myNext = <warning descr="Assigning 'null' value to non-annotated field">null</warning>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -355,6 +355,7 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase {
|
||||
public void testReturnOrElseNull() { doTestWith(insp -> insp.REPORT_NULLABLE_METHODS_RETURNING_NOT_NULL = true); }
|
||||
public void testArrayIntersectionType() { doTest(); }
|
||||
public void testFunctionType() { doTest(); }
|
||||
public void testIteratorHasNextModifiesPrivateField() { doTest(); }
|
||||
public void testJsr305TypeUseNoLocal() {
|
||||
DataFlowInspectionTest.addJavaxNullabilityAnnotations(myFixture);
|
||||
DataFlowInspectionTest.addJavaxDefaultNullabilityAnnotations(myFixture);
|
||||
|
||||
Reference in New Issue
Block a user