[Fb-contrib-commit] SF.net SVN: fb-contrib:[1729] trunk/fb-contrib
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2012-10-31 17:33:09
|
Revision: 1729
http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1729&view=rev
Author: dbrosius
Date: 2012-10-31 17:32:54 +0000 (Wed, 31 Oct 2012)
Log Message:
-----------
sync from github
Modified Paths:
--------------
trunk/fb-contrib/.classpath
trunk/fb-contrib/build.xml
trunk/fb-contrib/etc/findbugs.xml
trunk/fb-contrib/etc/messages.xml
trunk/fb-contrib/samples/CVAA_Sample.java
trunk/fb-contrib/samples/DWI_Sample.java
trunk/fb-contrib/samples/LEST_Sample.java
trunk/fb-contrib/samples/SMII_Sample.java
trunk/fb-contrib/samples/USBR_Sample.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CompareClassNameEquals.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ContraVariantArrayAssignment.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossibleConstantAllocationInLoop.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SpoiledChildInterfaceImplementor.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/StaticMethodInstanceInvocation.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnnecessaryNewNullCheck.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnnecessaryStoreBeforeReturn.java
Modified: trunk/fb-contrib/.classpath
===================================================================
--- trunk/fb-contrib/.classpath 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/.classpath 2012-10-31 17:32:54 UTC (rev 1729)
@@ -9,17 +9,6 @@
<classpathentry kind="lib" path="samples/lib/junit-4.10.jar"/>
<classpathentry kind="lib" path="samples/lib/log4j-1.2.16.jar"/>
<classpathentry kind="lib" path="samples/lib/servlet-api-3.0.1.jar"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/asm-3.3.jar"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/asm-analysis-3.3.jar"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/asm-commons-3.3.jar"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/asm-tree-3.3.jar"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/asm-util-3.3.jar"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/bcel.jar"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/dom4j-1.6.1.jar"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/findbugs.jar" sourcepath="/findbugs"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/jaxen-1.1.1.jar"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/jFormatString.jar"/>
- <classpathentry kind="lib" path="/home/dave/dev/avondale/3rdparty/findbugs/lib/jsr305.jar"/>
<classpathentry kind="lib" path="samples/lib/commons-lang3-3.1.jar"/>
<classpathentry kind="lib" path="samples/lib/backport-concurrent-3.1.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/findbugs"/>
Modified: trunk/fb-contrib/build.xml
===================================================================
--- trunk/fb-contrib/build.xml 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/build.xml 2012-10-31 17:32:54 UTC (rev 1729)
@@ -17,7 +17,7 @@
<property name="javac.deprecation" value="on" />
<property name="javac.debug" value="on" />
- <property name="fb-contrib.version" value="4.8.1" />
+ <property name="fb-contrib.version" value="4.9.0" />
<property name="findbugs.version" value="2.0.0" />
<property name="findbugs-bcel.version" value="2.0.0" />
Modified: trunk/fb-contrib/etc/findbugs.xml
===================================================================
--- trunk/fb-contrib/etc/findbugs.xml 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/etc/findbugs.xml 2012-10-31 17:32:54 UTC (rev 1729)
@@ -30,9 +30,9 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.UnrelatedCollectionContents" speed="fast" reports="UCC_UNRELATED_COLLECTION_CONTENTS" />
<Detector class="com.mebigfatguy.fbcontrib.detect.DeclaredRuntimeException" speed="fast" reports="DRE_DECLARED_RUNTIME_EXCEPTION" />
-<!-- COMMENT OUT FOR RELEASE
+<!-- COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.detect.ClassEnvy" speed="fast" reports="CE_CLASS_ENVY" disabled="true" />
- COMMENT OUT FOR RELEASE -->
+<!-- COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.detect.LiteralStringComparison" speed="fast" reports="LSC_LITERAL_STRING_COMPARISON" />
<Detector class="com.mebigfatguy.fbcontrib.detect.PartiallyConstructedObjectAccess" speed="fast" reports="PCOA_PARTIALLY_CONSTRUCTED_OBJECT_ACCESS" />
@@ -73,9 +73,9 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.AbstractOverriddenMethod" speed="fast" reports="AOM_ABSTRACT_OVERRIDDEN_METHOD" />
<Detector class="com.mebigfatguy.fbcontrib.detect.CustomBuiltXML" speed="fast" reports="CBX_CUSTOM_BUILT_XML" />
-<!-- COMMENT OUT FOR RELEASE
+<!-- COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.detect.BloatedSynchronizedBlock" speed="fast" reports="BSB_BLOATED_SYNCHRONIZED_BLOCK" hidden="true" />
- COMMENT OUT FOR RELEASE -->
+<!-- COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.detect.ConstantListIndex" speed="fast" reports="CLI_CONSTANT_LIST_INDEX" />
<Detector class="com.mebigfatguy.fbcontrib.detect.SloppyClassReflection" speed="fast" reports="SCR_SLOPPY_CLASS_REFLECTION" />
@@ -176,9 +176,9 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.UnnecessaryNewNullCheck" speed="fast" reports="UNNC_UNNECESSARY_NEW_NULL_CHECK" />
<Detector class="com.mebigfatguy.fbcontrib.detect.DeprecatedTypesafeEnumPattern" speed="fast" reports="DTEP_DEPRECATED_TYPESAFE_ENUM_PATTERN" />
-<!-- COMMENT OUT FOR RELEASE
+<!-- COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.detect.StutteredMethodArguments" speed="fast" reports="SMA_STUTTERED_METHOD_ARGUMENTS" hidden="true" />
- COMMENT OUT FOR RELEASE -->
+<!-- COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.detect.TristateBooleanPattern" speed="fast" reports="TBP_TRISTATE_BOOLEAN_PATTERN" />
@@ -193,9 +193,9 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.PoorlyDefinedParameter" speed="fast" reports="PDP_POORLY_DEFINED_PARAMETER" />
<Detector class="com.mebigfatguy.fbcontrib.detect.NonSymmetricEquals" speed="fast" reports="NSE_NON_SYMMETRIC_EQUALS" />
-<!-- COMMENT OUT FOR RELEASE
+<!-- COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.detect.ContraVariantArrayAssignment" speed="fast" hidden="true" reports="CVAA_CONTRAVARIANT_ARRAY_ASSIGNMENT,CVAA_CONTRAVARIANT_ELEMENT_ASSIGNMENT" />
- COMMENT OUT FOR RELEASE -->
+<!-- COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.detect.NonFunctionalField" speed="fast" reports="NFF_NON_FUNCTIONAL_FIELD" />
@@ -221,9 +221,9 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousGetterSetterUse" speed="fast" reports="SGSU_SUSPICIOUS_GETTER_SETTER_USE" />
<Detector class="com.mebigfatguy.fbcontrib.detect.LingeringGraphicsObjects" speed="fast" reports="LGO_LINGERING_GRAPHICS_OBJECT" />
-<!-- COMMENT OUT FOR RELEASE
+<!-- COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.detect.StackedTryBlocks" speed="fast" reports="STB_STACKED_TRY_BLOCKS" />
- COMMENT OUT FOR RELEASE -->
+<!-- COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.detect.CommonsEqualsBuilderToEquals" speed="fast" reports="CEBE_COMMONS_EQUALS_BUILDER_ISEQUALS" />
<Detector class="com.mebigfatguy.fbcontrib.detect.CommonsHashcodeBuilderToHashcode" speed="fast" reports="CHTH_COMMONS_HASHCODE_BUILDER_TOHASHCODE" />
@@ -334,7 +334,7 @@
<BugPattern abbrev="SPP" type="SPP_EMPTY_CASING" category="STYLE" />
<BugPattern abbrev="SPP" type="SPP_TEMPORARY_TRIM" category="STYLE" />
<BugPattern abbrev="BAS" type="BAS_BLOATED_ASSIGNMENT_SCOPE" category="PERFORMANCE" />
- <BugPattern abbrev="SCII" type="SCII_SPOILED_CHILD_INTERFACE_IMPLEMENTATOR" category="STYLE" />
+ <BugPattern abbrev="SCII" type="SCII_SPOILED_CHILD_INTERFACE_IMPLEMENTOR" category="STYLE" />
<BugPattern abbrev="DWI" type="DWI_DELETING_WHILE_ITERATING" category="CORRECTNESS" />
<BugPattern abbrev="DWI" type="DWI_MODIFYING_WHILE_ITERATING" category="CORRECTNESS" />
<BugPattern abbrev="USS" type="USS_USE_STRING_SPLIT" category="STYLE" />
Modified: trunk/fb-contrib/etc/messages.xml
===================================================================
--- trunk/fb-contrib/etc/messages.xml 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/etc/messages.xml 2012-10-31 17:32:54 UTC (rev 1729)
@@ -2547,7 +2547,7 @@
</Details>
</BugPattern>
- <BugPattern type="SCII_SPOILED_CHILD_INTERFACE_IMPLEMENTATOR">
+ <BugPattern type="SCII_SPOILED_CHILD_INTERFACE_IMPLEMENTOR">
<ShortDescription>Class implements interface by relying on unknowing superclass methods</ShortDescription>
<LongDescription>Class {0} implements interface by relying on unknowing superclass methods</LongDescription>
<Details>
Modified: trunk/fb-contrib/samples/CVAA_Sample.java
===================================================================
--- trunk/fb-contrib/samples/CVAA_Sample.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/samples/CVAA_Sample.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -1,13 +1,15 @@
+import java.util.Set;
+
public class CVAA_Sample
{
Base[] b2;
class Base {}
-
+
class Derived extends Base {}
-
+
public void cvaa()
- {
+ {
Derived[] d2 = new Derived[4];
Base[] b = d2;
b2 = d2;
@@ -16,12 +18,16 @@
b[1] = doDerived();
b[2] = null;
b[3] = d;
-
+
Integer[] a = new Integer[1];
System.arraycopy(a[0], 0, a, 1, 1);
}
-
+
private Derived doDerived(){
return new Derived();
}
+
+ public String fpVarArgs(String s1, Set<String> s2) {
+ return String.format("s1=%s s2=%s", s1, s2);
+ }
}
\ No newline at end of file
Modified: trunk/fb-contrib/samples/DWI_Sample.java
===================================================================
--- trunk/fb-contrib/samples/DWI_Sample.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/samples/DWI_Sample.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -3,10 +3,10 @@
import java.util.Iterator;
import java.util.Set;
-public class DWI_Sample
+public class DWI_Sample
{
Set<String> avail;
-
+
public void deleteOdds(Set<Integer> bagOInts)
{
Iterator<Integer> it = bagOInts.iterator();
@@ -17,7 +17,7 @@
bagOInts.remove(i);
}
}
-
+
public void addIf(Set<String> s, Collection<String> c) {
for (String ss : s)
{
@@ -25,7 +25,7 @@
s.addAll(c);
}
}
-
+
public void fpUnaliased()
{
Iterator<String> it = avail.iterator();
@@ -36,7 +36,7 @@
avail.add(it.next() + "booya");
}
}
-
+
public void fpWithBreak(Set<String> ss)
{
for (String s : ss)
@@ -47,4 +47,15 @@
}
}
}
+
+ public void fpClearWithBreak(Set<String> ss)
+ {
+ for (String s : ss)
+ {
+ if (s.equals("foo")) {
+ ss.clear();
+ break;
+ }
+ }
+ }
}
Modified: trunk/fb-contrib/samples/LEST_Sample.java
===================================================================
--- trunk/fb-contrib/samples/LEST_Sample.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/samples/LEST_Sample.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -1,3 +1,4 @@
+import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -139,6 +140,26 @@
}
}
+ public void testLestFP3510540() throws Exception
+ {
+ boolean bool = true;
+ if (bool)
+ {
+ try
+ {
+ throw new IOException();
+ }
+ catch (IOException ioe)
+ {
+ throw new Exception(ioe);
+ }
+ }
+ else
+ {
+ throw new Exception("message");
+ }
+ }
+
private Exception wrap(Exception e) {
return new Exception(e);
}
Modified: trunk/fb-contrib/samples/SMII_Sample.java
===================================================================
--- trunk/fb-contrib/samples/SMII_Sample.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/samples/SMII_Sample.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -6,72 +6,82 @@
public class SMII_Sample
{
private Inner i = new Inner();
-
+
public static void static_empty()
{
}
-
+
public static void static_one(String s)
{
}
-
+
public void test_empty(SMII_Sample smii)
{
smii.static_empty();
}
-
+
public void test_empty2(SMII_Sample smii)
{
smii.static_one("foo".toUpperCase());
}
-
- public SMII_Sample getSMI()
+
+ public SMII_Sample getSMI()
{
return new SMII_Sample();
}
-
+
public void test_chaining()
{
new SMII_Sample().getSMI().static_one("hello");
}
-
+
public void test_dotclass()
{
Set s = new HashSet();
s.add(String.class);
}
-
+
public void test_ClassForName() throws ClassNotFoundException
{
Class c = Class.forName("java.lang.Object");
}
-
+
public void test_ClassGetName()
{
String name = Object.class.getName();
}
-
+
public void avoidGeneratedMethods(final Inner inner)
{
inner.next = null;
}
-
+
public static class Inner
{
- private Inner next;
+ private Inner next;
}
-
- public void testFPInstance(SMII_Sample sample)
+
+ public static SMII_Sample fp1()
{
+ SMII_Sample s = new SMII_Sample();
+
+ SMII_Sample.fp1();
+ SMII_Sample.fp1();
+
+ return s;
+ }
+
+ public void testFP2Instance(SMII_Sample sample)
+ {
SMII_Sample.testInstanceAsFirstParm(sample, "");
SMII_Sample.testInstanceAsFirstParm("");
}
-
+
public static SMII_Sample testInstanceAsFirstParm(String s1)
{
return new SMII_Sample();
}
-
+
public static SMII_Sample testInstanceAsFirstParm(SMII_Sample sample, String s1)
{
return sample;
Modified: trunk/fb-contrib/samples/USBR_Sample.java
===================================================================
--- trunk/fb-contrib/samples/USBR_Sample.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/samples/USBR_Sample.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -10,17 +10,17 @@
{
sum += Integer.parseInt(s);
}
-
+
int ave = sum / tokens.length;
return ave;
}
-
+
public int dontReport(int j)
{
int i;
try
{
- i = 0;
+ i = 0;
i = i / j;
}
catch (Exception e)
@@ -29,7 +29,7 @@
}
return i;
}
-
+
public Exception fpReturnException(String num)
{
try
@@ -42,7 +42,7 @@
return e;
}
}
-
+
public int fpPlusEquals()
{
int i = 0;
@@ -50,4 +50,10 @@
i+= dontReport(i);
return i;
}
+
+ public boolean fpOrEquals(boolean b)
+ {
+ b |= fpOrEquals(b);
+ return b;
+ }
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -70,7 +70,7 @@
/**
* constructs a BAS detector given the reporter to report bugs on
- *
+ *
* @param bugReporter
* the sync of bug reports
*/
@@ -81,7 +81,7 @@
/**
* implements the visitor to create and the clear the register to location
* map
- *
+ *
* @param classContext
* the context object of the currently parsed class
*/
@@ -105,7 +105,7 @@
/**
* implements the visitor to reset the register to location map
- *
+ *
* @param obj
* the context object of the currently parsed code block
*/
@@ -152,7 +152,7 @@
/**
* implements the visitor to look for variables assigned below the scope in
* which they are used.
- *
+ *
* @param seen
* the opcode of the currently parsed instruction
*/
@@ -372,7 +372,7 @@
/**
* returns either a register number of a field reference of the object that
* a method is being called on, or null, if it can't be determined.
- *
+ *
* @return either an Integer for a register, or a String for the field name,
* or null
*/
@@ -407,7 +407,7 @@
/**
* returns the scope block in which this register was assigned, by
* traversing the scope block tree
- *
+ *
* @param sb
* the scope block to start searching in
* @param pc
@@ -433,12 +433,12 @@
/**
* returns an existing scope block that has the same target as the one
* looked for
- *
+ *
* @param sb
* the scope block to start with
* @param target
* the target to look for
- *
+ *
* @return the scope block found or null
*/
private ScopeBlock findScopeBlockWithTarget(ScopeBlock sb, int start,
@@ -479,7 +479,7 @@
/**
* construts a new scope block
- *
+ *
* @param start
* the beginning of the block
* @param finish
@@ -499,7 +499,7 @@
/**
* returns a string representation of the scope block
- *
+ *
* @returns a string representation
*/
@Override
@@ -511,7 +511,7 @@
/**
* returns the scope blocks parent
- *
+ *
* @return the parent of this scope block
*/
public ScopeBlock getParent() {
@@ -520,7 +520,7 @@
/**
* returns the start of the block
- *
+ *
* @return the start of the block
*/
public int getStart() {
@@ -529,7 +529,7 @@
/**
* returns the end of the block
- *
+ *
* @return the end of the block
*/
public int getFinish() {
@@ -538,7 +538,7 @@
/**
* sets the start pc of the block
- *
+ *
* @param start
* the start pc
*/
@@ -548,7 +548,7 @@
/**
* sets the finish pc of the block
- *
+ *
* @param finish
* the finish pc
*/
@@ -569,7 +569,7 @@
/**
* returns whether this scope block is a loop
- *
+ *
* @returns whether this block is a loop
*/
public boolean isLoop() {
@@ -585,7 +585,7 @@
/**
* returns whether this block was caused from a goto
- *
+ *
* @returns whether this block was caused by a goto
*/
public boolean isGoto() {
@@ -594,7 +594,7 @@
/**
* adds the register as a store in this scope block
- *
+ *
* @param reg
* the register that was stored
* @param pc
@@ -615,7 +615,7 @@
/**
* removes stores to registers that where retrieved from method calls on
* assocObject
- *
+ *
* @param assocObject
* the object that a method call was just performed on
*/
@@ -635,7 +635,7 @@
/**
* adds the register as a load in this scope block
- *
+ *
* @param reg
* the register that was loaded
* @param pc
@@ -652,7 +652,7 @@
/**
* adds a scope block to this subtree by finding the correct place in
* the hierarchy to store it
- *
+ *
* @param newChild
* the scope block to add to the tree
*/
@@ -684,7 +684,7 @@
/**
* removes a child from this node
- *
+ *
* @param child
* the child to remove
*/
@@ -760,10 +760,10 @@
/**
* returns whether this block either loads or stores into the register
* in question
- *
+ *
* @param reg
* the register to look for loads or stores
- *
+ *
* @return whether the block uses the register
*/
public boolean usesReg(Integer reg) {
@@ -823,7 +823,7 @@
return dangerousAssignmentMethodSources.contains(key);
}
- class UserObject {
+ static class UserObject {
Comparable<?> caller;
boolean isRisky;
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ClassEnvy.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2012 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
@@ -87,7 +87,7 @@
/**
* overrides the visitor to collect package and class names
- *
+ *
* @param classContext the context object that holds the JavaClass being parsed
*/
@Override
@@ -106,7 +106,7 @@
/**
* overrides the visitor to check whether the method is static
- *
+ *
* @param obj the method currently being parsed
*/
@Override
@@ -118,7 +118,7 @@
/**
* overrides the visitor to look for the method that uses another class the most, and
* if it exceeds the threshold reports it
- *
+ *
* @param obj the code that is currently being parsed
*/
@Override
@@ -147,11 +147,11 @@
if (bestEnvyCount < envyMin) {
return;
}
- String bestEnvy = bestEnvyEntry.getKey();
double bestPercent = ((double)bestEnvyCount) / ((double) (bestEnvyCount + thisClsAccessCount));
if (bestPercent > envyPercent) {
+ String bestEnvy = bestEnvyEntry.getKey();
if (implementsCommonInterface(bestEnvy)) {
return;
}
@@ -168,7 +168,7 @@
/**
* overrides the visitor to look for method calls, and populate a class access count map
* based on the owning class of methods called.
- *
+ *
* @param seen the opcode currently being parsed
*/
@Override
@@ -204,9 +204,9 @@
/**
* return whether or not a class implements a common or marker interface
- *
+ *
* @param name the class name to check
- *
+ *
* @return if this class implements a common or marker interface
*/
private boolean implementsCommonInterface(String name) {
@@ -233,9 +233,9 @@
/**
* increment the count of class access of the class on the stack
- *
+ *
* @param classAtStackIndex the position on the stack of the class in question
- *
+ *
* @return true if the class is counted
*/
private boolean countClassAccess(final int classAtStackIndex) {
@@ -261,7 +261,7 @@
/**
* increment the count of class access of the specified class if it is in a similar
* package to the caller, and is not general purpose
- *
+ *
* @param calledClass the class to check
*/
private void countClassAccess(final String calledClass) {
@@ -284,7 +284,7 @@
/**
* add the current line number to a set of line numbers
- *
+ *
* @param lineNumbers the current set of line numbers
*/
private void addLineNumber(Set<Integer> lineNumbers) {
@@ -303,9 +303,9 @@
/**
* checks to see if the specified class is a built in class, or implements a simple interface
- *
+ *
* @param className the class in question
- *
+ *
* @return whether or not the class is general purpose
*/
private boolean generalPurpose(final String className) {
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CompareClassNameEquals.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CompareClassNameEquals.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CompareClassNameEquals.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -2,17 +2,17 @@
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2012 Bhaskar Maddala
* Copyright (C) 2005-2012 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
@@ -31,13 +31,13 @@
* In a JVM, Two classes are the same class (and consequently the same type) if
* they are loaded by the same class loader, and they have the same fully
* qualified name [JVMSpec 1999].
- *
+ *
* Two classes with the same name but different package names are distinct, as
* are two classes with the same fully qualified name loaded by different class
* loaders.
- *
+ *
* Find usage involving comparison of class names, rather than the class itself.
- *
+ *
*/
public class CompareClassNameEquals extends OpcodeStackDetector {
private boolean flag = false;
@@ -76,7 +76,7 @@
&& "java/lang/String".equals(getClassConstantOperand())) {
Item item = stack.getItemMethodInvokedOn(this);
Object userValue = item.getUserValue();
- if (userValue != null && userValue == Boolean.TRUE) {
+ if (userValue != null && Boolean.TRUE.equals(userValue)) {
bugReporter
.reportBug(new BugInstance(this,
"CCNE_COMPARE_CLASS_EQUALS_NAME",
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ContraVariantArrayAssignment.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ContraVariantArrayAssignment.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ContraVariantArrayAssignment.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2012 Bhaskar Maddala
- *
+ *
* 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
@@ -33,18 +33,18 @@
import edu.umd.cs.findbugs.OpcodeStack;
/**
- * Finds contravariant array assignments. Since arrays are mutable data structures, their use
+ * Finds contravariant array assignments. Since arrays are mutable data structures, their use
* must be restricted to covariant or invariant usage
- *
+ *
* <pre>
* class A {}
* class B extends A {}
- *
+ *
* B[] b = new B[2];
* A[] a = b;
* a[0] = new A(); // results in ArrayStoreException (Runtime)
* </pre>
- *
+ *
* Contravariant array assignments are reported as low or normal priority bugs. In cases
* where the detector can determine an ArrayStoreException the bug is reported with high priority.
*
@@ -52,7 +52,7 @@
public class ContraVariantArrayAssignment extends BytecodeScanningDetector {
private final BugReporter bugReporter;
private final OpcodeStack stack;
-
+
/**
* constructs a CVAA detector given the reporter to report bugs on.
@@ -65,9 +65,9 @@
/**
* implements the visitor to pass through constructors and static initializers to the
- * byte code scanning code. These methods are not reported, but are used to build
+ * byte code scanning code. These methods are not reported, but are used to build
* SourceLineAnnotations for fields, if accessed.
- *
+ *
* @param obj the context object of the currently parsed code attribute
*/
@Override
@@ -81,7 +81,7 @@
@Override
public void sawOpcode(int seen) {
- try{
+ try{
switch(seen){
case ASTORE:
case ASTORE_0:
@@ -102,23 +102,24 @@
case PUTFIELD:
case PUTSTATIC:
if(stack.getStackDepth() > 0){
- OpcodeStack.Item item = stack.getStackItem(0);
+ OpcodeStack.Item item = stack.getStackItem(0);
String sourceSignature = item.getSignature();
String targetSignature = getSigConstantOperand();
checkSignatures(sourceSignature, targetSignature);
}
break;
case AASTORE:
+/*
OpcodeStack.Item arrayref = stack.getStackItem(2);
OpcodeStack.Item value = stack.getStackItem(0);
-
+
if(!value.isNull()) {
- String sourceSignature = value.getSignature();
+ String sourceSignature = value.getSignature();
String targetSignature = arrayref.getSignature();
if (!"Ljava/lang/Object;".equals(targetSignature)) {
try{
if(Type.getType(sourceSignature) instanceof ObjectType ) {
- ObjectType sourceType = (ObjectType) Type.getType(sourceSignature);
+ ObjectType sourceType = (ObjectType) Type.getType(sourceSignature);
ObjectType targetType = (ObjectType) ((ArrayType) Type.getType(targetSignature)).getBasicType();
if(!sourceType.equals(targetType) && !sourceType.subclassOf(targetType)){
bugReporter.reportBug(new BugInstance(this, "CVAA_CONTRAVARIANT_ARRAY_ASSIGNMENT", HIGH_PRIORITY)
@@ -132,6 +133,7 @@
}
}
}
+*/
break;
}
super.sawOpcode(seen);
@@ -140,11 +142,11 @@
stack.sawOpcode(this, seen);
}
}
-
+
private boolean isArrayType(String signature){
return Type.getType(signature) instanceof ArrayType;
}
-
+
private boolean isObjectType(String signature){
return ((ArrayType)Type.getType(signature)).getBasicType() instanceof ObjectType;
}
@@ -154,7 +156,7 @@
if ("Ljava/lang/Object;".equals(targetSignature)) {
return;
}
-
+
if(isArrayType(sourceSignature) && isArrayType(targetSignature)) {
if(isObjectType(sourceSignature) && isObjectType(targetSignature)) {
ObjectType sourceType = (ObjectType) ((ArrayType) Type.getType(sourceSignature)).getBasicType();
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2012 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
@@ -32,6 +32,7 @@
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.LocalVariable;
import org.apache.bcel.classfile.LocalVariableTable;
+import org.apache.bcel.generic.Type;
import com.mebigfatguy.fbcontrib.utils.CodeByteUtils;
import com.mebigfatguy.fbcontrib.utils.RegisterUtils;
@@ -52,8 +53,8 @@
* this occurs the iterator will become invalid and throw a ConcurrentModificationException.
* Instead, the remove should be called on the iterator itself.
*/
-public class DeletingWhileIterating extends BytecodeScanningDetector
-{
+public class DeletingWhileIterating extends BytecodeScanningDetector
+{
private static JavaClass collectionClass;
private static JavaClass iteratorClass;
private static Set<JavaClass> exceptionClasses;
@@ -66,14 +67,14 @@
collectionClass = null;
iteratorClass = null;
}
-
+
try {
exceptionClasses = new HashSet<JavaClass>();
exceptionClasses.add(Repository.lookupClass("java.util.concurrent.CopyOnWriteArrayList"));
exceptionClasses.add(Repository.lookupClass("java.util.concurrent.CopyOnWriteArraySet"));
} catch (ClassNotFoundException cnfe) {
}
-
+
collectionMethods = new HashSet<String>();
collectionMethods.add("entrySet()Ljava/lang/Set;");
collectionMethods.add("keySet()Ljava/lang/Set;");
@@ -96,7 +97,7 @@
private Map<Integer, Integer> groupToIterator;
private Map<Integer, Loop> loops;
private Map<Integer, Set<Integer>> endOfScopes;
-
+
/**
* constructs a DWI detector given the reporter to report bugs on
* @param bugReporter the sync of bug reports
@@ -104,18 +105,18 @@
public DeletingWhileIterating(BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
-
+
/**
* implements the visitor to setup the opcode stack, collectionGroups, groupToIterator and loops
- *
+ *
* @param classContext the context object of the currently parsed class
*/
@Override
public void visitClassContext(ClassContext classContext) {
if ((collectionClass == null) || (iteratorClass == null))
return;
-
- try {
+
+ try {
stack = new OpcodeStack();
collectionGroups = new ArrayList<Set<Comparable<?>>>();
groupToIterator = new HashMap<Integer, Integer>();
@@ -129,10 +130,10 @@
endOfScopes = null;
}
}
-
+
/**
* implements the visitor to reset the stack, collectionGroups, groupToIterator and loops
- *
+ *
* @param obj the context object of the currently parsed code block
*/
@Override
@@ -142,19 +143,19 @@
groupToIterator.clear();
loops.clear();
buildVariableEndScopeMap();
-
+
super.visitCode(obj);
}
-
+
/**
* implements the visitor to look for deletes on collections that are being iterated
- *
+ *
* @param seen the opcode of the currently parsed instruction
*/
@Override
public void sawOpcode(int seen) {
int groupId = -1;
-
+
try {
if (seen == INVOKEINTERFACE)
{
@@ -162,13 +163,13 @@
String methodName = getNameConstantOperand();
String signature = getSigConstantOperand();
String methodInfo = methodName + signature;
-
+
if (isCollection(className)) {
if (collectionMethods.contains(methodInfo)) {
if (stack.getStackDepth() > 0) {
OpcodeStack.Item itm = stack.getStackItem(0);
groupId = findCollectionGroup(itm, true);
-
+
}
} else if ("iterator()Ljava/util/Iterator;".equals(methodInfo)) {
if (stack.getStackDepth() > 0) {
@@ -185,19 +186,8 @@
if (loop != null) {
int pc = getPC();
if (loop.hasPC(pc)) {
- boolean breakFollows = false;
- byte[] code = getCode().getCode();
- int nextPC = getNextPC();
- int popOp = CodeByteUtils.getbyte(code, nextPC++);
- if (popOp == Constants.POP) {
- int gotoOp = CodeByteUtils.getbyte(code, nextPC);
- if (gotoOp == Constants.GOTO) {
- int target = nextPC + CodeByteUtils.getshort(code, nextPC+1);
- if (target > loop.getLoopFinish())
- breakFollows = true;
- }
- }
-
+ boolean breakFollows = breakFollows(loop, !Type.getReturnType(signature).getSignature().equals("V"));
+
if (!breakFollows) {
bugReporter.reportBug(new BugInstance(this, "DWI_DELETING_WHILE_ITERATING", NORMAL_PRIORITY)
.addClass(this)
@@ -221,10 +211,13 @@
if (loop != null) {
int pc = getPC();
if (loop.hasPC(pc)) {
- bugReporter.reportBug(new BugInstance(this, "DWI_MODIFYING_WHILE_ITERATING", NORMAL_PRIORITY)
+ boolean breakFollows = breakFollows(loop, !Type.getReturnType(signature).getSignature().equals("V"));
+ if (!breakFollows) {
+ bugReporter.reportBug(new BugInstance(this, "DWI_MODIFYING_WHILE_ITERATING", NORMAL_PRIORITY)
.addClass(this)
.addMethod(this)
.addSourceLine(this));
+ }
}
}
}
@@ -243,7 +236,7 @@
} else if (seen == PUTFIELD) {
if (stack.getStackDepth() > 1) {
OpcodeStack.Item itm = stack.getStackItem(0);
-
+
Integer id = (Integer)itm.getUserValue();
if (id == null) {
FieldAnnotation fa = FieldAnnotation.fromFieldDescriptor(new FieldDescriptor(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand(), false));
@@ -257,7 +250,7 @@
Integer id = (Integer)itm.getUserValue();
if (id != null) {
int reg = RegisterUtils.getAStoreReg(this, seen);
-
+
try {
JavaClass cls = itm.getJavaClass();
if ((cls != null) && cls.implementationOf(iteratorClass)) {
@@ -269,7 +262,7 @@
}
groupToIterator.put(id, regIt);
}
-
+
Set<Comparable<?>> group = collectionGroups.get(id.intValue());
if (group != null) {
group.add(Integer.valueOf(reg));
@@ -309,11 +302,33 @@
OpcodeStack.Item itm = stack.getStackItem(0);
itm.setUserValue(Integer.valueOf(groupId));
}
-
+
processEndOfScopes(Integer.valueOf(getPC()));
}
}
-
+
+ private boolean breakFollows(Loop loop, boolean needsPop) {
+
+ byte[] code = getCode().getCode();
+ int nextPC = getNextPC();
+
+ if (needsPop) {
+ int popOp = CodeByteUtils.getbyte(code, nextPC++);
+ if (popOp != Constants.POP) {
+ return false;
+ }
+ }
+
+ int gotoOp = CodeByteUtils.getbyte(code, nextPC);
+ if ((gotoOp == Constants.GOTO) || (gotoOp == Constants.GOTO_W)) {
+ int target = nextPC + CodeByteUtils.getshort(code, nextPC+1);
+ if (target > loop.getLoopFinish())
+ return true;
+ }
+
+ return false;
+ }
+
private boolean isCollection(String className) {
try {
JavaClass cls = Repository.lookupClass(className);
@@ -323,10 +338,10 @@
return false;
}
}
-
+
private Comparable<?> getGroupElement(OpcodeStack.Item itm) {
Comparable<?> groupElement = null;
-
+
int reg = itm.getRegisterNumber();
if (reg >= 0)
groupElement = Integer.valueOf(reg);
@@ -338,10 +353,10 @@
groupElement = field.getName() + ":{" + regLoad + "}";
}
}
-
+
return groupElement;
}
-
+
private int findCollectionGroup(OpcodeStack.Item itm, boolean addIfNotFound) {
Integer id = (Integer)itm.getUserValue();
@@ -357,7 +372,7 @@
return i;
}
}
-
+
if (addIfNotFound) {
Set<Comparable<?>> group = new HashSet<Comparable<?>>();
group.add(groupElement);
@@ -365,10 +380,10 @@
return collectionGroups.size() - 1;
}
}
-
+
return -1;
}
-
+
private void removeFromCollectionGroup(OpcodeStack.Item itm) {
Comparable<?> groupElement = getGroupElement(itm);
if (groupElement != null) {
@@ -380,10 +395,10 @@
}
}
}
-
+
private void buildVariableEndScopeMap() {
endOfScopes = new HashMap<Integer, Set<Integer>>();
-
+
LocalVariableTable lvt = getMethod().getLocalVariableTable();
if (lvt != null) {
int len = lvt.getLength();
@@ -402,7 +417,7 @@
}
}
}
-
+
private void processEndOfScopes(Integer pc) {
Set<Integer> endVars = endOfScopes.get(pc);
if (endVars != null) {
@@ -417,12 +432,12 @@
}
}
}
-
+
static class Loop
{
public int loopStart;
public int loopFinish;
-
+
public Loop(int start, int finish) {
loopStart = start;
loopFinish = finish;
@@ -435,11 +450,11 @@
public int getLoopStart() {
return loopStart;
}
-
+
public boolean hasPC(int pc) {
return (loopStart <= pc) && (pc <= loopFinish);
}
-
+
@Override
public String toString() {
return "Start=" + loopStart + " Finish=" + loopFinish;
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2012 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
@@ -66,18 +66,18 @@
* constructs a FCBL detector given the reporter to report bugs on.
* @param bugReporter the sync of bug reports
- */
+ */
public FieldCouldBeLocal(BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
-
+
/**
* overrides the visitor to collect localizable fields, and then report those that
* survive all method checks.
- *
+ *
* @param classContext the context object that holds the JavaClass parsed
*/
- @Override
+ @Override
public void visitClassContext(ClassContext classContext) {
try {
localizableFields = new HashMap<String, FieldInfo>();
@@ -91,7 +91,7 @@
localizableFields.put(f.getName(), new FieldInfo(fa));
}
}
-
+
if (localizableFields.size() > 0) {
super.visitClassContext(classContext);
for (FieldInfo fi : localizableFields.values()) {
@@ -111,26 +111,23 @@
clsContext = null;
}
}
-
+
/**
* overrides the visitor to navigate basic blocks looking for all first usages of fields, removing
* those that are read from first.
- *
+ *
* @param obj the context object of the currently parsed method
*/
@Override
public void visitMethod(Method obj) {
if (localizableFields.isEmpty())
return;
-
- String methodName = obj.getName();
- if ("<clinit>".equals(methodName) || "<init>".equals(methodName))
- return;
+
try {
cpg = new ConstantPoolGen(getConstantPool());
cfg = clsContext.getCFG(obj);
BasicBlock bb = cfg.getEntry();
- Set<String> uncheckedFields = new HashSet<String>(localizableFields.keySet());
+ Set<String> uncheckedFields = new HashSet<String>(localizableFields.keySet());
visitedBlocks.clear();
checkBlock(bb, uncheckedFields);
}
@@ -142,10 +139,10 @@
cpg = null;
}
}
-
+
/**
* looks for methods that contain a GETFIELD or PUTFIELD opcodes
- *
+ *
* @param method the context object of the current method
* @return if the class uses synchronization
*/
@@ -153,12 +150,12 @@
BitSet bytecodeSet = getClassContext().getBytecodeSet(method);
return (bytecodeSet != null) && (bytecodeSet.get(Constants.PUTFIELD) || bytecodeSet.get(Constants.GETFIELD));
}
-
+
/**
* implements the visitor to pass through constructors and static initializers to the
- * byte code scanning code. These methods are not reported, but are used to build
+ * byte code scanning code. These methods are not reported, but are used to build
* SourceLineAnnotations for fields, if accessed.
- *
+ *
* @param obj the context object of the currently parsed code attribute
*/
@Override
@@ -170,11 +167,11 @@
super.visitCode(obj);
}
}
-
+
/**
* implements the visitor to add SourceLineAnnotations for fields in constructors and static
* initializers.
- *
+ *
* @param seen the opcode of the currently visited instruction
*/
@Override
@@ -188,13 +185,13 @@
}
}
}
-
+
/**
* looks in this basic block for the first access to the fields in uncheckedFields. Once found
- * the item is removed from uncheckedFields, and removed from localizableFields if the access is
+ * the item is removed from uncheckedFields, and removed from localizableFields if the access is
* a GETFIELD. If any unchecked fields remain, this method is recursively called on all outgoing edges
* of this basic block.
- *
+ *
* @param bb this basic block
* @param uncheckedFields the list of fields to look for
*/
@@ -208,7 +205,7 @@
return;
BlockState bState = toBeProcessed.removeFirst();
bb = bState.getBasicBlock();
-
+
InstructionIterator ii = bb.instructionIterator();
while ((bState.getUncheckedFieldSize() > 0) && ii.hasNext()) {
InstructionHandle ih = ii.next();
@@ -217,7 +214,7 @@
FieldInstruction fi = (FieldInstruction) ins;
String fieldName = fi.getFieldName(cpg);
boolean justRemoved = bState.removeUncheckedField(fieldName);
-
+
if (ins instanceof GETFIELD) {
if (justRemoved) {
localizableFields.remove(fieldName);
@@ -229,9 +226,9 @@
if (finfo != null)
finfo.setSrcLineAnnotation(SourceLineAnnotation.fromVisitedInstruction(clsContext, this, ih.getPosition()));
}
- }
+ }
}
-
+
if (bState.getUncheckedFieldSize() > 0) {
Iterator<Edge> oei = cfg.outgoingEdgeIterator(bb);
while (oei.hasNext()) {
@@ -246,14 +243,14 @@
}
}
}
-
+
/**
* holds information about a field and it's first usage
*/
private static class FieldInfo {
private final FieldAnnotation fieldAnnotation;
private SourceLineAnnotation srcLineAnnotation;
-
+
/**
* creates a FieldInfo from an annotation, and assumes no source line information
* @param fa the field annotation for this field
@@ -262,7 +259,7 @@
fieldAnnotation = fa;
srcLineAnnotation = null;
}
-
+
/**
* set the source line annotation of first use for this field
* @param sla the source line annotation
@@ -271,7 +268,7 @@
if (srcLineAnnotation == null)
srcLineAnnotation = sla;
}
-
+
/**
* get the field annotation for this field
* @return the field annotation
@@ -279,7 +276,7 @@
public FieldAnnotation getFieldAnnotation() {
return fieldAnnotation;
}
-
+
/**
* get the source line annotation for the first use of this field
* @return the source line annotation
@@ -288,10 +285,10 @@
return srcLineAnnotation;
}
}
-
+
/**
* holds the parse state of the current basic block, and what fields are left to be checked
- * the fields that are left to be checked are a reference from the parent block
+ * the fields that are left to be checked are a reference from the parent block
* and a new collection is created on first write to the set to reduce memory concerns.
*/
private static class BlockState {
@@ -300,7 +297,7 @@
private boolean fieldsAreSharedWithParent;
/**
- * creates a BlockState consisting of the next basic block to parse,
+ * creates a BlockState consisting of the next basic block to parse,
* and what fields are to be checked
* @param bb the basic block to parse
* @param fields the fields to look for first use
@@ -310,9 +307,9 @@
uncheckedFields = fields;
fieldsAreSharedWithParent = true;
}
-
+
/**
- * creates a BlockState consisting of the next basic block to parse,
+ * creates a BlockState consisting of the next basic block to parse,
* and what fields are to be checked
* @param bb the basic block to parse
* @param the basic block to copy from
@@ -322,7 +319,7 @@
uncheckedFields = parentBlockState.uncheckedFields;
fieldsAreSharedWithParent = true;
}
-
+
/**
* get the basic block to parse
* @return the basic block
@@ -330,7 +327,7 @@
public BasicBlock getBasicBlock() {
return basicBlock;
}
-
+
/**
* returns the number of unchecked fields
* @return the number of unchecked fields
@@ -338,7 +335,7 @@
public int getUncheckedFieldSize() {
return (uncheckedFields == null) ? 0 : uncheckedFields.size();
}
-
+
/**
* return the field from the set of unchecked fields
* if this occurs make a copy of the set on write to reduce memory usage
@@ -351,7 +348,7 @@
fieldsAreSharedWithParent = false;
return true;
}
-
+
if (fieldsAreSharedWithParent) {
uncheckedFields = new HashSet<String>(uncheckedFields);
fieldsAreSharedWithParent = false;
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossibleConstantAllocationInLoop.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossibleConstantAllocationInLoop.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossibleConstantAllocationInLoop.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2012 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
@@ -34,7 +34,7 @@
import edu.umd.cs.findbugs.ba.ClassContext;
public class PossibleConstantAllocationInLoop extends BytecodeScanningDetector {
-
+
private final BugReporter bugReporter;
private OpcodeStack stack;
/** allocation number, info where allocated */
@@ -42,11 +42,11 @@
/** reg, allocation number */
private Map<Integer, Integer> storedAllocations;
private int nextAllocationNumber;
-
+
public PossibleConstantAllocationInLoop(BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
-
+
@Override
public void visitClassContext(ClassContext classContext) {
try {
@@ -60,7 +60,7 @@
storedAllocations = null;
}
}
-
+
@Override
public void visitCode(Code obj) {
stack.resetForMethodEntry(this);
@@ -68,7 +68,7 @@
storedAllocations.clear();
nextAllocationNumber = 1;
super.visitCode(obj);
-
+
for (AllocationInfo info : allocations.values()) {
if (info.loopBottom != -1) {
bugReporter.reportBug(new BugInstance(this, "PCAIL_POSSIBLE_CONSTANT_ALLOCATION_IN_LOOP", NORMAL_PRIORITY)
@@ -78,12 +78,12 @@
}
}
}
-
+
@Override
public void sawOpcode(int seen) {
boolean sawAllocation = false;
Integer sawAllocationNumber = null;
-
+
try {
switch (seen) {
case IFEQ:
@@ -115,7 +115,7 @@
}
}
break;
-
+
case INVOKESPECIAL:
if ("<init>".equals(getNameConstantOperand()) && "()V".equals(getSigConstantOperand())) {
String clsName = getClassConstantOperand();
@@ -126,11 +126,12 @@
}
}
//$FALL-THROUGH$
-
+
case INVOKEINTERFACE:
case INVOKEVIRTUAL:
case INVOKESTATIC:
- Type[] types = Type.getArgumentTypes(getSigConstantOperand());
+ String signature = getSigConstantOperand();
+ Type[] types = Type.getArgumentTypes(signature);
if (stack.getStackDepth() >= types.length) {
for (int i = 0; i < types.length; i++) {
OpcodeStack.Item item = stack.getStackItem(i);
@@ -139,9 +140,21 @@
allocations.remove(allocation);
}
}
+ if ((seen == INVOKEINTERFACE) || (seen == INVOKEVIRTUAL) || ((seen == INVOKESPECIAL))) {
+ //ignore possible method chaining
+ OpcodeStack.Item item = stack.getStackItem(types.length);
+ Integer allocation = (Integer)item.getUserValue();
+ if (allocation != null) {
+ String retType = Type.getReturnType(signature).getSignature();
+ if (!"V".equals(retType) && retType.equals(item.getSignature())) {
+ sawAllocationNumber = allocation;
+ sawAllocation = true;
+ }
+ }
+ }
}
break;
-
+
case ASTORE:
case ASTORE_0:
case ASTORE_1:
@@ -151,9 +164,9 @@
OpcodeStack.Item item = stack.getStackItem(0);
Integer allocation = (Integer)item.getUserValue();
if (allocation != null) {
- Integer reg = Integer.valueOf(RegisterUtils.getAStoreReg(this, seen));
+ Integer reg = Integer.valueOf(RegisterUtils.getAStoreReg(this, seen));
if (storedAllocations.values().contains(allocation)) {
- allocations.remove(allocation);
+ allocations.remove(allocation);
storedAllocations.remove(reg);
} else if (storedAllocations.containsKey(reg)) {
allocations.remove(allocation);
@@ -165,7 +178,7 @@
}
}
break;
-
+
case AASTORE:
if (stack.getStackDepth() >= 2) {
OpcodeStack.Item item = stack.getStackItem(0);
@@ -175,7 +188,7 @@
}
}
break;
-
+
case ALOAD:
case ALOAD_0:
case ALOAD_1:
@@ -195,7 +208,7 @@
}
}
break;
-
+
case PUTFIELD:
if (stack.getStackDepth() > 1) {
OpcodeStack.Item item = stack.getStackItem(0);
@@ -203,7 +216,7 @@
allocations.remove(allocation);
}
break;
-
+
case ARETURN:
case ATHROW:
if (stack.getStackDepth() > 0) {
@@ -212,7 +225,7 @@
if (allocation != null) {
allocations.remove(allocation);
}
- }
+ }
break;
}
} finally {
@@ -224,19 +237,19 @@
OpcodeStack.Item item = stack.getStackItem(0);
item.setUserValue(sawAllocationNumber);
}
-
+
if (seen == INVOKESPECIAL)
nextAllocationNumber++;
}
}
}
-
+
static class AllocationInfo {
-
+
int allocationPC;
int loopTop;
int loopBottom;
-
+
public AllocationInfo(int pc) {
allocationPC = pc;
loopTop = -1;
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -199,8 +199,6 @@
} else if (seen == PUTFIELD) {
fieldMethodCalls.remove(getNameConstantOperand());
} else if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE) || (seen == INVOKESTATIC)) {
- String className = getClassConstantOperand();
- String methodName = getNameConstantOperand();
String signature = getSigConstantOperand();
int parmCount = Type.getArgumentTypes(signature).length;
int neededStackSize = parmCount - ((seen == INVOKESTATIC) ? 1 : 0);
@@ -214,6 +212,7 @@
}
}
+ String className = getClassConstantOperand();
MethodCall mc;
int reg = -1;
@@ -236,6 +235,7 @@
}
}
+ String methodName = getNameConstantOperand();
if (mc != null) {
if (!signature.endsWith("V") && methodName.equals(mc.getName()) && signature.equals(mc.getSignature()) && !isRiskyName(className, methodName)) {
Object[] parms = mc.getParms();
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SpoiledChildInterfaceImplementor.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SpoiledChildInterfaceImplementor.java 2012-10-25 19:46:23 UTC (rev 1728)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SpoiledChildInterfaceImplementor.java 2012-10-31 17:32:54 UTC (rev 1729)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2012 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
@@ -31,31 +31,31 @@
import edu.umd.cs.findbugs.ba.ClassContext;
/**
- * looks for classes that implement interfaces by relying on methods being
+ * looks for classes that implement interfaces by relying on methods being
* implemented in super classes, even though the superclass knows nothing about
* the interface being implemented by the child.
*/
public class SpoiledChildInterfaceImplementor implements Detector {
private final BugReporter bugReporter;
-
+
/**
* constructs a SCII detector given the reporter to report bugs on
* @param bugReporter the sync of bug reports
- */
+ */
public SpoiledChildInterfaceImplementor(BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
-
+
/** looks for classes that implement interfaces but don't provide those methods
- *
+ *
* @param classContext the context object of the currently parsed class
*/
public void visitClassC...
[truncated message content] |