/** * 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 } }