Example #1
0
 /**
  * Record a given null status of a given local variable as it will be seen in the finally block.
  *
  * @param local the local variable being observed
  * @param nullStatus the null status of local at the current point in the flow
  */
 public void markFinallyNullStatus(LocalVariableBinding local, int nullStatus) {
   if (this.initsOnFinally == null) return;
   if (this.conditionalLevel == -1) return;
   if (this.conditionalLevel == 0) {
     // node is unconditionally reached, take nullStatus as is:
     this.initsOnFinally.markNullStatus(local, nullStatus);
     return;
   }
   // node is reached only conditionally, weaken status to potentially_ and merge with previous
   UnconditionalFlowInfo newInfo = this.initsOnFinally.unconditionalCopy();
   newInfo.markNullStatus(local, nullStatus);
   this.initsOnFinally = this.initsOnFinally.mergedWith(newInfo);
 }
  public void recordHandlingException(
      ReferenceBinding exceptionType,
      UnconditionalFlowInfo flowInfo,
      TypeBinding raisedException,
      ASTNode invocationSite,
      boolean wasMasked) {

    // even if unreachable code, need to perform unhandled exception diagnosis
    int size = this.thrownExceptions.length;
    if (this.exceptionCount == size) {
      System.arraycopy(
          this.thrownExceptions, 0, (this.thrownExceptions = new TypeBinding[size * 2]), 0, size);
      System.arraycopy(
          this.exceptionThrowers, 0, (this.exceptionThrowers = new ASTNode[size * 2]), 0, size);
      System.arraycopy(
          this.exceptionThrowerFlowInfos,
          0,
          (this.exceptionThrowerFlowInfos = new FlowInfo[size * 2]),
          0,
          size);
    }
    this.thrownExceptions[this.exceptionCount] = raisedException;
    this.exceptionThrowers[this.exceptionCount] = invocationSite;
    this.exceptionThrowerFlowInfos[this.exceptionCount++] = flowInfo.copy();
  }
  public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
    this.preAssertInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);

    Constant cst = this.assertExpression.optimizedBooleanConstant();
    if ((this.assertExpression.implicitConversion & TypeIds.UNBOXING) != 0) {
      this.assertExpression.checkNPE(currentScope, flowContext, flowInfo);
    }
    boolean isOptimizedTrueAssertion = cst != Constant.NotAConstant && cst.booleanValue() == true;
    boolean isOptimizedFalseAssertion = cst != Constant.NotAConstant && cst.booleanValue() == false;

    flowContext.tagBits |= FlowContext.HIDE_NULL_COMPARISON_WARNING;
    FlowInfo conditionFlowInfo =
        this.assertExpression.analyseCode(currentScope, flowContext, flowInfo.copy());
    flowContext.extendTimeToLiveForNullCheckedField(1); // survive this assert as a Statement
    flowContext.tagBits &= ~FlowContext.HIDE_NULL_COMPARISON_WARNING;
    UnconditionalFlowInfo assertWhenTrueInfo =
        conditionFlowInfo.initsWhenTrue().unconditionalInits();
    FlowInfo assertInfo = conditionFlowInfo.initsWhenFalse();
    if (isOptimizedTrueAssertion) {
      assertInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
    }

    if (this.exceptionArgument != null) {
      // only gets evaluated when escaping - results are not taken into account
      FlowInfo exceptionInfo =
          this.exceptionArgument.analyseCode(currentScope, flowContext, assertInfo.copy());

      if (isOptimizedTrueAssertion) {
        currentScope.problemReporter().fakeReachable(this.exceptionArgument);
      } else {
        flowContext.checkExceptionHandlers(
            currentScope.getJavaLangAssertionError(), this, exceptionInfo, currentScope);
      }
    }

    if (!isOptimizedTrueAssertion) {
      // add the assert support in the clinit
      manageSyntheticAccessIfNecessary(currentScope, flowInfo);
    }
    // account for potential AssertionError:
    flowContext.recordAbruptExit();
    if (isOptimizedFalseAssertion) {
      return flowInfo; // if assertions are enabled, the following code will be unreachable
      // change this if we need to carry null analysis results of the assert
      // expression downstream
    } else {
      CompilerOptions compilerOptions = currentScope.compilerOptions();
      if (!compilerOptions.includeNullInfoFromAsserts) {
        // keep just the initializations info, don't include assert's null info
        // merge initialization info's and then add back the null info from flowInfo to
        // make sure that the empty null info of assertInfo doesnt change flowInfo's null info.
        return ((flowInfo.nullInfoLessUnconditionalCopy())
                .mergedWith(assertInfo.nullInfoLessUnconditionalCopy()))
            .addNullInfoFrom(flowInfo);
      }
      return flowInfo
          .mergedWith(assertInfo.nullInfoLessUnconditionalCopy())
          .addInitializationsFrom(assertWhenTrueInfo.discardInitializationInfo());
      // keep the merge from the initial code for the definite assignment
      // analysis, tweak the null part to influence nulls downstream
    }
  }