[Fb-contrib-commit] SF.net SVN: fb-contrib:[1549] trunk/fb-contrib/src/com/mebigfatguy/ fbcontrib/
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2010-05-08 04:18:36
|
Revision: 1549
http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1549&view=rev
Author: dbrosius
Date: 2010-05-08 04:18:29 +0000 (Sat, 08 May 2010)
Log Message:
-----------
report field WOC -- altho probably not as likely to catch as the allocation has to preceed the other uses.
Modified Paths:
--------------
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/WriteOnlyCollection.java
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/WriteOnlyCollection.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/WriteOnlyCollection.java 2010-05-08 04:17:41 UTC (rev 1548)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/WriteOnlyCollection.java 2010-05-08 04:18:29 UTC (rev 1549)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2010 Dave Brosius
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -52,16 +52,16 @@
{
collectionClasses.add(HashSet.class.getName());
collectionClasses.add(TreeSet.class.getName());
- collectionClasses.add(LinkedHashSet.class.getName());
+ collectionClasses.add(LinkedHashSet.class.getName());
collectionClasses.add(HashMap.class.getName());
collectionClasses.add(TreeMap.class.getName());
collectionClasses.add(Hashtable.class.getName());
- collectionClasses.add(LinkedHashMap.class.getName());
+ collectionClasses.add(LinkedHashMap.class.getName());
collectionClasses.add(Vector.class.getName());
collectionClasses.add(ArrayList.class.getName());
collectionClasses.add(LinkedList.class.getName());
}
-
+
private static Set<String> writeMethods = new HashSet<String>();
static
{
@@ -86,15 +86,15 @@
writeMethods.add("setSize");
writeMethods.add("trimToSize");
}
-
- private BugReporter bugReporter;
+
+ private final BugReporter bugReporter;
private OpcodeStack stack;
/** register to first allocation PC */
private Map<Integer, Integer> localWOCollections;
/** field to first allocation PC */
private Map<String, Integer> fieldWOCollections;
-
-
+
+
/**
* constructs a WOC detector given the reporter to report bugs on
* @param bugReporter the sync of bug reports
@@ -104,7 +104,7 @@
}
/**
* overrides the visitor to initialize and tear down the opcode stack
- *
+ *
* @param classContext the context object of the currently parsed class
*/
@Override
@@ -114,16 +114,22 @@
localWOCollections = new HashMap<Integer, Integer>();
fieldWOCollections = new HashMap<String, Integer>();
super.visitClassContext(classContext);
+
+ for (Integer pc : fieldWOCollections.values()) {
+ bugReporter.reportBug(new BugInstance(this, "WOC_WRITE_ONLY_COLLECTION", NORMAL_PRIORITY)
+ .addClass(this)
+ .addSourceLine(this, pc.intValue()));
+ }
} finally {
stack = null;
localWOCollections = null;
fieldWOCollections = null;
}
}
-
+
/**
* overrides the visitor reset the stack
- *
+ *
* @param obj the context object of the currently parsed code block
*/
@Override
@@ -131,25 +137,27 @@
stack.resetForMethodEntry(this);
localWOCollections.clear();
super.visitCode(obj);
-
+
for (Integer pc : localWOCollections.values()) {
- bugReporter.reportBug(new BugInstance(this, "WOC_WRITE_ONLY_COLLECTION", NORMAL_PRIORITY)
+ bugReporter.reportBug(new BugInstance(this,
+"WOC_WRITE_ONLY_COLLECTION", NORMAL_PRIORITY)
.addClass(this)
.addMethod(this)
.addSourceLine(this, pc.intValue()));
}
}
-
+
/**
- * overrides the visitor to look for uses of collections where the only access to
+ * overrides the visitor to look for uses of collections where the only
+access to
* to the collection is to write to it
- *
+ *
* @param seen the opcode of the currently visited instruction
*/
@Override
public void sawOpcode(int seen) {
Object userObject = null;
-
+
try {
switch (seen) {
case INVOKESPECIAL:
@@ -157,11 +165,13 @@
if ("<init>".equals(methodName)) {
String clsName = getClassConstantOperand().replace('/', '.');
if (collectionClasses.contains(clsName))
- userObject = Boolean.TRUE;
+ {
+ userObject = Boolean.TRUE;
+ }
}
processMethodParms();
break;
-
+
case INVOKEINTERFACE:
case INVOKEVIRTUAL:
String sig = getSigConstantOperand();
@@ -173,23 +183,28 @@
String name = getNameConstantOperand();
if (!writeMethods.contains(name)) {
clearUserValue(item);
+ } else if (!"clone".equals(name)) {
+ Type t = Type.getReturnType(sig);
+ if ((t != Type.VOID) && (getNextOpcode() != POP)) {
+ clearUserValue(item);
+ }
}
}
}
processMethodParms();
break;
-
+
case INVOKESTATIC:
processMethodParms();
break;
-
+
case ARETURN:
if (stack.getStackDepth() > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
clearUserValue(item);
}
break;
-
+
case ASTORE_0:
case ASTORE_1:
case ASTORE_2:
@@ -208,7 +223,7 @@
}
}
break;
-
+
case ALOAD_0:
case ALOAD_1:
case ALOAD_2:
@@ -219,7 +234,14 @@
userObject = Integer.valueOf(reg);
}
break;
-
+
+ case AASTORE:
+ if (stack.getStackDepth() >= 3) {
+ OpcodeStack.Item item = stack.getStackItem(0);
+ clearUserValue(item);
+ }
+ break;
+
case PUTFIELD:
if (stack.getStackDepth() > 1) {
OpcodeStack.Item item = stack.getStackItem(0);
@@ -228,7 +250,7 @@
if (uo instanceof Boolean) {
Item fieldItem = stack.getStackItem(1);
boolean storedInThis = fieldItem.getRegisterNumber() == 0;
- if (storedInThis) {
+ if (storedInThis) {
XField field = getXFieldOperand();
if ((field.getAccessFlags() & Constants.ACC_PRIVATE) != 0) {
String fieldName = field.getName();
@@ -241,7 +263,7 @@
}
}
break;
-
+
case GETFIELD:
if (stack.getStackDepth() > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
@@ -265,7 +287,7 @@
}
}
}
-
+
private void clearUserValue(OpcodeStack.Item item) {
Object uo = item.getUserValue();
if (uo instanceof Integer) {
@@ -275,7 +297,7 @@
}
item.setUserValue(null);
}
-
+
private void processMethodParms() {
String sig = getSigConstantOperand();
int numParms = Type.getArgumentTypes(sig).length;
@@ -286,3 +308,5 @@
}
}
}
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|