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

📄 findbadcast2.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package edu.umd.cs.findbugs.detect;import java.util.BitSet;import java.util.HashSet;import java.util.Iterator;import java.util.Set;import org.apache.bcel.Constants;import org.apache.bcel.Repository;import org.apache.bcel.classfile.Attribute;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.classfile.LineNumberTable;import org.apache.bcel.classfile.Method;import org.apache.bcel.classfile.Synthetic;import org.apache.bcel.generic.CHECKCAST;import org.apache.bcel.generic.ConstantPoolGen;import org.apache.bcel.generic.INSTANCEOF;import org.apache.bcel.generic.Instruction;import org.apache.bcel.generic.InstructionHandle;import org.apache.bcel.generic.InvokeInstruction;import org.apache.bcel.generic.MethodGen;import org.apache.bcel.generic.ObjectType;import org.apache.bcel.generic.ReferenceType;import org.apache.bcel.generic.Type;import org.apache.bcel.generic.TypedInstruction;import edu.umd.cs.findbugs.BugAnnotation;import edu.umd.cs.findbugs.DeepSubtypeAnalysis;import edu.umd.cs.findbugs.BugAccumulator;import edu.umd.cs.findbugs.BugInstance;import edu.umd.cs.findbugs.BugReporter;import edu.umd.cs.findbugs.Detector;import edu.umd.cs.findbugs.FieldAnnotation;import edu.umd.cs.findbugs.LocalVariableAnnotation;import edu.umd.cs.findbugs.SourceLineAnnotation;import edu.umd.cs.findbugs.SystemProperties;import edu.umd.cs.findbugs.TypeAnnotation;import edu.umd.cs.findbugs.ba.AnalysisContext;import edu.umd.cs.findbugs.ba.CFG;import edu.umd.cs.findbugs.ba.CFGBuilderException;import edu.umd.cs.findbugs.ba.ClassContext;import edu.umd.cs.findbugs.ba.DataflowAnalysisException;import edu.umd.cs.findbugs.ba.Location;import edu.umd.cs.findbugs.ba.MethodUnprofitableException;import edu.umd.cs.findbugs.ba.npe.IsNullValue;import edu.umd.cs.findbugs.ba.npe.IsNullValueDataflow;import edu.umd.cs.findbugs.ba.npe.IsNullValueFrame;import edu.umd.cs.findbugs.ba.npe.NullDerefAndRedundantComparisonFinder;import edu.umd.cs.findbugs.ba.type.NullType;import edu.umd.cs.findbugs.ba.type.TopType;import edu.umd.cs.findbugs.ba.type.TypeDataflow;import edu.umd.cs.findbugs.ba.type.TypeFrame;import edu.umd.cs.findbugs.ba.vna.ValueNumber;import edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow;import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame;public class FindBadCast2 implements Detector {	private BugReporter bugReporter;	private Set<String> concreteCollectionClasses = new HashSet<String>();	private Set<String> abstractCollectionClasses = new HashSet<String>();	private Set<String> veryAbstractCollectionClasses = new HashSet<String>();	private static final boolean DEBUG = SystemProperties.getBoolean("bc.debug");  	public FindBadCast2(BugReporter bugReporter) {				this.bugReporter = bugReporter;		veryAbstractCollectionClasses.add("java.util.Collection");		veryAbstractCollectionClasses.add("java.util.Iterable");		abstractCollectionClasses.add("java.util.Collection");		abstractCollectionClasses.add("java.util.List");		abstractCollectionClasses.add("java.util.Set");		abstractCollectionClasses.add("java.util.SortedSet");		abstractCollectionClasses.add("java.util.SortedMap");		abstractCollectionClasses.add("java.util.Map");		concreteCollectionClasses.add("java.util.LinkedHashMap");		concreteCollectionClasses.add("java.util.LinkedHashSet");		concreteCollectionClasses.add("java.util.HashMap");		concreteCollectionClasses.add("java.util.HashSet");		concreteCollectionClasses.add("java.util.TreeMap");		concreteCollectionClasses.add("java.util.TreeSet");		concreteCollectionClasses.add("java.util.ArrayList");		concreteCollectionClasses.add("java.util.LinkedList");		concreteCollectionClasses.add("java.util.Hashtable");		concreteCollectionClasses.add("java.util.Vector");	}	public void visitClassContext(ClassContext classContext) {		JavaClass javaClass = classContext.getJavaClass();		Method[] methodList = javaClass.getMethods();		for (Method method : methodList) {			if (method.getCode() == null)				continue;			try {				analyzeMethod(classContext, method);			} catch (MethodUnprofitableException e) {				assert true; // move along; nothing to see			} catch (CFGBuilderException e) {				String msg = "Detector " + this.getClass().getName()										+ " caught exception while analyzing " + javaClass.getClassName() + "." + method.getName() + " : " + method.getSignature();				bugReporter.logError(msg , e);			} catch (DataflowAnalysisException e) {				String msg = "Detector " + this.getClass().getName()										+ " caught exception while analyzing " + javaClass.getClassName() + "." + method.getName() + " : " + method.getSignature();				bugReporter.logError(msg, e);			}		}	}	public boolean prescreen(ClassContext classContext, Method method) {		BitSet bytecodeSet = classContext.getBytecodeSet(method);		return bytecodeSet != null && (bytecodeSet.get(Constants.CHECKCAST)				|| bytecodeSet.get(Constants.INSTANCEOF));	}	private boolean isSynthetic(Method m) {		Attribute[] attrs = m.getAttributes();		for (Attribute attr : attrs) {			if (attr instanceof Synthetic)				return true;		}		return false;	}	private Set<ValueNumber> getParameterValueNumbers(ClassContext classContext, Method method,  CFG cfg ) throws DataflowAnalysisException, CFGBuilderException {		ValueNumberDataflow vnaDataflow = classContext.getValueNumberDataflow(method);		ValueNumberFrame vnaFrameAtEntry = vnaDataflow.getStartFact(cfg				.getEntry());		Set<ValueNumber> paramValueNumberSet = new HashSet<ValueNumber>();		int firstParam = method.isStatic() ? 0 : 1;		for (int i = firstParam; i < vnaFrameAtEntry.getNumLocals(); ++i) {			paramValueNumberSet.add(vnaFrameAtEntry.getValue(i));		}		return paramValueNumberSet;	}	private void analyzeMethod(ClassContext classContext, Method method)			throws CFGBuilderException, DataflowAnalysisException {		if (isSynthetic(method) || !prescreen(classContext, method))			return;		BugAccumulator accumulator = new BugAccumulator(bugReporter);		CFG cfg = classContext.getCFG(method);		TypeDataflow typeDataflow = classContext.getTypeDataflow(method);		IsNullValueDataflow isNullDataflow = classContext.getIsNullValueDataflow(method);		Set<ValueNumber> paramValueNumberSet = null;		ValueNumberDataflow vnaDataflow = null;		ConstantPoolGen cpg = classContext.getConstantPoolGen();		MethodGen methodGen = classContext.getMethodGen(method);		if (methodGen == null) return;		String methodName = methodGen.getClassName() + "."				+ methodGen.getName();		String sourceFile = classContext.getJavaClass().getSourceFileName();		if (DEBUG) {			System.out.println("Checking " + methodName);		}		Set<SourceLineAnnotation> haveInstanceOf = new HashSet<SourceLineAnnotation>();		Set<SourceLineAnnotation> haveCast = new HashSet<SourceLineAnnotation>();		Set<SourceLineAnnotation> haveMultipleInstanceOf = new HashSet<SourceLineAnnotation>();		Set<SourceLineAnnotation> haveMultipleCast = new HashSet<SourceLineAnnotation>();		for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {			Location location = i.next();			InstructionHandle handle = location.getHandle();			Instruction ins = handle.getInstruction();			if (!(ins instanceof CHECKCAST) && !(ins instanceof INSTANCEOF))				continue;			SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation					.fromVisitedInstruction(classContext, methodGen, sourceFile, handle);			if (ins instanceof CHECKCAST) {				if (!haveCast.add(sourceLineAnnotation))					haveMultipleCast.add(sourceLineAnnotation);			} else {				if (!haveInstanceOf.add(sourceLineAnnotation))					haveMultipleInstanceOf.add(sourceLineAnnotation);			}		}		BitSet linesMentionedMultipleTimes = ClassContext.linesMentionedMultipleTimes(method);		LineNumberTable lineNumberTable = methodGen.getLineNumberTable(methodGen.getConstantPool());		for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {			Location location = i.next();			InstructionHandle handle = location.getHandle();			int pc = handle.getPosition();			Instruction ins = handle.getInstruction();			if (!(ins instanceof CHECKCAST) && !(ins instanceof INSTANCEOF))				continue;			if (handle.getNext() == null) continue;			Instruction nextIns = handle.getNext().getInstruction();			boolean isCast = ins instanceof CHECKCAST;			String kind = isCast ? "checkedCast" : "instanceof";			int occurrences = cfg.getLocationsContainingInstructionWithOffset(					pc).size();			boolean split = occurrences > 1;			if (lineNumberTable != null) {				int line = lineNumberTable.getSourceLine(handle.getPosition());				if (line > 0 && linesMentionedMultipleTimes.get(line)) split=true;			}			IsNullValueFrame nullFrame = isNullDataflow.getFactAtLocation(location);			if (!nullFrame.isValid()) continue;			IsNullValue operandNullness = nullFrame.getTopValue();			if (DEBUG) {				System.out						.println(kind + " at pc: " + pc + " in " + methodName);				System.out.println(" occurrences: " + occurrences);				System.out.println("XXX: " + operandNullness);			}			if (split && !isCast) {				// don't report this case; it might be infeasible due to inlining				continue;			}			TypeFrame frame = typeDataflow.getFactAtLocation(location);			if (!frame.isValid()) {				// This basic block is probably dead				continue;			}			Type operandType = frame.getTopValue();			if (operandType.equals(TopType.instance())) {				// unreachable				continue;			}			boolean operandTypeIsExact = frame.isExact(frame.getStackLocation(0));			Type castType = ((TypedInstruction) ins).getType(cpg);			if (!(castType instanceof ReferenceType)) {

⌨️ 快捷键说明

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