[java-analysis] Pop jump roles and statements right after the condition

They should not take effect when we are already at branches.
Fixes IDEA-292666 False negative for checking definite assignment with ternaries

GitOrigin-RevId: 991562f8ec5a9c7b33dfa6a1810bb4ac385c7209
This commit is contained in:
Tagir Valeev
2022-04-26 17:00:19 +02:00
committed by intellij-monorepo-bot
parent 69ba31aaf2
commit fe8e2f8122
5 changed files with 53 additions and 6 deletions

View File

@@ -812,6 +812,13 @@ final class ControlFlowAnalyzer extends JavaElementVisitor {
addElementOffsetLater(elseBranch, true);
}
}
myStartJumpRoles.pop();
myEndJumpRoles.pop();
myStartStatementStack.popStatement();
myEndStatementStack.popStatement();
if (thenBranch != null) {
thenBranch.accept(this);
}
@@ -821,12 +828,6 @@ final class ControlFlowAnalyzer extends JavaElementVisitor {
addElementOffsetLater(statement, false);
elseBranch.accept(this);
}
myStartJumpRoles.pop();
myEndJumpRoles.pop();
myStartStatementStack.popStatement();
myEndStatementStack.popStatement();
}
@Override

View File

@@ -0,0 +1,10 @@
class X {
void test(int a, int b, int c){
int x;
if((a > 0? c < b && (x = b) > 0: (x = c) < 0 || c == b)) {
System.out.println(x);
} else {
System.out.println(<error descr="Variable 'x' might not have been initialized">x</error>);
}
}
}

View File

@@ -0,0 +1,12 @@
// LocalsOrMyInstanceFieldsControlFlowPolicy
class X {
void test(int a, int b, int c){<caret>
int x;
if((a > 0? c < b && (x = b) > 0: (x = c) < 0 || c == b)) {
System.out.println(x);
} else {
System.out.println(x);
}
}
}

View File

@@ -0,0 +1,20 @@
0: EMPTY
1: READ a
2: COND_GOTO [ELSE] 9
3: READ c
4: READ b
5: COND_GOTO [ELSE] 18
6: READ b
7: WRITE x
8: GOTO [END] 14
9: READ c
10: WRITE x
11: COND_GOTO [THEN] 15
12: READ c
13: READ b
14: COND_GOTO [ELSE] 18
15: READ x
16: EMPTY
17: GOTO [END] 20
18: READ x
19: EMPTY

View File

@@ -419,4 +419,8 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase {
setLanguageLevel(LanguageLevel.JDK_1_5);
doTest(true);
}
public void testUninitializedVarComplexTernary() {
doTest(false);
}
}