public DfaInstructionState[] visitNot(
      NotInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
    DfaValue dfaValue = memState.pop();

    dfaValue = dfaValue.createNegated();
    memState.push(dfaValue);
    return nextInstruction(instruction, runner, memState);
  }
  public DfaInstructionState[] visitConditionalGoto(
      ConditionalGotoInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
    DfaValue cond = memState.pop();

    DfaValue condTrue;
    DfaValue condFalse;

    if (instruction.isNegated()) {
      condFalse = cond;
      condTrue = cond.createNegated();
    } else {
      condTrue = cond;
      condFalse = cond.createNegated();
    }

    if (condTrue == runner.getFactory().getConstFactory().getTrue()) {
      markBranchReachable(instruction, true);
      return new DfaInstructionState[] {
        new DfaInstructionState(runner.getInstruction(instruction.getOffset()), memState)
      };
    }

    if (condFalse == runner.getFactory().getConstFactory().getTrue()) {
      markBranchReachable(instruction, false);
      return nextInstruction(instruction, runner, memState);
    }

    ArrayList<DfaInstructionState> result = new ArrayList<DfaInstructionState>();

    DfaMemoryState thenState = memState.createCopy();
    DfaMemoryState elseState = memState.createCopy();

    if (thenState.applyCondition(condTrue)) {
      result.add(
          new DfaInstructionState(runner.getInstruction(instruction.getOffset()), thenState));
      markBranchReachable(instruction, true);
    }

    if (elseState.applyCondition(condFalse)) {
      result.add(
          new DfaInstructionState(runner.getInstruction(instruction.getIndex() + 1), elseState));
      markBranchReachable(instruction, false);
    }

    return result.toArray(new DfaInstructionState[result.size()]);
  }
示例#3
0
  @Nullable("for boxed values which can't be compared by ==")
  private Integer getOrCreateEqClassIndex(@NotNull DfaValue dfaValue) {
    int i = getEqClassIndex(dfaValue);
    if (i != -1) return i;
    if (!canBeInRelation(dfaValue)
        || !canBeReused(dfaValue)
            && !(((DfaBoxedValue) dfaValue).getWrappedValue() instanceof DfaConstValue)) {
      return null;
    }
    int freeIndex = myEqClasses.indexOf(null);
    int resultIndex = freeIndex >= 0 ? freeIndex : myEqClasses.size();
    EqClass aClass = new EqClass(myFactory);
    aClass.add(dfaValue.getID());

    if (freeIndex >= 0) {
      myEqClasses.set(freeIndex, aClass);
    } else {
      myEqClasses.add(aClass);
    }
    addToMap(dfaValue.getID(), resultIndex);

    return resultIndex;
  }
示例#4
0
  private int getEqClassIndex(@NotNull final DfaValue dfaValue) {
    final int id = unwrap(dfaValue).getID();
    int[] classes = myIdToEqClassesIndices.get(id);

    int result = -1;
    if (classes != null) {
      for (int index : classes) {
        EqClass aClass = myEqClasses.get(index);
        if (!aClass.contains(dfaValue.getID())) continue;
        if (!canBeReused(dfaValue) && aClass.size() > 1) break;
        result = index;
        break;
      }
    }
    return result;
  }
示例#5
0
 private boolean checkCompareWithBooleanLiteral(
     DfaValue dfaLeft, DfaValue dfaRight, boolean negated) {
   if (dfaRight instanceof DfaConstValue) {
     Object constVal = ((DfaConstValue) dfaRight).getValue();
     if (constVal instanceof Boolean) {
       DfaConstValue negVal =
           myFactory
               .getConstFactory()
               .createFromValue(!((Boolean) constVal).booleanValue(), PsiType.BOOLEAN, null);
       if (!applyRelation(dfaLeft, negVal, !negated)) {
         return false;
       }
       if (!applyRelation(dfaLeft.createNegated(), negVal, negated)) {
         return false;
       }
     }
   }
   return true;
 }
  private List<DfaMemoryState> addContractResults(
      DfaValue[] argValues,
      MethodContract contract,
      List<DfaMemoryState> states,
      MethodCallInstruction instruction,
      DfaValueFactory factory,
      Set<DfaMemoryState> finalStates) {
    DfaConstValue.Factory constFactory = factory.getConstFactory();
    List<DfaMemoryState> falseStates = ContainerUtil.newArrayList();
    for (int i = 0; i < argValues.length; i++) {
      DfaValue argValue = argValues[i];
      MethodContract.ValueConstraint constraint = contract.arguments[i];
      DfaConstValue expectedValue = constraint.getComparisonValue(factory);
      if (expectedValue == null) continue;

      boolean invertCondition = constraint.shouldUseNonEqComparison();
      DfaValue condition =
          factory
              .getRelationFactory()
              .createRelation(argValue, expectedValue, EQEQ, invertCondition);
      if (condition == null) {
        if (!(argValue instanceof DfaConstValue)) {
          for (DfaMemoryState state : states) {
            falseStates.add(state.createCopy());
          }
          continue;
        }
        condition =
            constFactory.createFromValue(
                (argValue == expectedValue) != invertCondition, PsiType.BOOLEAN, null);
      }

      List<DfaMemoryState> nextStates = ContainerUtil.newArrayList();
      for (DfaMemoryState state : states) {
        boolean unknownVsNull =
            expectedValue == constFactory.getNull()
                && argValue instanceof DfaVariableValue
                && ((DfaMemoryStateImpl) state)
                        .getVariableState((DfaVariableValue) argValue)
                        .getNullability()
                    == Nullness.UNKNOWN;
        DfaMemoryState falseCopy = state.createCopy();
        if (state.applyCondition(condition)) {
          if (unknownVsNull && !invertCondition) {
            state.markEphemeral();
          }
          nextStates.add(state);
        }
        if (falseCopy.applyCondition(condition.createNegated())) {
          if (unknownVsNull && invertCondition) {
            falseCopy.markEphemeral();
          }
          falseStates.add(falseCopy);
        }
      }
      states = nextStates;
    }

    for (DfaMemoryState state : states) {
      state.push(getDfaContractReturnValue(contract, instruction, factory));
      finalStates.add(state);
    }

    return falseStates;
  }