1 19 20 package edu.umd.cs.findbugs.detect; 21 22 23 import edu.umd.cs.findbugs.*; 24 import java.util.*; 25 26 import org.apache.bcel.classfile.Field; 27 import org.apache.bcel.classfile.JavaClass; 28 import org.apache.bcel.classfile.Method; 29 30 public class MutableLock extends BytecodeScanningDetector implements StatelessDetector { 31 Set<String > setFields = new HashSet<String >(); 32 Set<String > finalFields = new HashSet<String >(); 33 boolean thisOnTOS = false; 34 private BugReporter bugReporter; 35 36 public MutableLock(BugReporter bugReporter) { 37 this.bugReporter = bugReporter; 38 } 39 40 41 @Override 42 public void visit(JavaClass obj) { 43 finalFields.clear(); 44 super.visit(obj); 45 } 46 47 @Override 48 public void visit(Field obj) { 49 super.visit(obj); 50 if (obj.isFinal()) finalFields.add(obj.getName()); 51 } 52 @Override 53 public void visit(Method obj) { 54 super.visit(obj); 55 setFields.clear(); 56 thisOnTOS = false; 57 } 58 59 @Override 60 public void sawOpcode(int seen) { 61 62 switch (seen) { 63 case ALOAD_0: 64 thisOnTOS = true; 65 return; 66 case MONITOREXIT: 67 setFields.clear(); 68 break; 69 case PUTFIELD: 70 if (getClassConstantOperand().equals(getClassName())) 71 setFields.add(getNameConstantOperand()); 72 break; 73 case GETFIELD: 74 if (thisOnTOS && getClassConstantOperand().equals(getClassName()) 75 && setFields.contains(getNameConstantOperand()) 76 && asUnsignedByte(codeBytes[getPC() + 3]) == DUP 77 && asUnsignedByte(codeBytes[getPC() + 5]) == MONITORENTER 78 79 && !finalFields.contains(getNameConstantOperand()) 80 ) 81 bugReporter.reportBug(new BugInstance(this, "ML_SYNC_ON_UPDATED_FIELD", NORMAL_PRIORITY) 82 .addClassAndMethod(this) 83 .addReferencedField(this) 84 .addSourceLine(this, getPC() + 5)); 85 break; 86 default: 87 } 88 thisOnTOS = false; 89 } 90 } 91 | Popular Tags |