@Nullable private DfaInstructionState[] handleRelationBinop( BinopInstruction instruction, DataFlowRunner runner, DfaMemoryState memState, DfaValue dfaRight, DfaValue dfaLeft) { DfaValueFactory factory = runner.getFactory(); final Instruction next = runner.getInstruction(instruction.getIndex() + 1); DfaRelationValue dfaRelation = factory .getRelationFactory() .createRelation(dfaLeft, dfaRight, instruction.getOperationSign(), false); if (dfaRelation == null) { return null; } myCanBeNullInInstanceof.add(instruction); ArrayList<DfaInstructionState> states = new ArrayList<DfaInstructionState>(); final DfaMemoryState trueCopy = memState.createCopy(); if (trueCopy.applyCondition(dfaRelation)) { trueCopy.push(factory.getConstFactory().getTrue()); instruction.setTrueReachable(); states.add(new DfaInstructionState(next, trueCopy)); } //noinspection UnnecessaryLocalVariable DfaMemoryState falseCopy = memState; if (falseCopy.applyCondition(dfaRelation.createNegated())) { falseCopy.push(factory.getConstFactory().getFalse()); instruction.setFalseReachable(); states.add(new DfaInstructionState(next, falseCopy)); if (instruction instanceof InstanceofInstruction && !falseCopy.isNull(dfaLeft)) { myUsefulInstanceofs.add((InstanceofInstruction) instruction); } } return states.toArray(new DfaInstructionState[states.size()]); }
@Nullable private static DfaInstructionState[] handleConstantComparison( BinopInstruction instruction, DataFlowRunner runner, DfaMemoryState memState, DfaValue dfaRight, DfaValue dfaLeft, IElementType opSign) { if (dfaRight instanceof DfaConstValue && dfaLeft instanceof DfaVariableValue) { Object value = ((DfaConstValue) dfaRight).getValue(); if (value instanceof Number) { DfaInstructionState[] result = checkComparingWithConstant( instruction, runner, memState, (DfaVariableValue) dfaLeft, opSign, ((Number) value).doubleValue()); if (result != null) { return result; } } } if (dfaRight instanceof DfaVariableValue && dfaLeft instanceof DfaConstValue) { return handleConstantComparison( instruction, runner, memState, dfaLeft, dfaRight, DfaRelationValue.getSymmetricOperation(opSign)); } if (EQEQ != opSign && NE != opSign) { return null; } if (dfaLeft instanceof DfaConstValue && dfaRight instanceof DfaConstValue || dfaLeft == runner.getFactory().getConstFactory().getContractFail() || dfaRight == runner.getFactory().getConstFactory().getContractFail()) { boolean negated = (NE == opSign) ^ (DfaMemoryStateImpl.isNaN(dfaLeft) || DfaMemoryStateImpl.isNaN(dfaRight)); if (dfaLeft == dfaRight ^ negated) { return alwaysTrue(instruction, runner, memState); } return alwaysFalse(instruction, runner, memState); } return null; }