1 19 20 package edu.umd.cs.findbugs.detect; 21 22 23 import edu.umd.cs.findbugs.*; 24 import org.apache.bcel.classfile.*; 25 26 public class FindBadForLoop extends BytecodeScanningDetector implements StatelessDetector { 27 28 29 OpcodeStack stack = new OpcodeStack(); 30 BugReporter bugReporter; 31 32 public FindBadForLoop(BugReporter bugReporter) { 33 this.bugReporter = bugReporter; 34 } 35 36 37 38 @Override 39 public void visit(JavaClass obj) { 40 } 41 42 @Override 43 public void visit(Method obj) { 44 } 45 46 LineNumberTable lineNumbers; 47 @Override 48 public void visit(Code obj) { 49 lastRegStore = -1; 50 lineNumbers = obj.getLineNumberTable(); 51 stack.resetForMethodEntry(this); 52 super.visit(obj); 53 } 54 55 56 int lastRegStore; 57 @Override 58 public void sawOpcode(int seen) { 59 stack.mergeJumps(this); 60 try { 61 if (seen == ISTORE 62 || seen == ISTORE_0 63 || seen == ISTORE_1 64 || seen == ISTORE_2 65 || seen == ISTORE_3) 66 lastRegStore = getRegisterOperand(); 67 if (lineNumbers!= null && stack.getStackDepth() >= 2 && ( 68 seen == IF_ICMPGE 69 || seen == IF_ICMPGT 70 || seen == IF_ICMPLT 71 || seen == IF_ICMPLE 72 || seen == IF_ICMPNE 73 || seen == IF_ICMPEQ)) { 74 OpcodeStack.Item item0 = stack.getStackItem(0); 75 OpcodeStack.Item item1 = stack.getStackItem(1); 76 int r0 = item0.getRegisterNumber(); 77 int r1 = item1.getRegisterNumber(); 78 int rMin = Math.min(r0,r1); 79 int rMax = Math.max(r0,r1); 80 int branchTarget = getBranchTarget(); 81 if (rMin == -1 && rMax > 0 && rMax == lastRegStore 82 && branchTarget-6 > getPC()) { 83 int beforeTarget = getCodeByte(branchTarget - 3); 84 int beforeGoto = getCodeByte(branchTarget - 6); 85 if (beforeTarget == GOTO && beforeGoto == IINC) { 86 int offset1 = (byte) getCodeByte(branchTarget - 2); 87 int offset2 = getCodeByte(branchTarget - 1); 88 int offset = offset1 << 8 | offset2; 89 int backTarget = branchTarget - 3 + offset; 90 int reg = getCodeByte(branchTarget - 5); 91 int testLineNumber 92 = lineNumbers.getSourceLine(getPC()); 93 int incLineNumber 94 = lineNumbers.getSourceLine(branchTarget-6); 95 int beforeIncLineNumber 96 = lineNumbers.getSourceLine(branchTarget-7); 97 if (backTarget < getPC() && 98 getPC() - 8 < backTarget 99 && reg != rMax 100 && incLineNumber < testLineNumber+3 101 && beforeIncLineNumber > incLineNumber 102 ) { 103 104 bugReporter.reportBug(new BugInstance(this, "QF_QUESTIONABLE_FOR_LOOP", NORMAL_PRIORITY) 105 .addClassAndMethod(this) 106 .addSourceLine(this)); 107 } 108 } 109 110 } 111 } 112 113 stack.sawOpcode(this, seen); 114 115 } catch (RuntimeException e) { 116 System.out.println("Exception at " + getPC() 118 + " in " + getFullyQualifiedMethodName()); 119 e.printStackTrace(System.out); 120 } 121 } 122 123 } 124 | Popular Tags |