⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unconditionalvaluederefanalysis.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		XMethod called = XFactory.createXMethod(				inv,				methodGen.getConstantPool());		SignatureParser sigParser = new SignatureParser(called.getSignature());		int numParams = sigParser.getNumParameters();		IsNullValueFrame invFrame = invDataflow.getFactAtLocation(location);		if (!invFrame.isValid()) return;		for (int i = 0; i < numParams; i++) {			int offset = sigParser.getSlotsFromTopOfStackForParameter(i);			int slot = invFrame.getStackLocation(offset);			IsNullValue value = invFrame.getValue(slot);			if (reportDereference(invFrame, slot) && database.parameterMustBeNonNull(called, i)) {				// Get the corresponding value number				ValueNumber vn = vnaFrame.getArgument(inv, methodGen.getConstantPool(), i, sigParser);				fact.addDeref(vn, location);			}		}	}	/**	 * Check to see if the instruction has a null check associated with it,	 * and if so, add a dereference.	 * 	 * @param location the Location of the instruction	 * @param vnaFrame ValueNumberFrame at the Location of the instruction	 * @param fact     the dataflow value to modify	 * @throws DataflowAnalysisException	 */	private void checkInstance(			Location location,			ValueNumberFrame vnaFrame,			UnconditionalValueDerefSet fact) throws DataflowAnalysisException {		// See if this instruction has a null check.		// If it does, the fall through predecessor will be		// identify itself as the null check.		if (!location.isFirstInstructionInBasicBlock()) {			return;		}		if (invDataflow == null) return;		BasicBlock fallThroughPredecessor =			cfg.getPredecessorWithEdgeType(location.getBasicBlock(), EdgeTypes.FALL_THROUGH_EDGE);		if (fallThroughPredecessor == null || !fallThroughPredecessor.isNullCheck()) {			return;		}		// Get the null-checked value		ValueNumber vn = vnaFrame.getInstance(location.getHandle().getInstruction(), methodGen.getConstantPool()); 		// Ignore dereferences of this		if (!methodGen.isStatic()) {			ValueNumber v = vnaFrame.getValue(0);			if (v.equals(vn)) return;		}		if (vn.hasFlag(ValueNumber.CONSTANT_CLASS_OBJECT)) return;		IsNullValueFrame startFact = null;		startFact = invDataflow.getStartFact(fallThroughPredecessor);		if (!startFact.isValid()) return;		int slot = startFact.getInstanceSlot(				location.getHandle().getInstruction(),				methodGen.getConstantPool());		if (!reportDereference(startFact, slot)) return;		if (DEBUG) {			System.out.println("FOUND GUARANTEED DEREFERENCE");			System.out.println("Load: " + vnaFrame.getLoad(vn));			System.out.println("Pred: " + fallThroughPredecessor);			System.out.println("startFact: " + startFact);			System.out.println("Location: " + location);			System.out.println("Value number frame: " + vnaFrame);			System.out.println("Dereferenced valueNumber: " + vn);			System.out.println("invDataflow: " + startFact);			System.out.println("IGNORE_DEREF_OF_NCP: " + IGNORE_DEREF_OF_NCP);		}		// Mark the value number as being dereferenced at this location		fact.addDeref(vn, location);	}	private boolean reportDereference(IsNullValueFrame invFrameAtNullCheck, int instance) {		return reportDereference( invFrameAtNullCheck.getValue(instance));	}	private boolean reportDereference(IsNullValue value) {		if (value.isDefinitelyNotNull()) return false;		if (value.isDefinitelyNull()) return false;		if (IGNORE_DEREF_OF_NCP				&& value.isNullOnComplicatedPath()) return false;		return true;	}	/**	 * Return whether or not given instruction is an assertion.	 * 	 * @param handle the instruction	 * @return true if instruction is an assertion, false otherwise	 */	private boolean isAssertion(InstructionHandle handle) {		return  assertionMethods.isAssertionInstruction ( handle.getInstruction() , 				methodGen.getConstantPool());	}	/* (non-Javadoc)	 * @see edu.umd.cs.findbugs.ba.DataflowAnalysis#copy(java.lang.Object, java.lang.Object)	 */	public void copy(UnconditionalValueDerefSet source, UnconditionalValueDerefSet dest) {		dest.makeSameAs(source);	}	/* (non-Javadoc)	 * @see edu.umd.cs.findbugs.ba.DataflowAnalysis#createFact()	 */	public UnconditionalValueDerefSet createFact() {		return new UnconditionalValueDerefSet(vnaDataflow.getAnalysis().getNumValuesAllocated());	}	/* (non-Javadoc)	 * @see edu.umd.cs.findbugs.ba.DataflowAnalysis#initEntryFact(java.lang.Object)	 */	public void initEntryFact(UnconditionalValueDerefSet result)			throws DataflowAnalysisException {		result.clear();	}	/* (non-Javadoc)	 * @see edu.umd.cs.findbugs.ba.DataflowAnalysis#initResultFact(java.lang.Object)	 */	public void initResultFact(UnconditionalValueDerefSet result) {		result.setIsTop();	}	/* (non-Javadoc)	 * @see edu.umd.cs.findbugs.ba.DataflowAnalysis#makeFactTop(java.lang.Object)	 */	public void makeFactTop(UnconditionalValueDerefSet fact) {  		fact.setIsTop();	}	public boolean isTop(UnconditionalValueDerefSet fact) {		return fact.isTop();	}	/* (non-Javadoc)	 * @see edu.umd.cs.findbugs.ba.DataflowAnalysis#meetInto(java.lang.Object, edu.umd.cs.findbugs.ba.Edge, java.lang.Object)	 */	public void meetInto(UnconditionalValueDerefSet fact, Edge edge,			UnconditionalValueDerefSet result) throws DataflowAnalysisException {		meetInto(fact, edge, result, false);	}	/* (non-Javadoc)	 * @see edu.umd.cs.findbugs.ba.DataflowAnalysis#meetInto(java.lang.Object, edu.umd.cs.findbugs.ba.Edge, java.lang.Object)	 */	public void meetInto(UnconditionalValueDerefSet fact, Edge edge,			UnconditionalValueDerefSet result, boolean onlyEdge) throws DataflowAnalysisException {		if (isExceptionEdge(edge) && !onlyEdge) {			if (DEBUG) System.out.println("Skipping exception edge");			return;		}		ValueNumber knownNonnullOnBranch = null;		// Edge transfer function		if (isFactValid(fact)) {			fact = propagateDerefSetsToMergeInputValues(fact, edge);			if (invDataflow != null) {				knownNonnullOnBranch = findValueKnownNonnullOnBranch(fact, edge);				if (knownNonnullOnBranch != null) {					fact = duplicateFact(fact);					fact.clearDerefSet(knownNonnullOnBranch);				}			}		}		boolean isBackEdge = edge.isBackwardInBytecode();		Set<Integer> loopExitBranches = ClassContext.getLoopExitBranches(method, methodGen);		assert loopExitBranches != null;		boolean sourceIsTopOfLoop = edge.sourceIsTopOfLoop(loopExitBranches);		if (sourceIsTopOfLoop && edge.getType() == EdgeTypes.FALL_THROUGH_EDGE)			isBackEdge = true;		if (false && (edge.getType() == EdgeTypes.IFCMP_EDGE || sourceIsTopOfLoop)) {			System.out.println("Meet into " + edge);			System.out.println("  foo2: " + sourceIsTopOfLoop);			System.out.println("  getType: " + edge.getType() );			System.out.println("  Backedge according to bytecode: " + isBackEdge);			System.out.println("  Fact hashCode: " + System.identityHashCode(result));			System.out.println("  Initial fact: " + result);			System.out.println("  Edge fact: " + fact);		}		if (result.isTop() || fact.isBottom()) {			// Make result identical to other fact			copy(fact, result);			if (ASSUME_NONZERO_TRIP_LOOPS && isBackEdge && !fact.isTop())				result.resultsFromBackEdge = true;		} else if (ASSUME_NONZERO_TRIP_LOOPS && isBackEdge && !fact.isTop()) {			result.unionWith(fact, vnaDataflow.getAnalysis().getFactory());			result.resultsFromBackEdge = true;			if (DEBUG) {				System.out.println("\n Forcing union of " +  System.identityHashCode(result) + " due to backedge info");				System.out.println("  result: " +  result);			}		} else if (result.isBottom() || fact.isTop()) {			// No change in result fact		} else {			// Dataflow merge			// (intersection of unconditional deref values)		   if (ASSUME_NONZERO_TRIP_LOOPS && result.resultsFromBackEdge) {				result.backEdgeUpdateCount++;				if (result.backEdgeUpdateCount < 10) {					if (DEBUG) System.out.println("\n Union update of " +  System.identityHashCode(result) + " due to backedge info");					result.unionWith(fact, vnaDataflow.getAnalysis().getFactory());					return;				}			}			result.mergeWith(fact, knownNonnullOnBranch, vnaDataflow.getAnalysis().getFactory());			if (DEBUG) {				System.out.println("  updated: " + System.identityHashCode(result));				System.out.println("  result: " +  result);			}		}		if (DEBUG && isBackEdge && edge.getType() == EdgeTypes.IFCMP_EDGE) {		 System.out.println("  result: " +  result);		}	}	/**	 * Find out if any VNs in the source block	 * contribute to unconditionally dereferenced VNs in the	 * target block.  If so, the VN in the source block is	 * also unconditionally dereferenced, and we must propagate	 * the target VN's dereferences.	 *  	 * @param fact a dataflow value	 * @param edge edge to check for merge input values	 * @return possibly-modified dataflow value	 */	private  UnconditionalValueDerefSet propagateDerefSetsToMergeInputValues(			UnconditionalValueDerefSet fact, Edge edge) {		ValueNumberFrame blockValueNumberFrame =			vnaDataflow.getResultFact(edge.getSource());		ValueNumberFrame targetValueNumberFrame =			vnaDataflow.getStartFact(edge.getTarget());		UnconditionalValueDerefSet originalFact = fact;		fact = duplicateFact(fact);		if (blockValueNumberFrame.isValid() && targetValueNumberFrame.isValid() &&				blockValueNumberFrame.getNumSlots() == targetValueNumberFrame.getNumSlots()) {			if (DEBUG) {				System.out.println("** Valid VNA frames for " + edge);				System.out.println("** Block : " + blockValueNumberFrame);				System.out.println("** Target: " + targetValueNumberFrame);			}			for (int i = 0; i < blockValueNumberFrame.getNumSlots(); i++) {				ValueNumber blockVN = blockValueNumberFrame.getValue(i);				ValueNumber targetVN = targetValueNumberFrame.getValue(i);				if (blockVN.equals(targetVN)) continue;				fact.clearDerefSet(blockVN);				if (originalFact.isUnconditionallyDereferenced(targetVN))					fact.setDerefSet(blockVN, originalFact.getUnconditionalDerefLocationSet(targetVN));			} // for all slots			for(ValueNumber blockVN : blockValueNumberFrame.valueNumbersForLoads()) {				AvailableLoad load = blockValueNumberFrame.getLoad(blockVN);				if (load == null) continue;				ValueNumber [] targetVNs = targetValueNumberFrame.getAvailableLoad(load);				if (targetVNs != null)					for(ValueNumber targetVN : targetVNs) 						if (targetVN.hasFlag(ValueNumber.PHI_NODE) && fact.isUnconditionallyDereferenced(targetVN)								&& !fact.isUnconditionallyDereferenced(blockVN)) {							//  Block VN is also dereferenced unconditionally.							AvailableLoad targetLoad = targetValueNumberFrame.getLoad(targetVN);							if (!load.equals(targetLoad)) continue;							if (DEBUG) {								System.out.println("** Copy vn derefs for " + load +" from " + targetVN + 										" --> " + blockVN);								System.out.println("** block phi for " +  System.identityHashCode(blockValueNumberFrame)										+ " is " + blockValueNumberFrame.phiNodeForLoads);								System.out.println("** target phi for " +  System.identityHashCode(targetValueNumberFrame)										+ " is " + targetValueNumberFrame.phiNodeForLoads);							}							fact.setDerefSet(blockVN, fact.getUnconditionalDerefLocationSet(targetVN));						}			}		}		if (DEBUG) {			System.out.println("Target VNF: " + targetValueNumberFrame);			System.out.println("Block VNF: " + blockValueNumberFrame);			System.out.println("fact: " + fact);		}		fact.cleanDerefSet(null, blockValueNumberFrame);		return fact;	}	/**	 * Return a duplicate of given dataflow fact.	 * 	 * @param fact a dataflow fact	 * @return a duplicate of the input dataflow fact	 */	private UnconditionalValueDerefSet duplicateFact(UnconditionalValueDerefSet fact) {		UnconditionalValueDerefSet copyOfFact = createFact();		copy(fact, copyOfFact);		fact = copyOfFact;		return fact;	}	/**	 * Clear deref sets of values if this edge is the non-null branch	 * of an if comparison.	 * 	 * @param fact a datflow fact	 * @param edge edge to check	 * @return possibly-modified dataflow fact	 */	private @CheckForNull ValueNumber findValueKnownNonnullOnBranch(			UnconditionalValueDerefSet fact, Edge edge) {		IsNullValueFrame invFrame = invDataflow.getResultFact(edge.getSource());		if (!invFrame.isValid()) {			return null;		}		IsNullConditionDecision decision = invFrame.getDecision();		if (decision == null) {			return null;		}		IsNullValue inv = decision.getDecision(edge.getType());		if (inv == null || !inv.isDefinitelyNotNull()) {			return null;		}		ValueNumber value = decision.getValue();		if (DEBUG) {			System.out.println("Value number " + value + " is known nonnull on " + edge);		}		return value;	}	/**	 * Determine whether dataflow should be propagated on given edge.	 * 	 * @param edge the edge	 * @return true if dataflow should be propagated on the edge, false otherwise	 */	private boolean isExceptionEdge(Edge edge) {		boolean isExceptionEdge = edge.isExceptionEdge();		if (DEBUG && isExceptionEdge)			System.out.println("Ignoring " + edge);		return isExceptionEdge;	}	/* (non-Javadoc)	 * @see edu.umd.cs.findbugs.ba.DataflowAnalysis#same(java.lang.Object, java.lang.Object)	 */	public boolean same(UnconditionalValueDerefSet fact1, UnconditionalValueDerefSet fact2) {		return fact1.resultsFromBackEdge || fact1.isSameAs(fact2);	}	@Override	public void startIteration() {		// System.out.println("analysis iteration in " + methodGen.getClassName() + " on " + methodGen.toString());	}	@Override	public int getLastUpdateTimestamp(UnconditionalValueDerefSet fact) {		return fact.getLastUpdateTimestamp();	}	@Override	public void setLastUpdateTimestamp(UnconditionalValueDerefSet fact, int lastUpdate) {		fact.setLastUpdateTimestamp(lastUpdate);	}	public static void main(String[] args) throws Exception {		if (args.length != 1) {			System.err.println("Usage: " + UnconditionalValueDerefAnalysis.class.getName() + " <classfile>");			System.exit(1);		}		DataflowTestDriver<UnconditionalValueDerefSet, UnconditionalValueDerefAnalysis> driver =			new DataflowTestDriver<UnconditionalValueDerefSet, UnconditionalValueDerefAnalysis>() {			/* (non-Javadoc)			 * @see edu.umd.cs.findbugs.ba.DataflowTestDriver#createDataflow(edu.umd.cs.findbugs.ba.ClassContext, org.apache.bcel.classfile.Method)			 */			@Override			public Dataflow<UnconditionalValueDerefSet, UnconditionalValueDerefAnalysis> createDataflow(ClassContext classContext, Method method) throws CFGBuilderException, DataflowAnalysisException {				return classContext.getUnconditionalValueDerefDataflow(method);			}		};		if (SystemProperties.getBoolean("forwardcfg")) {			driver.overrideIsForwards();		}		driver.execute(args[0]);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -