01: /*
02: * FindBugs - Find bugs in Java programs
03: * Copyright (C) 2003-2005 University of Maryland
04: *
05: * This library is free software; you can redistribute it and/or
06: * modify it under the terms of the GNU Lesser General Public
07: * License as published by the Free Software Foundation; either
08: * version 2.1 of the License, or (at your option) any later version.
09: *
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: import java.util.HashSet;
23: import java.util.Set;
24:
25: import edu.umd.cs.findbugs.BugInstance;
26: import edu.umd.cs.findbugs.BugReporter;
27: import edu.umd.cs.findbugs.BytecodeScanningDetector;
28: import edu.umd.cs.findbugs.ba.AnalysisContext;
29: import edu.umd.cs.findbugs.ba.ClassContext;
30: import edu.umd.cs.findbugs.ba.XField;
31:
32: public class VolatileUsage extends BytecodeScanningDetector {
33: private BugReporter bugReporter;
34:
35: public VolatileUsage(BugReporter bugReporter) {
36: this .bugReporter = bugReporter;
37: }
38:
39: @Override
40: public void visitClassContext(ClassContext classContext) {
41: classContext.getJavaClass().accept(this );
42: }
43:
44: Set<XField> initializationWrites = new HashSet<XField>();
45:
46: Set<XField> otherWrites = new HashSet<XField>();
47:
48: @Override
49: public void sawOpcode(int seen) {
50: switch (seen) {
51: case PUTSTATIC: {
52: XField f = getXFieldOperand();
53: if (!interesting(f))
54: return;
55: if (getMethodName().equals("<clinit>"))
56: initializationWrites.add(f);
57: else
58: otherWrites.add(f);
59: break;
60: }
61: case PUTFIELD: {
62: XField f = getXFieldOperand();
63: if (!interesting(f))
64: return;
65:
66: if (getMethodName().equals("<init>"))
67: initializationWrites.add(f);
68: else
69: otherWrites.add(f);
70: break;
71: }
72: }
73: }
74:
75: @Override
76: public void report() {
77:
78: for (XField f : AnalysisContext.currentXFactory().allFields())
79: if (interesting(f)) {
80: int priority = LOW_PRIORITY;
81: if (initializationWrites.contains(f)
82: && !otherWrites.contains(f))
83: priority = NORMAL_PRIORITY;
84: bugReporter.reportBug(new BugInstance(this ,
85: "VO_VOLATILE_REFERENCE_TO_ARRAY", priority)
86: .addClass(f.getClassDescriptor()).addField(f));
87: }
88: }
89:
90: /**
91: * @param f
92: * @return
93: */
94: private boolean interesting(XField f) {
95: return f != null && f.isVolatile()
96: && f.getSignature().charAt(0) == '[';
97: }
98: }
|