[java-dfa] Avoid extra unboxing in prefix inc/dec operation

Fixes IDEA-260267 Integer equality not properly evaluated after auto-increment

GitOrigin-RevId: 981901b35969c900ae17a362a74dd53884518295
This commit is contained in:
Tagir Valeev
2021-01-27 03:56:16 +00:00
committed by intellij-monorepo-bot
parent 0b81794548
commit bf9726c4ed
3 changed files with 33 additions and 13 deletions
@@ -1941,26 +1941,28 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
else {
operand.accept(this);
PsiType type = expression.getType();
PsiPrimitiveType unboxed = PsiPrimitiveType.getUnboxedType(type);
generateBoxingUnboxingInstructionFor(operand, unboxed == null ? type : unboxed);
if (PsiUtil.isIncrementDecrementOperation(expression)) {
if (!processIncrementDecrement(expression, operand)) {
pushUnknown();
addInstruction(new AssignInstruction(operand, null, myFactory.createValue(operand)));
}
}
else if (expression.getOperationTokenType() == JavaTokenType.EXCL) {
addInstruction(new NotInstruction(expression));
}
else if (expression.getOperationTokenType() == JavaTokenType.MINUS && (PsiType.INT.equals(type) || PsiType.LONG.equals(type))) {
addInstruction(new PushValueInstruction(DfTypes.defaultValue(type)));
addInstruction(new SwapInstruction());
addInstruction(new BinopInstruction(expression.getOperationTokenType(), expression, type));
}
else {
addInstruction(new PopInstruction());
pushUnknown();
PsiType type = expression.getType();
PsiPrimitiveType unboxed = PsiPrimitiveType.getUnboxedType(type);
generateBoxingUnboxingInstructionFor(operand, unboxed == null ? type : unboxed);
if (expression.getOperationTokenType() == JavaTokenType.EXCL) {
addInstruction(new NotInstruction(expression));
}
else if (expression.getOperationTokenType() == JavaTokenType.MINUS && (PsiType.INT.equals(type) || PsiType.LONG.equals(type))) {
addInstruction(new PushValueInstruction(DfTypes.defaultValue(type)));
addInstruction(new SwapInstruction());
addInstruction(new BinopInstruction(expression.getOperationTokenType(), expression, type));
}
else {
addInstruction(new PopInstruction());
pushUnknown();
}
}
}
}
@@ -0,0 +1,17 @@
class X {
void test() {
Integer integer = 0;
++integer;
if (<warning descr="Condition 'integer == 1' is always 'true'">integer == 1</warning>) {
System.out.println("Line to be printed");
}
}
void test2() {
Integer integer = 0;
integer++;
if (<warning descr="Condition 'integer == 1' is always 'true'">integer == 1</warning>) {
System.out.println("Line to be printed");
}
}
}
@@ -679,6 +679,7 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
public void testProtobufNotNullGetters() { doTest(); }
public void testAIOOBETransfer() { doTest(); }
public void testBoxingShortByte() { doTest(); }
public void testBoxingIncrement() { doTest(); }
public void testUnboxingWithConversionCalls() { doTest(); }
public void testNullableAliasing() { doTest(); }
public void testReapplyTypeArguments() { doTest(); }