KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > detect > FindBadForLoop


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2005, University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

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 JavaDoc
39          public void visit(JavaClass obj) {
40     }
41
42     @Override JavaDoc
43          public void visit(Method obj) {
44     }
45
46                 LineNumberTable lineNumbers;
47     @Override JavaDoc
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 JavaDoc
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 JavaDoc e) {
116             // FIXME
117
System.out.println("Exception at " + getPC()
118                 + " in " + getFullyQualifiedMethodName());
119             e.printStackTrace(System.out);
120             }
121     }
122
123 }
124
Popular Tags