1 19 20 package edu.umd.cs.findbugs.detect; 21 22 23 import edu.umd.cs.findbugs.*; 24 import edu.umd.cs.findbugs.ba.*; 25 import edu.umd.cs.findbugs.ba.type.*; 26 import java.util.*; 27 import org.apache.bcel.Constants; 28 import org.apache.bcel.classfile.*; 29 import org.apache.bcel.generic.*; 30 31 37 public final class FindJSR166LockMonitorenter implements Detector, StatelessDetector { 38 private BugReporter bugReporter; 39 40 private static final ObjectType LOCK_TYPE = ObjectTypeFactory.getInstance("java.util.concurrent.locks.Lock"); 41 42 public FindJSR166LockMonitorenter(BugReporter bugReporter) { 43 this.bugReporter = bugReporter; 44 } 45 46 @Override 47 public Object clone() { 48 try { 49 return super.clone(); 50 } catch (CloneNotSupportedException e) { 51 throw new AssertionError (e); 52 } 53 } 54 55 public void visitClassContext(ClassContext classContext) { 56 JavaClass jclass = classContext.getJavaClass(); 57 Method[] methodList = jclass.getMethods(); 58 59 for (Method method : methodList) { 60 if (method.getCode() == null) 61 continue; 62 63 BitSet bytecodeSet = classContext.getBytecodeSet(method); 65 if (bytecodeSet == null) continue; 66 if (!bytecodeSet.get(Constants.MONITORENTER)) 67 continue; 68 69 try { 70 analyzeMethod(classContext, method); 71 } catch (CFGBuilderException e) { 72 bugReporter.logError("FindJSR166LockMonitorEnter caught exception", e); 73 } catch (DataflowAnalysisException e) { 74 bugReporter.logError("FindJSR166LockMonitorEnter caught exception", e); 75 } 76 } 77 } 78 79 private void analyzeMethod(ClassContext classContext, Method method) 80 throws CFGBuilderException, DataflowAnalysisException { 81 ConstantPoolGen cpg = classContext.getConstantPoolGen(); 82 CFG cfg = classContext.getCFG(method); 83 TypeDataflow typeDataflow = classContext.getTypeDataflow(method); 84 85 for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { 86 Location location = i.next(); 87 88 InstructionHandle handle = location.getHandle(); 89 Instruction ins = handle.getInstruction(); 90 91 if (ins.getOpcode() != Constants.MONITORENTER) 92 continue; 93 94 TypeFrame frame = typeDataflow.getFactAtLocation(location); 95 if (!frame.isValid()) 96 continue; 97 Type type = frame.getInstance(ins, cpg); 98 99 if (!(type instanceof ReferenceType)) { 100 return; 104 } 105 106 boolean isSubtype; 107 try { 108 isSubtype = Hierarchy.isSubtype((ReferenceType) type, LOCK_TYPE); 109 } catch (ClassNotFoundException e) { 110 bugReporter.reportMissingClass(e); 111 return; 112 } 113 114 if (isSubtype) { 115 MethodGen mg = classContext.getMethodGen(method); 116 String sourceFile = classContext.getJavaClass().getSourceFileName(); 117 118 bugReporter.reportBug(new BugInstance(this, "JLM_JSR166_LOCK_MONITORENTER", NORMAL_PRIORITY) 119 .addClassAndMethod(mg, sourceFile) 120 .addSourceLine(classContext, mg, sourceFile, handle)); 121 } 122 } 123 } 124 125 public void report() { 126 } 127 } 128 129 | Popular Tags |