Thread: [Fb-contrib-commit] SF.net SVN: fb-contrib: [427] trunk/fb-contrib
Brought to you by:
dbrosius
From: <dbr...@us...> - 2006-04-09 20:15:17
|
Revision: 427 Author: dbrosius Date: 2006-04-09 13:15:07 -0700 (Sun, 09 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=427&view=rev Log Message: ----------- add additional samples classpath (lib dir) Modified Paths: -------------- trunk/fb-contrib/.classpath trunk/fb-contrib/build.xml Modified: trunk/fb-contrib/.classpath =================================================================== --- trunk/fb-contrib/.classpath 2006-04-09 20:11:12 UTC (rev 426) +++ trunk/fb-contrib/.classpath 2006-04-09 20:15:07 UTC (rev 427) @@ -5,5 +5,6 @@ <classpathentry kind="src" path="samples"/> <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/lib/findbugs.jar"/> <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/lib/bcel.jar"/> + <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/samples/lib/jsp-api.jar"/> <classpathentry kind="output" path="classes"/> </classpath> Modified: trunk/fb-contrib/build.xml =================================================================== --- trunk/fb-contrib/build.xml 2006-04-09 20:11:12 UTC (rev 426) +++ trunk/fb-contrib/build.xml 2006-04-09 20:15:07 UTC (rev 427) @@ -12,6 +12,7 @@ <property name="lib.dir" value="${basedir}/lib"/> <property name="etc.dir" value="${basedir}/etc"/> <property name="samples.dir" value="${basedir}/samples"/> + <property name="sampleslib.dir" value="${samples.dir}/lib"/> <property name="javadoc.dir" value="${basedir}/javadoc"/> <property name="javac.source" value="1.5"/> <property name="javac.target" value="jsr14"/> @@ -39,6 +40,9 @@ <pathelement location="${lib.dir}/findbugs.jar"/> <pathelement location="${lib.dir}/bcel.jar"/> </path> + <path id="fb-contrib.samples.classpath"> + <pathelement location="${sampleslib.dir}/jsp-api.jar"/> + </path> <mkdir dir="${classes.dir}/com"/> <mkdir dir="${classes.dir}/com/mebigfatguy"/> <mkdir dir="${classes.dir}/com/mebigfatguy/fbcontrib"/> @@ -73,6 +77,7 @@ deprecation="${javac.deprecation}" debug="${javac.debug}"> <classpath refid="fb-contrib.classpath"/> + <classpath refid="fb-contrib.samples.classpath"/> </javac> </target> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-04-17 15:43:30
|
Revision: 464 Author: dbrosius Date: 2006-04-17 08:43:17 -0700 (Mon, 17 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=464&view=rev Log Message: ----------- Manually cleanup memory now that StatelessDetector is removed. Modified Paths: -------------- trunk/fb-contrib/.classpath trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java Modified: trunk/fb-contrib/.classpath =================================================================== --- trunk/fb-contrib/.classpath 2006-04-17 15:40:42 UTC (rev 463) +++ trunk/fb-contrib/.classpath 2006-04-17 15:43:17 UTC (rev 464) @@ -3,8 +3,8 @@ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="samples"/> - <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/lib/findbugs.jar"/> - <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/lib/bcel.jar"/> - <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/samples/lib/jsp-api.jar"/> + <classpathentry kind="lib" path="C:/fb-contrib/fb-contrib/lib/findbugs.jar"/> + <classpathentry kind="lib" path="C:/fb-contrib/fb-contrib/lib/bcel.jar"/> + <classpathentry kind="lib" path="C:/fb-contrib/fb-contrib/samples/lib/jsp-api.jar"/> <classpathentry kind="output" path="classes"/> </classpath> Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java 2006-04-17 15:40:42 UTC (rev 463) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java 2006-04-17 15:43:17 UTC (rev 464) @@ -42,7 +42,6 @@ import edu.umd.cs.findbugs.BytecodeScanningDetector; import edu.umd.cs.findbugs.FieldAnnotation; import edu.umd.cs.findbugs.SourceLineAnnotation; -import edu.umd.cs.findbugs.StatelessDetector; import edu.umd.cs.findbugs.ba.BasicBlock; import edu.umd.cs.findbugs.ba.CFG; import edu.umd.cs.findbugs.ba.ClassContext; @@ -53,14 +52,14 @@ * finds fields that are used in a locals only fashion, specifically private fields * that are accessed first in each method with a store vs. a load. */ -public class FieldCouldBeLocal extends BytecodeScanningDetector implements StatelessDetector { - +public class FieldCouldBeLocal extends BytecodeScanningDetector +{ private BugReporter bugReporter; private ClassContext clsContext; - private Map<String, FieldInfo> localizableFields = new HashMap<String, FieldInfo>(); + private Map<String, FieldInfo> localizableFields; private CFG cfg; private ConstantPoolGen cpg; - private BitSet visitedBlocks = new BitSet(); + private BitSet visitedBlocks; /** * constructs a FCBL detector given the reporter to report bugs on. @@ -72,17 +71,6 @@ } /** - * clone this detector so that it can be a StatelessDetector. - * - * @return a clone of this object - * @throws CloneNotSupportedException should not happen - */ - @Override - public Object clone() throws CloneNotSupportedException { - return super.clone(); - } - - /** * overrides the visitor to collect localizable fields, and then report those that * survive all method checks. * @@ -90,7 +78,8 @@ */ @Override public void visitClassContext(ClassContext classContext) { - localizableFields.clear(); + localizableFields = new HashMap<String, FieldInfo>(); + visitedBlocks = new BitSet(); clsContext = classContext; JavaClass cls = classContext.getJavaClass(); Field[] fields = cls.getFields(); @@ -114,6 +103,9 @@ bugReporter.reportBug(bug); } } + localizableFields = null; + visitedBlocks = null; + clsContext = null; } /** @@ -140,6 +132,9 @@ catch (Exception e) { localizableFields.clear(); } + finally { + cfg = null; + } } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-04-18 02:43:31
|
Revision: 469 Author: dbrosius Date: 2006-04-17 19:43:21 -0700 (Mon, 17 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=469&view=rev Log Message: ----------- Manually cleanup memory now that StatelessDetector is removed. Modified Paths: -------------- trunk/fb-contrib/.classpath trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/JDBCVendorReliance.java Modified: trunk/fb-contrib/.classpath =================================================================== --- trunk/fb-contrib/.classpath 2006-04-17 15:52:11 UTC (rev 468) +++ trunk/fb-contrib/.classpath 2006-04-18 02:43:21 UTC (rev 469) @@ -3,8 +3,8 @@ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="samples"/> - <classpathentry kind="lib" path="C:/fb-contrib/fb-contrib/lib/findbugs.jar"/> - <classpathentry kind="lib" path="C:/fb-contrib/fb-contrib/lib/bcel.jar"/> - <classpathentry kind="lib" path="C:/fb-contrib/fb-contrib/samples/lib/jsp-api.jar"/> + <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/lib/findbugs.jar"/> + <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/lib/bcel.jar"/> + <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/samples/lib/jsp-api.jar"/> <classpathentry kind="output" path="classes"/> </classpath> Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/JDBCVendorReliance.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/JDBCVendorReliance.java 2006-04-17 15:52:11 UTC (rev 468) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/JDBCVendorReliance.java 2006-04-18 02:43:21 UTC (rev 469) @@ -31,16 +31,16 @@ import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; import edu.umd.cs.findbugs.OpcodeStack; -import edu.umd.cs.findbugs.StatelessDetector; +import edu.umd.cs.findbugs.ba.ClassContext; /** * looks for uses of jdbc vendor specific classes and methods making the database access code * non portable. */ -public class JDBCVendorReliance extends BytecodeScanningDetector implements StatelessDetector { - +public class JDBCVendorReliance extends BytecodeScanningDetector +{ private BugReporter bugReporter; - private OpcodeStack stack = new OpcodeStack(); + private OpcodeStack stack; private Map<Integer, Integer> jdbcLocals = new HashMap<Integer, Integer>(); /** @@ -51,17 +51,14 @@ this.bugReporter = bugReporter; } + public void visitClassContext(ClassContext classContext) { + stack = new OpcodeStack(); + jdbcLocals = new HashMap<Integer, Integer>(); + super.visitClassContext(classContext); + stack = null; + jdbcLocals = null; + } /** - * clone this detector so that it can be a StatelessDetector - * - * @return a clone of this object - */ - @Override - public Object clone() throws CloneNotSupportedException { - return super.clone(); - } - - /** * implement the visitor to reset the opcode stack and set of locals that are jdbc objects * * @param obj the context param of the currently parsed method This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-05-02 02:02:16
|
Revision: 513 Author: dbrosius Date: 2006-05-01 19:02:10 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=513&view=rev Log Message: ----------- Prepare for the 2.6.0 release Modified Paths: -------------- trunk/fb-contrib/build.xml trunk/fb-contrib/htdocs/index.html Modified: trunk/fb-contrib/build.xml =================================================================== --- trunk/fb-contrib/build.xml 2006-05-01 02:53:42 UTC (rev 512) +++ trunk/fb-contrib/build.xml 2006-05-02 02:02:10 UTC (rev 513) @@ -19,7 +19,7 @@ <property name="javac.deprecation" value="on"/> <property name="javac.debug" value="on"/> - <property name="fb-contrib.version" value="2.5.0"/> + <property name="fb-contrib.version" value="2.6.0"/> <target name="clean" description="removes all generated collateral"> <delete dir="${classes.dir}"/> @@ -133,7 +133,7 @@ destdir="${javadoc.dir}" windowtitle="fb-contrib api"> <doctitle><![CDATA[<h1>fb-contrib javadoc</h1>]]></doctitle> - <bottom><![CDATA[<i>Copyright © 2005 MeBigFatGuy.com. All Rights Reserved.</i>]]></bottom> + <bottom><![CDATA[<i>Copyright © 2005-2006 MeBigFatGuy.com. All Rights Reserved.</i>]]></bottom> </javadoc> </target> </project> \ No newline at end of file Modified: trunk/fb-contrib/htdocs/index.html =================================================================== --- trunk/fb-contrib/htdocs/index.html 2006-05-01 02:53:42 UTC (rev 512) +++ trunk/fb-contrib/htdocs/index.html 2006-05-02 02:02:10 UTC (rev 513) @@ -46,16 +46,23 @@ <a href="javadoc/index.html">JavaDoc</a> <hr/> - <img id="svn_image" src="flip2.gif" onClick="toggleBlock('svn', 'svn_image');" align="top"/> - Detectors added in SVN<br/> - Note: these detectors are still in testing<br/> - Also note that the svn version of fb-contrib requires FindBugs v0.9.7.<br/> - <div id="svn" style="display:block;"> + <img id="svn_image" src="flip1.gif" onClick="toggleBlock('svn', 'svn_image');" align="top"/> + Detectors added in svn + <div id="svn" style="display:none;"> <ul> <li><b>[BSB] Bloated Synchronized Block</b><br/> Looks for methods that implement synchronized blocks that appear to contain some code at the beginning that does not need to be synchronized. Moving these lines out of the synchronized block should help multithreaded performance.</li> + </ul> + </div> + + <hr/> + <img id="v2_6_0_image" src="flip2.gif" onClick="toggleBlock('v2_6_0', 'v2_6_0_image');" align="top"/> + Detectors added in v2.6.0<br/> + Note: This version of fb-contrib requires FindBugs v0.9.7.<br/> + <div id="v2_6_0" style="display:block;"> + <ul> <li><b>[FCBL] Field could be Local</b><br/> Looks for classes that declare fields that are used in a locals-only fashion, specifically private fields that are accessed first in each method with a store vs. a load. These fields can be declared as one or more This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-06-20 03:59:42
|
Revision: 570 Author: dbrosius Date: 2006-06-19 20:59:30 -0700 (Mon, 19 Jun 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=570&view=rev Log Message: ----------- Prepare for v2.8.0 Modified Paths: -------------- trunk/fb-contrib/build.xml trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/htdocs/index.html trunk/fb-contrib/samples/ISB_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java Modified: trunk/fb-contrib/build.xml =================================================================== --- trunk/fb-contrib/build.xml 2006-06-20 03:26:29 UTC (rev 569) +++ trunk/fb-contrib/build.xml 2006-06-20 03:59:30 UTC (rev 570) @@ -19,7 +19,7 @@ <property name="javac.deprecation" value="on"/> <property name="javac.debug" value="on"/> - <property name="fb-contrib.version" value="2.7.0"/> + <property name="fb-contrib.version" value="2.8.0"/> <target name="clean" description="removes all generated collateral"> <delete dir="${classes.dir}"/> Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-06-20 03:26:29 UTC (rev 569) +++ trunk/fb-contrib/etc/findbugs.xml 2006-06-20 03:59:30 UTC (rev 570) @@ -266,8 +266,8 @@ <BugPattern abbrev="S508C" type="S508C_NON_ACCESSIBLE_JCOMPONENT" category="CORRECTNESS" /> <BugPattern abbrev="S508C" type="S508C_SET_COMP_COLOR" category="CORRECTNESS" /> <BugPattern abbrev="UEC" type="UEC_USE_ENUM_COLLECTIONS" category="PERFORMANCE" /> - <BugPattern abbrev="SIL" type="SIL_SQL_IN_LOOP" category="PERFORMANCE" experimental="true" /> - <BugPattern abbrev="NMCS" type="NMCS_NEEDLESS_MEMBER_COLLECTION_SYNCHRONIZATION" category="PERFORMANCE" experimental="true" /> + <BugPattern abbrev="SIL" type="SIL_SQL_IN_LOOP" category="PERFORMANCE" /> + <BugPattern abbrev="NMCS" type="NMCS_NEEDLESS_MEMBER_COLLECTION_SYNCHRONIZATION" category="PERFORMANCE" /> <BugPattern abbrev="ITC" type="ITC_INHERITANCE_TYPE_CHECKING" category="STYLE" experimental="true" /> <BugPattern abbrev="SACM" type="SACM_STATIC_ARRAY_CREATED_IN_METHOD" category="PERFORMANCE" experimental="true" /> <BugPattern abbrev="RMC" type="RMC_REDUNDANT_METHOD_CALLS" category="PERFORMANCE" experimental="true" /> Modified: trunk/fb-contrib/htdocs/index.html =================================================================== --- trunk/fb-contrib/htdocs/index.html 2006-06-20 03:26:29 UTC (rev 569) +++ trunk/fb-contrib/htdocs/index.html 2006-06-20 03:59:30 UTC (rev 570) @@ -44,17 +44,24 @@ <a href="http://www.sourceforge.net/projects/fb-contrib">Project Page</a> <img src="vbar.gif" height="12"/> <a href="javadoc/index.html">JavaDoc</a> - - <hr/> - <img id="svn_image" src="flip2.gif" onClick="toggleBlock('svn', 'svn_image');" align="top"/> + + <hr/> + <img id="svn_image" src="flip1.gif" onClick="toggleBlock('svn', 'svn_image');" align="top"/> Detectors added in svn<br/> - Note: This version of fb-contrib requires FindBugs v1.0.0<br/> - <div id="svn" style="display:block;"> + <div id="svn" style="display:none;"> <ul> <li><b>[BSB] Bloated Synchronized Block</b><br/> Looks for methods that implement synchronized blocks that appear to contain some code at the beginning that does not need to be synchronized. Moving these lines out of the synchronized block should help multithreaded performance.</li> + </ul> + </div> + <hr/> + <img id="v2_8_0_image" src="flip2.gif" onClick="toggleBlock('v2_8_0', 'v2_8_0_image');" align="top"/> + Detectors added in v2.8.0<br/> + Note: This version of fb-contrib requires FindBugs v1.0.0<br/> + <div id="v2_8_0" style="display:block;"> + <ul> <li><b>[NMCS] Needless Member Collection Synchronization</b><br/> Looks for private collection members, either static or instance, that are only initialized in the clinit or init, but are synchronized. This is not necessary as the constructor or static @@ -72,7 +79,6 @@ cleaner to use mycollection.toArray(new type[mycollection.size()].</li> </ul> </div> - <hr/> <img id="v2_6_0_image" src="flip1.gif" onClick="toggleBlock('v2_6_0', 'v2_6_0_image');" align="top"/> Detectors added in v2.6.0<br/> Modified: trunk/fb-contrib/samples/ISB_Sample.java =================================================================== --- trunk/fb-contrib/samples/ISB_Sample.java 2006-06-20 03:26:29 UTC (rev 569) +++ trunk/fb-contrib/samples/ISB_Sample.java 2006-06-20 03:59:30 UTC (rev 570) @@ -51,6 +51,14 @@ return sb.toString(); } + public String testFPISB8(int x) + { + StringBuffer sb = new StringBuffer(); + sb.append(x); + sb.append("hello"); + return sb.toString(); + } + public String toString() { String a = System.getProperty("foo"); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java 2006-06-20 03:26:29 UTC (rev 569) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java 2006-06-20 03:59:30 UTC (rev 570) @@ -26,6 +26,7 @@ import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; import edu.umd.cs.findbugs.OpcodeStack; +import edu.umd.cs.findbugs.ba.ClassContext; /** * looks for appending strings inside of calls to StringBuffer or StringBuilder append. @@ -33,7 +34,8 @@ public class InefficientStringBuffering extends BytecodeScanningDetector { private BugReporter bugReporter; - private OpcodeStack opStack; + private OpcodeStack stack; + private boolean sawLDCEmpty; /** * constructs a ISB detector given the reporter to report bugs on @@ -43,6 +45,19 @@ this.bugReporter = bugReporter; } + /** + * implements the visitor to create an clear the stack + * + * @param classContext the context object of the currently parsed class + */ + public void visitClassContext(ClassContext classContext) { + try { + stack = new OpcodeStack(); + super.visitClassContext(classContext); + } finally { + stack = null; + } + } /** * implements the visitor to create and clear the stack * @@ -51,16 +66,16 @@ @Override public void visitCode(final Code obj) { if (obj.getCode() != null) { - opStack = new OpcodeStack(); + stack.resetForMethodEntry(this); + sawLDCEmpty = false; super.visit(obj); - opStack = null; } } @Override public void sawOpcode(final int seen) { try { - opStack.mergeJumps(this); + stack.mergeJumps(this); if (seen == INVOKESPECIAL) { String calledClass = getClassConstantOperand(); @@ -78,40 +93,49 @@ } } } else if (seen == INVOKEVIRTUAL) { - String calledClass = getClassConstantOperand(); - if (("java/lang/StringBuffer".equals(calledClass) - || "java/lang/StringBuilder".equals(calledClass)) - && "append".equals(getNameConstantOperand()) - && getSigConstantOperand().startsWith("(Ljava/lang/String;)")) { - if (opStack.getStackDepth() > 0) { - OpcodeStack.Item itm = opStack.getStackItem(0); - Object cons = itm.getConstant(); - if ((cons instanceof String) && (itm.getRegisterNumber() < 0)) { - if (((String)cons).length() == 0) { - bugReporter.reportBug( - new BugInstance(this, "ISB_EMPTY_STRING_APPENDING", NORMAL_PRIORITY) - .addClass(this) - .addMethod(this) - .addSourceLine(this)); + if (sawLDCEmpty) { + String calledClass = getClassConstantOperand(); + if (("java/lang/StringBuffer".equals(calledClass) + || "java/lang/StringBuilder".equals(calledClass)) + && "append".equals(getNameConstantOperand()) + && getSigConstantOperand().startsWith("(Ljava/lang/String;)")) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + Object cons = itm.getConstant(); + if ((cons instanceof String) && (itm.getRegisterNumber() < 0)) { + if (((String)cons).length() == 0) { + bugReporter.reportBug( + new BugInstance(this, "ISB_EMPTY_STRING_APPENDING", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } } } } } } else if (seen == GOTO) { - int depth = opStack.getStackDepth(); + int depth = stack.getStackDepth(); for (int i = 0; i < depth; i++) { - OpcodeStack.Item itm = opStack.getStackItem(i); + OpcodeStack.Item itm = stack.getStackItem(i); itm.setUserValue(Boolean.TRUE); } + } else if (seen == LDC) { + Constant c = getConstantRefOperand(); + if (c instanceof ConstantString) { + String s = ((ConstantString) c).getBytes(getConstantPool()); + if (s.length() == 0) + sawLDCEmpty = true; + } } } finally { - opStack.sawOpcode(this, seen); + stack.sawOpcode(this, seen); } } private OpcodeStack.Item getStringBufferItemAt(int depth) { - if (opStack.getStackDepth() > depth) { - OpcodeStack.Item itm = opStack.getStackItem(depth); + if (stack.getStackDepth() > depth) { + OpcodeStack.Item itm = stack.getStackItem(depth); String signature = itm.getSignature(); if ("Ljava/lang/StringBuffer;".equals(signature) || "Ljava/lang/StringBuilder;".equals(signature)) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java 2006-06-20 03:26:29 UTC (rev 569) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java 2006-06-20 03:59:30 UTC (rev 570) @@ -26,7 +26,6 @@ import org.apache.bcel.classfile.JavaClass; import com.mebigfatguy.fbcontrib.utils.Integer14; -import com.mebigfatguy.fbcontrib.utils.MapEntry; import com.mebigfatguy.fbcontrib.utils.RegisterUtils; import edu.umd.cs.findbugs.BugInstance; @@ -60,6 +59,11 @@ this.bugReporter = bugReporter; } + /** + * implements the visitor to create and clear the stack, and report missing class errors + * + * @param classContext the context object of the currently parsed class + */ public void visitClassContext(ClassContext classContext) { if (collectionClass == null) { if (ex != null) { @@ -77,6 +81,11 @@ } } + /** + * implements the visitor to reset the stack and uservalues + * + * @param obj the context object of the currently parsed code block + */ @Override public void visitCode(Code obj) { try { @@ -88,6 +97,11 @@ } } + /** + * implements the visitor to look for manually copying of collections to arrays + * + * @param seen the opcode of the currently parsed instruction + */ @Override public void sawOpcode(int seen) { int reg = -1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-09-04 04:08:24
|
Revision: 627 http://svn.sourceforge.net/fb-contrib/?rev=627&view=rev Author: dbrosius Date: 2006-09-03 21:08:09 -0700 (Sun, 03 Sep 2006) Log Message: ----------- initial checkin, new URV detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/URV_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedReturnValues.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-09-04 03:08:46 UTC (rev 626) +++ trunk/fb-contrib/etc/findbugs.xml 2006-09-04 04:08:09 UTC (rev 627) @@ -242,6 +242,10 @@ speed="fast" reports="TR_TAIL_RECURSION" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.UnrelatedReturnValues" + speed="fast" + reports="URV_UNRELATED_RETURN_VALUES,URV_CHANGE_RETURN_TYPE" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -302,4 +306,7 @@ <BugPattern abbrev="LEST" type="LEST_LOST_EXCEPTION_STACK_TRACE" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="UCPM" type="UCPM_USE_CHARACTER_PARAMETERIZED_METHOD" category="PERFORMANCE" experimental="true" /> <BugPattern abbrev="TR" type="TR_TAIL_RECURSION" category="PERFORMANCE" experimental="true" /> + <BugPattern abbrev="URV" type="URV_UNRELATED_RETURN_VALUES" category="STYLE" experimental="true" /> + <BugPattern abbrev="URV" type="URV_CHANGE_RETURN_TYPE" category="STYLE" experimental="true" /> + </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-09-04 03:08:46 UTC (rev 626) +++ trunk/fb-contrib/etc/messages.xml 2006-09-04 04:08:09 UTC (rev 627) @@ -652,7 +652,18 @@ ]]> </Details> </Detector> - + + <Detector class="com.mebigfatguy.fbcontrib.detect.UnrelatedReturnValues"> + <Details> + <![CDATA[ + <p>looks for methods that are defined to return Object, and return different types of + objects based on different code paths. If this method is not based on a interface or + superclass, it is suggested to change the return type to a type that would accomodate + all kinds of return types.</p> + <p>It is a fast detector.</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1405,11 +1416,35 @@ <![CDATA[ <p>This method recursively calls itself as the last statement of the method (Tail Recursion). This method can be easily refactored into a simple loop, which - will make it more performant, and reduce the stack size requirements. + will make it more performant, and reduce the stack size requirements.</p> ]]> </Details> </BugPattern> + <BugPattern type="URV_UNRELATED_RETURN_VALUES"> + <ShortDescription>Derived method returns different types of unrelated Objects</ShortDescription> + <LongDescription>Derived method {1} returns different types of unrelated Objects</LongDescription> + <Details> + <![CDATA[ + <p>This method, which is derived from a superclass, or interface, returns two or + more unrelated types of objects. This will be very confusing to the code that must + call it.</p> + ]]> + </Details> + </BugPattern> + + <BugPattern type="URV_CHANGE_RETURN_TYPE"> + <ShortDescription>Method returns different types of unrelated Objects</ShortDescription> + <LongDescription>Method {1} returns different types of unrelated Objects</LongDescription> + <Details> + <![CDATA[ + <p>This method is defined to return a java.lang.Object. However, the return types + returned from this method can be defined by a more specific class or interface. Since this + method is not derived from a superclass or interface, it would be more clear to + change the return type of this method.</p> + ]]> + </Details> + </BugPattern> <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1465,4 +1500,5 @@ <BugCode abbrev="LEST">Lost Exception Stack Trace</BugCode> <BugCode abbrev="UCPM">Use Character Parameterized Method</BugCode> <BugCode abbrev="TR">Tail Recursion</BugCode> + <BugCode abbrev="URV">Unrelated Return Values</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/URV_Sample.java =================================================================== --- trunk/fb-contrib/samples/URV_Sample.java (rev 0) +++ trunk/fb-contrib/samples/URV_Sample.java 2006-09-04 04:08:09 UTC (rev 627) @@ -0,0 +1,37 @@ +import java.util.HashSet; +import java.util.TreeSet; + +public class URV_Sample extends URV_Super +{ + public Object getASet(boolean b) + { + if (b) + return new HashSet(); + else + return new TreeSet(); + } + + public Object getInfo(boolean b) + { + if (b) + return new String[4]; + else + return ""; + } + + public Object getInheritedInfo(boolean b) + { + if (b) + return new Integer(1); + else + return new Float(1.0); + } +} + +class URV_Super +{ + public Object getInheritedInfo(boolean b) + { + return null; + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedReturnValues.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedReturnValues.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedReturnValues.java 2006-09-04 04:08:09 UTC (rev 627) @@ -0,0 +1,171 @@ +/* + * fb-contrib - Auxilliary detectors for Java programs + * Copyright (C) 2005-2006 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 + */ +package com.mebigfatguy.fbcontrib.detect; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.classfile.Method; + +import com.mebigfatguy.fbcontrib.utils.Integer14; +import com.mebigfatguy.fbcontrib.utils.SignatureUtils; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.OpcodeStack; +import edu.umd.cs.findbugs.ba.ClassContext; + +/** + * looks for methods that return Object, and who's code body returns two or more + * different types of objects that are unrelated (other than by Object). + */ +public class UnrelatedReturnValues extends BytecodeScanningDetector +{ + private BugReporter bugReporter; + private OpcodeStack stack; + private JavaClass currentClass; + private Map<JavaClass, Integer> returnTypes; + private boolean isInherited; + + /** + * constructs a URV detector given the reporter to report bugs on + * @param bugReporter the sync of bug reports + */ + public UnrelatedReturnValues(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + public void visitClassContext(ClassContext classContext) { + try { + currentClass = classContext.getJavaClass(); + stack = new OpcodeStack(); + returnTypes = new HashMap<JavaClass, Integer>(); + super.visitClassContext(classContext); + } + finally { + currentClass = null; + stack = null; + returnTypes = null; + } + } + /** + * implements the visitor to see if the method returns Object, and if the method + * is defined in a superclass, or interface. + * + * @param obj the context object of the currently parsed code block + */ + @Override + public void visitCode(Code obj) { + try { + Method m = getMethod(); + String methodName = m.getName(); + String signature = m.getSignature(); + if (signature.endsWith(")Ljava/lang/Object;")) { + isInherited = SignatureUtils.isInheritedMethod(currentClass, methodName, signature); + stack.resetForMethodEntry(this); + returnTypes.clear(); + super.visitCode(obj); + if (returnTypes.size() > 1) { + JavaClass cls = findCommonType(returnTypes.keySet()); + BugInstance bug = null; + if ((cls == null) || isInherited) { + bug = new BugInstance(this, "URV_UNRELATED_RETURN_VALUES", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this); + } else if (!isInherited) { + bug = new BugInstance(this, "URV_CHANGE_RETURN_TYPE", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this); + bug.addString(cls.getClassName()); + } + if (bug != null) { + for (Integer pc : returnTypes.values()) { + bug.addSourceLine(this, pc.intValue()); + } + bugReporter.reportBug(bug); + } + } + } + } catch (ClassNotFoundException cnfe) { + bugReporter.reportMissingClass(cnfe); + } + } + + /** + * implements the visitor to find return values where the types of objects returned from the + * method are related only by object. + */ + public void sawOpcode(int seen) { + try { + stack.mergeJumps(this); + if (seen == ARETURN) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + returnTypes.put(itm.getJavaClass(), Integer14.valueOf(getPC())); + } + } + } catch (ClassNotFoundException cnfe) { + bugReporter.reportMissingClass(cnfe); + } finally { + stack.sawOpcode(this, seen); + } + } + + /** + * looks for a common superclass or interface for all the passed in types + * + * @param types the set of classes to look for a common super class or interface + * @return the type that is the common interface or superclass (not Object, tho). + */ + public JavaClass findCommonType(Set<JavaClass> classes) throws ClassNotFoundException { + Set<JavaClass> possibleCommonTypes = new HashSet<JavaClass>(); + classes.remove("java/lang/Object"); + boolean populate = true; + for (JavaClass cls : classes) { + JavaClass[] infs = cls.getAllInterfaces(); + JavaClass[] supers = cls.getSuperClasses(); + if (populate) { + possibleCommonTypes.addAll(Arrays.asList(infs)); + possibleCommonTypes.addAll(Arrays.asList(supers)); + possibleCommonTypes.remove("java/lang/Object"); + populate = false; + } else { + Set<JavaClass> retain = new HashSet<JavaClass>(); + retain.addAll(Arrays.asList(infs)); + retain.addAll(Arrays.asList(supers)); + possibleCommonTypes.retainAll(retain); + } + } + + if (possibleCommonTypes.size() == 0) + return null; + + for (JavaClass cls : possibleCommonTypes) { + if (cls.isInterface()) + return cls; + } + return possibleCommonTypes.iterator().next(); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-09-04 04:54:27
|
Revision: 629 http://svn.sourceforge.net/fb-contrib/?rev=629&view=rev Author: dbrosius Date: 2006-09-03 21:54:14 -0700 (Sun, 03 Sep 2006) Log Message: ----------- add another URV bug pattern to be more clear Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedReturnValues.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/SignatureUtils.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-09-04 04:29:23 UTC (rev 628) +++ trunk/fb-contrib/etc/findbugs.xml 2006-09-04 04:54:14 UTC (rev 629) @@ -244,7 +244,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.UnrelatedReturnValues" speed="fast" - reports="URV_UNRELATED_RETURN_VALUES,URV_CHANGE_RETURN_TYPE" /> + reports="URV_UNRELATED_RETURN_VALUES,URV_CHANGE_RETURN_TYPE,URV_INHERITED_METHOD_WITH_RELATED_TYPES" /> <!-- BugPattern --> @@ -308,5 +308,5 @@ <BugPattern abbrev="TR" type="TR_TAIL_RECURSION" category="PERFORMANCE" experimental="true" /> <BugPattern abbrev="URV" type="URV_UNRELATED_RETURN_VALUES" category="STYLE" experimental="true" /> <BugPattern abbrev="URV" type="URV_CHANGE_RETURN_TYPE" category="STYLE" experimental="true" /> - + <BugPattern abbrev="URV" type="URV_INHERITED_METHOD_WITH_RELATED_TYPES" category="STYLE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-09-04 04:29:23 UTC (rev 628) +++ trunk/fb-contrib/etc/messages.xml 2006-09-04 04:54:14 UTC (rev 629) @@ -1422,20 +1422,19 @@ </BugPattern> <BugPattern type="URV_UNRELATED_RETURN_VALUES"> - <ShortDescription>Derived method returns different types of unrelated Objects</ShortDescription> - <LongDescription>Derived method {1} returns different types of unrelated Objects</LongDescription> + <ShortDescription>Method returns different types of unrelated Objects</ShortDescription> + <LongDescription>Method {1} returns different types of unrelated Objects</LongDescription> <Details> <![CDATA[ - <p>This method, which is derived from a superclass, or interface, returns two or - more unrelated types of objects. This will be very confusing to the code that must - call it.</p> + <p>This method returns two or more unrelated types of objects (Related only through java.lang.Object). + This will be very confusing to the code that must call it.</p> ]]> </Details> </BugPattern> <BugPattern type="URV_CHANGE_RETURN_TYPE"> - <ShortDescription>Method returns different types of unrelated Objects</ShortDescription> - <LongDescription>Method {1} returns different types of unrelated Objects</LongDescription> + <ShortDescription>Method returns more specific type of object than declared</ShortDescription> + <LongDescription>Method {1} returns more specific type of object than declared</LongDescription> <Details> <![CDATA[ <p>This method is defined to return a java.lang.Object. However, the return types @@ -1445,6 +1444,20 @@ ]]> </Details> </BugPattern> + + <BugPattern type="URV_INHERITED_METHOD_WITH_RELATED_TYPES"> + <ShortDescription>Inherited method returns more specific type of object than declared</ShortDescription> + <LongDescription>Inherited method {1} returns more specific type of object than declared</LongDescription> + <Details> + <![CDATA[ + <p>This inherited method is defined to return a java.lang.Object. However, the return types returned + from this method can be defined by a more specific class or interface. If possible consider changing the + return type in the inheritance hierarchy of this method, otherwise the caller of this method will be brittle + in handling of the return type.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedReturnValues.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedReturnValues.java 2006-09-04 04:29:23 UTC (rev 628) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedReturnValues.java 2006-09-04 04:54:14 UTC (rev 629) @@ -95,10 +95,14 @@ .addClass(this) .addMethod(this); bug.addString(cls.getClassName()); - } else { + } else if (!isInherited) { bug = new BugInstance(this, "URV_UNRELATED_RETURN_VALUES", NORMAL_PRIORITY) .addClass(this) .addMethod(this); + } else { + bug = new BugInstance(this, "URV_INHERITED_METHOD_WITH_RELATED_TYPES", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this); } if (bug != null) { for (Integer pc : returnTypes.values()) { Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/SignatureUtils.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/SignatureUtils.java 2006-09-04 04:29:23 UTC (rev 628) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/SignatureUtils.java 2006-09-04 04:54:14 UTC (rev 629) @@ -31,7 +31,7 @@ JavaClass[] supers = cls.getSuperClasses(); for (int i = 0; i < supers.length; i++) { - if (supers[i].getClassName().equals("java/lang/Object")) { + if (supers[i].getClassName().equals("java.lang.Object")) { supers[i] = null; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-09-10 00:41:38
|
Revision: 638 http://svn.sourceforge.net/fb-contrib/?rev=638&view=rev Author: dbrosius Date: 2006-09-09 17:41:26 -0700 (Sat, 09 Sep 2006) Log Message: ----------- initial checkin - PIS detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/PIS_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossibleIncompleteSerialization.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-09-08 23:18:40 UTC (rev 637) +++ trunk/fb-contrib/etc/findbugs.xml 2006-09-10 00:41:26 UTC (rev 638) @@ -246,6 +246,9 @@ speed="fast" reports="URV_UNRELATED_RETURN_VALUES,URV_CHANGE_RETURN_TYPE,URV_INHERITED_METHOD_WITH_RELATED_TYPES" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.PossibleIncompleteSerialization" + speed="fast" + reports="PIS_POSSIBLE_INCOMPLETE_SERIALIZATION" /> <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -309,4 +312,5 @@ <BugPattern abbrev="URV" type="URV_UNRELATED_RETURN_VALUES" category="STYLE" experimental="true" /> <BugPattern abbrev="URV" type="URV_CHANGE_RETURN_TYPE" category="STYLE" experimental="true" /> <BugPattern abbrev="URV" type="URV_INHERITED_METHOD_WITH_RELATED_TYPES" category="STYLE" experimental="true" /> + <BugPattern abbrev="PIS" type="PIS_POSSIBLE_INCOMPLETE_SERIALIZATION" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-09-08 23:18:40 UTC (rev 637) +++ trunk/fb-contrib/etc/messages.xml 2006-09-10 00:41:26 UTC (rev 638) @@ -664,6 +664,17 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.PossibleIncompleteSerialization"> + <Details> + <![CDATA[ + <p>looks for classes that don't handle serialization of parent class member fields + when the class in question is serializable but is derived from a non serializable + classes.</p> + <p>It is a fast detector.</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1458,6 +1469,21 @@ </Details> </BugPattern> + <BugPattern type="PIS_POSSIBLE_INCOMPLETE_SERIALIZATION"> + <ShortDescription>Class doesn't serialize superclass fields</ShortDescription> + <LongDescription>Class {0} doesn't serialize superclass fields</LongDescription> + <Details> + <![CDATA[ + <p>This method implements Serializable but is derived from a + class that does not. The super class has fields that are not serialized + because this class does not take the responsibility of writing these fields out + either using Serializable's writeObject method, or Externalizable's writeExternal + method. Therefore when this class is read from a stream, the superclass fields + will only be initialized to the values specified in it's default constructor.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1514,4 +1540,5 @@ <BugCode abbrev="UCPM">Use Character Parameterized Method</BugCode> <BugCode abbrev="TR">Tail Recursion</BugCode> <BugCode abbrev="URV">Unrelated Return Values</BugCode> + <BugCode abbrev="PIS">Possible Incomplete Serialization</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/PIS_Sample.java =================================================================== --- trunk/fb-contrib/samples/PIS_Sample.java (rev 0) +++ trunk/fb-contrib/samples/PIS_Sample.java 2006-09-10 00:41:26 UTC (rev 638) @@ -0,0 +1,60 @@ +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +public class PIS_Sample +{ + public static void main(String[] args) + { + try + { + B b = new B(); + b.a = 100; + b.b = 100; + D d = new D(); + d.a = 100; + d.b = 100; + d.c = 100; + d.d = 100; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(b); + oos.writeObject(d); + oos.flush(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bais); + B b2 = (B)ois.readObject(); + D d2 = (D)ois.readObject(); + if ((b.a == b2.a) && (b.b == b2.b)) + System.out.println("Equal!"); + if ((d.a == d2.a) && (d.b == d2.b) && (d.c == d2.c) && (d.d == d2.d)) + System.out.println("Equal!"); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + public static class A + { + public int a = 0; + } + + public static class B extends A implements Serializable + { + public int b = 1; + } + + public static class C extends B + { + public int c = 2; + } + + public static class D extends C + { + public int d = 3; + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossibleIncompleteSerialization.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossibleIncompleteSerialization.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossibleIncompleteSerialization.java 2006-09-10 00:41:26 UTC (rev 638) @@ -0,0 +1,131 @@ +/* + * fb-contrib - Auxilliary detectors for Java programs + * Copyright (C) 2005-2006 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 + */ +package com.mebigfatguy.fbcontrib.detect; + +import org.apache.bcel.classfile.Field; +import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.classfile.Method; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.Detector; +import edu.umd.cs.findbugs.ba.ClassContext; + +/** + * looks for classes that don't handle serialization of parent class member fields + * when the class in question is serializable but is derived from non serializable classes. + */ +public class PossibleIncompleteSerialization implements Detector +{ + private BugReporter bugReporter; + + /** + * constructs a PIS detector given the reporter to report bugs on + * @param bugReporter the sync of bug reports + */ + public PossibleIncompleteSerialization(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + /** + * implements the visitor to look for classes that are serializable, and are derived + * from non serializable classes and don't either implement methods in Externalizable + * or Serializable to save parent class fields. + * + * @param classContext the context object of the currently parsed class + */ + public void visitClassContext(ClassContext classContext) { + try { + JavaClass cls = classContext.getJavaClass(); + if (isSerializable(cls)) { + JavaClass superCls = cls.getSuperClass(); + if (!isSerializable(superCls)) { + if (hasSerializableFields(superCls)) { + if (!hasSerializingMethods(cls)) { + bugReporter.reportBug(new BugInstance(this, "PIS_POSSIBLE_INCOMPLETE_SERIALIZATION", NORMAL_PRIORITY) + .addClass(cls)); + } + } + } + + } + } catch (ClassNotFoundException cnfe) { + + } finally { + + } + + } + + /** + * returns if the class implements Serializable or Externalizable + * + * @return if the class implements Serializable or Externalizable + */ + private boolean isSerializable(JavaClass cls) throws ClassNotFoundException { + JavaClass[] infs = cls.getAllInterfaces(); + for (JavaClass inf : infs) { + String clsName = inf.getClassName(); + if ("java.io.Serializable".equals(clsName) + || "java.io.Externalizable".equals(clsName)) + return true; + } + return false; + } + + /** + * looks for fields that are candidates for serialization + * + * @arg class the class to look for fields + * @return if their is a field that looks like it should be serialized + */ + private boolean hasSerializableFields(JavaClass cls) { + Field[] fields = cls.getFields(); + for (Field f : fields) { + if (!f.isStatic() && !f.isTransient() && !f.isSynthetic()) + return true; + } + return false; + } + + /** + * looks to see if this class implements method described by Serializable or Externalizable + * + * @arg cls the class to examine for serializing methods + * @return whether the class handles it's own serializing/externalizing + */ + private boolean hasSerializingMethods(JavaClass cls) { + Method[] methods = cls.getMethods(); + for (Method m : methods) { + if (!m.isStatic()) { + String methodName = m.getName(); + String methodSig = m.getSignature(); + if ("writeObject".equals(methodName) + && "(Ljava/io/ObjectOutputStream;)V".equals(methodSig)) + return true; + if ("writeExternal".equals(methodName) + && "(Ljava/io/ObjectOutput;)V".equals(methodSig)) + return true; + } + } + return false; + } + public void report() { + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-09-11 05:10:32
|
Revision: 643 http://svn.sourceforge.net/fb-contrib/?rev=643&view=rev Author: dbrosius Date: 2006-09-10 22:10:23 -0700 (Sun, 10 Sep 2006) Log Message: ----------- add stylesheet, and ant target to generate html file with bug descriptions, add to index page Modified Paths: -------------- trunk/fb-contrib/build.xml trunk/fb-contrib/htdocs/index.html Added Paths: ----------- trunk/fb-contrib/etc/bugdescriptions.xsl Modified: trunk/fb-contrib/build.xml =================================================================== --- trunk/fb-contrib/build.xml 2006-09-11 03:58:12 UTC (rev 642) +++ trunk/fb-contrib/build.xml 2006-09-11 05:10:23 UTC (rev 643) @@ -14,6 +14,7 @@ <property name="samples.dir" value="${basedir}/samples"/> <property name="sampleslib.dir" value="${samples.dir}/lib"/> <property name="javadoc.dir" value="${basedir}/javadoc"/> + <property name="htdocs.dir" value="${basedir}/htdocs"/> <property name="javac.source" value="1.5"/> <property name="javac.target" value="jsr14"/> <property name="javac.deprecation" value="on"/> @@ -24,6 +25,7 @@ <target name="clean" description="removes all generated collateral"> <delete dir="${classes.dir}"/> <delete dir="${javadoc.dir}"/> + <delete file="${htdocs.dir}/bugdescriptions.html"/> <delete file="${basedir}/fb-contrib.jar"/> <delete file="${basedir}/fb-contrib-src.zip"/> <delete> @@ -101,6 +103,13 @@ </jar> </target> + <target name="html" depends="-init" description="generates dynamic html"> + <xslt basedir="${etc.dir}" + destdir="${htdocs.dir}" + style="${etc.dir}/bugdescriptions.xsl" + in="${etc.dir}/messages.xml" out="${htdocs.dir}/bugdescriptions.html"/> + </target> + <target name="build" depends="-init, validate_xml, compile, compile_samples, jar" description="builds the plugin jar"> </target> Added: trunk/fb-contrib/etc/bugdescriptions.xsl =================================================================== --- trunk/fb-contrib/etc/bugdescriptions.xsl (rev 0) +++ trunk/fb-contrib/etc/bugdescriptions.xsl 2006-09-11 05:10:23 UTC (rev 643) @@ -0,0 +1,38 @@ +<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + + <xsl:template match="/MessageCollection"> + <html> + <head><title>fb-contrib: Bug Descriptions</title></head> + <body background="true"> + <div style="position:absolute;top:0;left:0;width:256;height:65535;z-index:1;background-image:url(blend.jpg);"> + </div> + + <div style="position:absolute;top:20;left:20;z-index:2;"> + <h1>fb-contrib: Bug Descriptions</h1> + + <table border="1" width="100%"> + <xsl:apply-templates select="BugCode"/> + </table> + </div> + </body> + </html> + </xsl:template> + + <xsl:template match="BugCode"> + <xsl:call-template name="Pattern"> + <xsl:with-param name="abbrev"><xsl:value-of select="@abbrev"/></xsl:with-param> + </xsl:call-template> + </xsl:template> + + <xsl:template name="Pattern"> + <xsl:param name="abbrev"/> + <xsl:for-each select="//BugPattern[starts-with(@type,$abbrev)]"> + <tr><td><b><xsl:value-of select="@type"/></b></td></tr> + <xsl:variable name="desc1"><xsl:value-of select="normalize-space(Details/text())"/></xsl:variable> + <xsl:variable name="desc2"><xsl:value-of select="substring($desc1, 9)"/></xsl:variable> + <xsl:variable name="desc"><xsl:value-of select="substring($desc2, 0, string-length($desc2) - 3)"/></xsl:variable> + <tr><td><xsl:copy-of select="$desc"/></td></tr> + </xsl:for-each> + </xsl:template> + +</xsl:transform> \ No newline at end of file Modified: trunk/fb-contrib/htdocs/index.html =================================================================== --- trunk/fb-contrib/htdocs/index.html 2006-09-11 03:58:12 UTC (rev 642) +++ trunk/fb-contrib/htdocs/index.html 2006-09-11 05:10:23 UTC (rev 643) @@ -44,6 +44,8 @@ <a href="http://www.sourceforge.net/projects/fb-contrib">Project Page</a> <img src="vbar.gif" height="12"/> <a href="javadoc/index.html">JavaDoc</a> + <img src="vbar.gif" height="12"/> + <a href="bugdescriptions.html">Bug Descriptions</a> <hr/> <img id="svn_image" src="flip2.gif" onClick="toggleBlock('svn', 'svn_image');" align="top"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-09-12 02:57:33
|
Revision: 646 http://svn.sourceforge.net/fb-contrib/?rev=646&view=rev Author: dbrosius Date: 2006-09-11 19:57:27 -0700 (Mon, 11 Sep 2006) Log Message: ----------- don't report no setLabelFor when the JLabel doesn't have a String Modified Paths: -------------- trunk/fb-contrib/samples/S508C_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java Modified: trunk/fb-contrib/samples/S508C_Sample.java =================================================================== --- trunk/fb-contrib/samples/S508C_Sample.java 2006-09-11 05:20:58 UTC (rev 645) +++ trunk/fb-contrib/samples/S508C_Sample.java 2006-09-12 02:57:27 UTC (rev 646) @@ -1,6 +1,7 @@ import java.awt.Color; import java.awt.Container; +import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; @@ -8,6 +9,7 @@ public class S508C_Sample extends JFrame { private JLabel fLabel = new JLabel("Hello"); + private JLabel imgLabel = new JLabel(new ImageIcon("/boo.gif")); private JComponent c = new MyComponent(); public S508C_Sample() { @@ -19,6 +21,9 @@ lLabel.setBackground(new Color(255, 0, 0)); lLabel.setForeground(new Color(255, 255, 100)); cp.add(lLabel); + + JLabel picLabel = new JLabel(new ImageIcon("/foo.gif")); + cp.add(picLabel); cp.add(c); setSize(300, 200); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-09-11 05:20:58 UTC (rev 645) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-09-12 02:57:27 UTC (rev 646) @@ -164,16 +164,37 @@ */ @Override public void sawOpcode(int seen) { + boolean sawTextLabel = false; try { stack.mergeJumps(this); if ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3))) { if (stack.getStackDepth() > 0) { OpcodeStack.Item item = stack.getStackItem(0); - if ("Ljavax/swing/JLabel;".equals(item.getSignature())) { + if ("Ljavax/swing/JLabel;".equals(item.getSignature()) + && (item.getUserValue() != null)) { int reg = RegisterUtils.getAStoreReg(this, seen); localLabels.put(Integer14.valueOf(reg), SourceLineAnnotation.fromVisitedInstruction(this)); } } + } else if (seen == PUTFIELD) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item item = stack.getStackItem(0); + if (item.getUserValue() == null) { + FieldAnnotation fa = new FieldAnnotation(getClassName(), getNameConstantOperand(), getSigConstantOperand(), false); + if (fa != null) + fieldLabels.remove(fa); + } + } + } else if (seen == INVOKESPECIAL) { + String className = getClassConstantOperand(); + String methodName = getNameConstantOperand(); + if ("javax/swing/JLabel".equals(className) + && "<init>".equals(methodName)) { + String signature = getSigConstantOperand(); + if (signature.indexOf("Ljava/lang/String;") >= 0) { + sawTextLabel = true; + } + } } else if (seen == INVOKEVIRTUAL) { String className = getClassConstantOperand(); String methodName = getNameConstantOperand(); @@ -238,6 +259,12 @@ bugReporter.reportMissingClass(cnfe); } finally { stack.sawOpcode(this, seen); + if (sawTextLabel) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item item = stack.getStackItem(0); + item.setUserValue(Boolean.TRUE); + } + } } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-09-15 22:44:13
|
Revision: 650 http://svn.sourceforge.net/fb-contrib/?rev=650&view=rev Author: dbrosius Date: 2006-09-15 15:44:04 -0700 (Fri, 15 Sep 2006) Log Message: ----------- add risky classes to ignore as well, especially ByteBuffer Modified Paths: -------------- trunk/fb-contrib/samples/RMC_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java Modified: trunk/fb-contrib/samples/RMC_Sample.java =================================================================== --- trunk/fb-contrib/samples/RMC_Sample.java 2006-09-14 04:57:15 UTC (rev 649) +++ trunk/fb-contrib/samples/RMC_Sample.java 2006-09-15 22:44:04 UTC (rev 650) @@ -1,3 +1,4 @@ +import java.nio.ByteBuffer; import java.util.Calendar; import java.util.Date; @@ -11,4 +12,10 @@ long j = e.getTime(); return l == j; } + + public void rmcFP(ByteBuffer bb) + { + int i = bb.getInt(); + int j = bb.getInt(); + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java 2006-09-14 04:57:15 UTC (rev 649) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java 2006-09-15 22:44:04 UTC (rev 650) @@ -46,7 +46,8 @@ */ public class RedundantMethodCalls extends BytecodeScanningDetector { - public static final String RMC_RISKY_USER_KEY = "fbcontrib.RMC.riskynames"; + public static final String RMC_RISKY_FIELD_USER_KEY = "fbcontrib.RMC.riskynames"; + public static final String RMC_RISKY_CLASS_USER_KEY = "fbcontrib.RMC.riskyclasses"; private static Set<String> riskyMethodNameContents = new HashSet<String>(); static { @@ -61,13 +62,26 @@ riskyMethodNameContents.add("pop"); riskyMethodNameContents.add("clone"); - String userNameProp = System.getProperty(RMC_RISKY_USER_KEY); + String userNameProp = System.getProperty(RMC_RISKY_FIELD_USER_KEY); if (userNameProp != null) { String[] userNames = userNameProp.split("\\s*,\\s*"); for (String name : userNames) riskyMethodNameContents.add(name.toLowerCase()); } } + private static Set<String> riskyClassNames = new HashSet<String>(); + static { + riskyClassNames.add("java/nio/ByteBuffer"); + riskyClassNames.add("java/io/DataInputStream"); + riskyClassNames.add("java/io/ObjectInputStream"); + String userNameProp = System.getProperty(RMC_RISKY_CLASS_USER_KEY); + if (userNameProp != null) { + String[] userNames = userNameProp.split("\\s*,\\s*"); + for (String name : userNames) + riskyClassNames.add(name); + } + } + private BugReporter bugReporter; private OpcodeStack stack = null; private Map<Integer, MethodCall> localMethodCalls = null; @@ -146,6 +160,7 @@ } else if (seen == PUTFIELD) { fieldMethodCalls.remove(getNameConstantOperand()); } else if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) { + String className = getClassConstantOperand(); String methodName = getNameConstantOperand(); String signature = getSigConstantOperand(); int parmCount = Type.getArgumentTypes(signature).length; @@ -170,7 +185,7 @@ return; if (mc != null) { - if (!signature.endsWith("V") && methodName.equals(mc.getName()) && signature.equals(mc.getSignature()) && !isRiskyName(methodName)) { + if (!signature.endsWith("V") && methodName.equals(mc.getName()) && signature.equals(mc.getSignature()) && !isRiskyName(className, methodName)) { Object[] parms = mc.getParms(); if (Arrays.equals(parms, parmConstants)) { Statistics statistics = Statistics.getStatistics(); @@ -201,12 +216,16 @@ } /** - * returns true if the method name contains a pattern that is considered likely to be this modifying + * returns true if the class or method name contains a pattern that is considered likely to be this modifying * + * @param className the class name to check * @param methodName the method name to check * @return whether the method sounds like it modifies this */ - private boolean isRiskyName(String methodName) { + private boolean isRiskyName(String className, String methodName) { + if (riskyClassNames.contains(className)) + return true; + methodName = methodName.toLowerCase(Locale.ENGLISH); for (String riskyName : riskyMethodNameContents) { if (methodName.indexOf(riskyName) >= 0) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-09-24 19:51:25
|
Revision: 655 http://svn.sourceforge.net/fb-contrib/?rev=655&view=rev Author: dbrosius Date: 2006-09-24 12:51:17 -0700 (Sun, 24 Sep 2006) Log Message: ----------- Modified Paths: -------------- trunk/fb-contrib/.classpath Removed Paths: ------------- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java Modified: trunk/fb-contrib/.classpath =================================================================== --- trunk/fb-contrib/.classpath 2006-09-24 19:49:47 UTC (rev 654) +++ trunk/fb-contrib/.classpath 2006-09-24 19:51:17 UTC (rev 655) @@ -3,8 +3,7 @@ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="samples"/> - <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/lib/findbugs.jar"/> - <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/lib/bcel.jar"/> - <classpathentry kind="lib" path="O:/fb-contrib/fb-contrib/samples/lib/jsp-api.jar"/> + <classpathentry kind="lib" path="O:/fb-contrib/trunk/fb-contrib/lib/findbugs.jar"/> + <classpathentry kind="lib" path="O:/fb-contrib/trunk/fb-contrib/lib/bcel.jar"/> <classpathentry kind="output" path="classes"/> </classpath> Deleted: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java 2006-09-24 19:49:47 UTC (rev 654) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java 2006-09-24 19:51:17 UTC (rev 655) @@ -1,265 +0,0 @@ -/* - * fb-contrib - Auxilliary detectors for Java programs - * Copyright (C) 2005-2006 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 - */ -package com.mebigfatguy.fbcontrib.detect; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import org.apache.bcel.classfile.Code; -import org.apache.bcel.classfile.CodeException; -import org.apache.bcel.generic.Type; - -import com.mebigfatguy.fbcontrib.collect.Statistics; -import com.mebigfatguy.fbcontrib.utils.Integer14; -import com.mebigfatguy.fbcontrib.utils.RegisterUtils; - -import edu.umd.cs.findbugs.BugInstance; -import edu.umd.cs.findbugs.BugReporter; -import edu.umd.cs.findbugs.BytecodeScanningDetector; -import edu.umd.cs.findbugs.FieldAnnotation; -import edu.umd.cs.findbugs.OpcodeStack; -import edu.umd.cs.findbugs.ba.ClassContext; - -/** - * looks for calls of the same method on the same object when that object hasn't changed. - * This often is redundant, and the second call can be removed, or combined. - */ -public class RedundantMethodCalls extends BytecodeScanningDetector -{ - public static final String RMC_RISKY_FIELD_USER_KEY = "fbcontrib.RMC.riskynames"; - public static final String RMC_RISKY_CLASS_USER_KEY = "fbcontrib.RMC.riskyclasses"; - - private static Set<String> riskyMethodNameContents = new HashSet<String>(); - static { - riskyMethodNameContents.add("next"); - riskyMethodNameContents.add("add"); - riskyMethodNameContents.add("append"); - riskyMethodNameContents.add("put"); - riskyMethodNameContents.add("remove"); - riskyMethodNameContents.add("read"); - riskyMethodNameContents.add("write"); - riskyMethodNameContents.add("push"); - riskyMethodNameContents.add("pop"); - riskyMethodNameContents.add("skip"); - riskyMethodNameContents.add("clone"); - - String userNameProp = System.getProperty(RMC_RISKY_FIELD_USER_KEY); - if (userNameProp != null) { - String[] userNames = userNameProp.split("\\s*,\\s*"); - for (String name : userNames) - riskyMethodNameContents.add(name.toLowerCase()); - } - } - private static Set<String> riskyClassNames = new HashSet<String>(); - static { - riskyClassNames.add("java/nio/ByteBuffer"); - riskyClassNames.add("java/io/DataInputStream"); - riskyClassNames.add("java/io/ObjectInputStream"); - String userNameProp = System.getProperty(RMC_RISKY_CLASS_USER_KEY); - if (userNameProp != null) { - String[] userNames = userNameProp.split("\\s*,\\s*"); - for (String name : userNames) - riskyClassNames.add(name); - } - } - - private BugReporter bugReporter; - private OpcodeStack stack = null; - private Map<Integer, MethodCall> localMethodCalls = null; - private Map<String, MethodCall> fieldMethodCalls = null; - private Set<Integer> branchTargets = null; - - /** - * constructs a RMC detector given the reporter to report bugs on - * @param bugReporter the sync of bug reports - */ - public RedundantMethodCalls(BugReporter bugReporter) { - this.bugReporter = bugReporter; - } - - /** - * implements the visitor to create and clear the stack, method call maps, and branch targets - * - * @param classContext the context object of the currently visited class - */ - public void visitClassContext(ClassContext classContext) { - try { - stack = new OpcodeStack(); - localMethodCalls = new HashMap<Integer, MethodCall>(); - fieldMethodCalls = new HashMap<String, MethodCall>(); - branchTargets = new HashSet<Integer>(); - super.visitClassContext(classContext); - } finally { - stack = null; - localMethodCalls = null; - fieldMethodCalls = null; - branchTargets = null; - } - } - - /** - * implements the visitor to reset the stack, and method call maps for new method - * - * @param obj the context object of the currently parsed code block - */ - public void visitCode(Code obj) { - stack.resetForMethodEntry(this); - localMethodCalls.clear(); - fieldMethodCalls.clear(); - branchTargets.clear(); - CodeException[] codeExceptions = obj.getExceptionTable(); - for (CodeException codeEx : codeExceptions) { - branchTargets.add(codeEx.getHandlerPC()); - } - super.visitCode(obj); - } - - /** - * implements the visitor to look for repetitive calls to the same method on the same object - * using the same constant parameters. These methods must return a value. - * - * @param seen the opcode of the currently parsed instruction - */ - public void sawOpcode(int seen) { - try { - stack.mergeJumps(this); - if (branchTargets.remove(Integer14.valueOf(getPC()))) { - localMethodCalls.clear(); - fieldMethodCalls.clear(); - } - - if (((seen >= IFEQ) && (seen <= GOTO)) || ((seen >= IFNULL) && (seen <= GOTO_W))) { - branchTargets.add(Integer14.valueOf(getBranchTarget())); - } else if ((seen == TABLESWITCH) || (seen == LOOKUPSWITCH)) { - int[] offsets = getSwitchOffsets(); - int pc = getPC(); - for (int offset : offsets) { - branchTargets.add(Integer14.valueOf(offset + pc)); - } - } else if ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3))) { - localMethodCalls.remove(Integer14.valueOf(RegisterUtils.getAStoreReg(this, seen))); - } else if (seen == PUTFIELD) { - fieldMethodCalls.remove(getNameConstantOperand()); - } else if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) { - String className = getClassConstantOperand(); - String methodName = getNameConstantOperand(); - String signature = getSigConstantOperand(); - int parmCount = Type.getArgumentTypes(signature).length; - if (stack.getStackDepth() > parmCount) { - Object[] parmConstants = new Object[parmCount]; - for (int i = 0; i < parmCount; i++) { - OpcodeStack.Item parm = stack.getStackItem(i); - parmConstants[i] = parm.getConstant(); - if (parmConstants[i] == null) - return; - } - OpcodeStack.Item obj = stack.getStackItem(parmCount); - int reg = obj.getRegisterNumber(); - FieldAnnotation fa = obj.getField(); - - MethodCall mc; - if (reg >= 0) { - mc = localMethodCalls.get(Integer14.valueOf(reg)); - } else if (fa != null) { - mc = fieldMethodCalls.get(fa.getFieldName()); - } else - return; - - if (mc != null) { - if (!signature.endsWith("V") && methodName.equals(mc.getName()) && signature.equals(mc.getSignature()) && !isRiskyName(className, methodName)) { - Object[] parms = mc.getParms(); - if (Arrays.equals(parms, parmConstants)) { - Statistics statistics = Statistics.getStatistics(); - bugReporter.reportBug(new BugInstance(this, "RMC_REDUNDANT_METHOD_CALLS", statistics.isSimpleGetter(getClassConstantOperand(), methodName, signature) ? EXP_PRIORITY : NORMAL_PRIORITY) - .addClass(this) - .addMethod(this) - .addSourceLine(this) - .addString(methodName + signature)); - } - } - if (reg >= 0) { - localMethodCalls.remove(Integer14.valueOf(reg)); - } else { - fieldMethodCalls.remove(fa.getFieldName()); - } - } else { - if (reg >= 0) { - localMethodCalls.put(Integer14.valueOf(reg), new MethodCall(methodName, signature, parmConstants)); - } else if (fa != null) { - fieldMethodCalls.put(fa.getFieldName(), new MethodCall(methodName, signature, parmConstants)); - } - } - } - } - } finally { - stack.sawOpcode(this, seen); - } - } - - /** - * returns true if the class or method name contains a pattern that is considered likely to be this modifying - * - * @param className the class name to check - * @param methodName the method name to check - * @return whether the method sounds like it modifies this - */ - private boolean isRiskyName(String className, String methodName) { - if (riskyClassNames.contains(className)) - return true; - - methodName = methodName.toLowerCase(Locale.ENGLISH); - for (String riskyName : riskyMethodNameContents) { - if (methodName.indexOf(riskyName) >= 0) - return true; - } - return false; - } - - /** - * contains information about a method call - */ - static class MethodCall - { - private String methodName; - private String methodSignature; - private Object[] methodParms; - - public MethodCall(String name, String signature, Object[] parms) { - methodName = name; - methodSignature = signature; - methodParms = parms; - } - - public String getName() { - return methodName; - } - - public String getSignature() { - return methodSignature; - } - - public Object[] getParms() { - return methodParms; - } - } -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-09-24 19:52:35
|
Revision: 656 http://svn.sourceforge.net/fb-contrib/?rev=656&view=rev Author: dbrosius Date: 2006-09-24 12:52:31 -0700 (Sun, 24 Sep 2006) Log Message: ----------- Removed Paths: ------------- trunk/fb-contrib/.classpath trunk/fb-contrib/.project Deleted: trunk/fb-contrib/.classpath =================================================================== --- trunk/fb-contrib/.classpath 2006-09-24 19:51:17 UTC (rev 655) +++ trunk/fb-contrib/.classpath 2006-09-24 19:52:31 UTC (rev 656) @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="src" path="src"/> - <classpathentry kind="src" path="samples"/> - <classpathentry kind="lib" path="O:/fb-contrib/trunk/fb-contrib/lib/findbugs.jar"/> - <classpathentry kind="lib" path="O:/fb-contrib/trunk/fb-contrib/lib/bcel.jar"/> - <classpathentry kind="output" path="classes"/> -</classpath> Deleted: trunk/fb-contrib/.project =================================================================== --- trunk/fb-contrib/.project 2006-09-24 19:51:17 UTC (rev 655) +++ trunk/fb-contrib/.project 2006-09-24 19:52:31 UTC (rev 656) @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>fb-contrib</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-10-06 02:57:12
|
Revision: 662 http://svn.sourceforge.net/fb-contrib/?rev=662&view=rev Author: dbrosius Date: 2006-10-05 19:57:07 -0700 (Thu, 05 Oct 2006) Log Message: ----------- get ready for 3.0.0 Modified Paths: -------------- trunk/fb-contrib/build.xml trunk/fb-contrib/htdocs/index.html Modified: trunk/fb-contrib/build.xml =================================================================== --- trunk/fb-contrib/build.xml 2006-09-25 02:30:17 UTC (rev 661) +++ trunk/fb-contrib/build.xml 2006-10-06 02:57:07 UTC (rev 662) @@ -20,7 +20,7 @@ <property name="javac.deprecation" value="on"/> <property name="javac.debug" value="on"/> - <property name="fb-contrib.version" value="2.9.0"/> + <property name="fb-contrib.version" value="3.0.0"/> <target name="clean" description="removes all generated collateral"> <delete dir="${classes.dir}"/> Modified: trunk/fb-contrib/htdocs/index.html =================================================================== --- trunk/fb-contrib/htdocs/index.html 2006-09-25 02:30:17 UTC (rev 661) +++ trunk/fb-contrib/htdocs/index.html 2006-10-06 02:57:07 UTC (rev 662) @@ -48,8 +48,13 @@ <a href="bugdescriptions.html">Bug Descriptions</a> <hr/> - <img id="svn_image" src="flip2.gif" onClick="toggleBlock('svn', 'svn_image');" align="top"/> + <img id="svn_image" src="flip1.gif" onClick="toggleBlock('svn', 'svn_image');" align="top"/> Detectors added in svn<br/> + <div id="svn" style="display:none;"> + </div> + <hr/> + <img id="v3_0_0_image" src="flip2.gif" onClick="toggleBlock('v3_0_0', 'svn_image');" align="top"/> + Detectors added in v3.0.0<br/> <div id="svn" style="display:block;"> <ul> <li><b>[LEST] Lost Exception Stack Trace</b><br/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-10-27 05:28:07
|
Revision: 674 http://svn.sourceforge.net/fb-contrib/?rev=674&view=rev Author: dbrosius Date: 2006-10-26 22:27:56 -0700 (Thu, 26 Oct 2006) Log Message: ----------- Initial checkin SC detector (no xml support yet) Added Paths: ----------- trunk/fb-contrib/samples/SC_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java Added: trunk/fb-contrib/samples/SC_Sample.java =================================================================== --- trunk/fb-contrib/samples/SC_Sample.java (rev 0) +++ trunk/fb-contrib/samples/SC_Sample.java 2006-10-27 05:27:56 UTC (rev 674) @@ -0,0 +1,28 @@ +import java.util.Comparator; + +public class SC_Sample +{ + public static final int T1 = 0; + public static final int T2 = 1; + + int t = 0; + class SampleComparator implements Comparator<SC_Sample> + { + public int compare(SC_Sample arg0, SC_Sample arg1) { + if (arg0.t == arg1.t) + return 0; + + return -1; + } + } + + class SampleComparable implements Comparable<SC_Sample> + { + public int compareTo(SC_Sample arg0) { + if (t == arg0.t) + return 0; + + return 1; + } + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java 2006-10-27 05:27:56 UTC (rev 674) @@ -0,0 +1,120 @@ +package com.mebigfatguy.fbcontrib.detect; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.bcel.Repository; +import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.generic.Type; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.OpcodeStack; +import edu.umd.cs.findbugs.ba.ClassContext; + +/** + * looks for class that implement Comparator or Comparable, and whose compare or compareTo + * methods return constant values only, but that don't represent the three possible choice + * (a negative number, 0, and a positive number). + */ +public class SuspiciousComparator extends BytecodeScanningDetector +{ + private static Map<JavaClass, String> compareClasses = new HashMap<JavaClass, String>(); + static { + try { + compareClasses.put(Repository.lookupClass("java/lang/Comparable"), "compare:2:I");; + compareClasses.put(Repository.lookupClass("java.lang/Comparator"), "compareTo:1:I"); + } catch (ClassNotFoundException cnfe) { + } + } + + private OpcodeStack stack; + private BugReporter bugReporter; + private String[] methodInfo; + private boolean indeterminate; + private boolean seenNegative; + private boolean seenPositive; + private boolean seenZero; + + + /** + * constructs a DRE detector given the reporter to report bugs on + * @param bugReporter the sync of bug reports + */ + public SuspiciousComparator(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + public void visitClassContext(ClassContext classContext) { + try { + JavaClass cls = classContext.getJavaClass(); + for (Map.Entry<JavaClass, String> entry : compareClasses.entrySet()) { + if (cls.implementationOf(entry.getKey())) { + methodInfo = entry.getValue().split(":"); + stack = new OpcodeStack(); + super.visitClassContext(classContext); + break; + } + } + } catch (ClassNotFoundException cnfe) { + bugReporter.reportMissingClass(cnfe); + } finally { + methodInfo = null; + stack = null; + } + } + + public void visitCode(Code obj) { + String methodName = getMethodName(); + String methodSig = getMethodSig(); + if (methodName.equals(methodInfo[0]) + && methodSig.endsWith(methodInfo[2]) + && (Type.getArgumentTypes(methodSig).length == Integer.valueOf(methodInfo[1]))) { + stack.resetForMethodEntry(this); + indeterminate = false; + seenNegative = false; + seenPositive = false; + seenZero = false; + super.visitCode(obj); + if (!indeterminate) { + boolean seenAll = seenNegative & seenPositive & seenZero; + if (!seenAll) { + bugReporter.reportBug(new BugInstance(this, "SC_SUSPICIOUS_COMPARATOR", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this, 0)); + } + } + } + } + + public void sawOpcode(int seen) { + try { + if (indeterminate) + return; + + if (seen == IRETURN) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item item = stack.getStackItem(0); + Integer returnValue = (Integer)item.getConstant(); + if (returnValue == null) + indeterminate = true; + else { + int v = returnValue.intValue(); + if (v < 0) + seenNegative = true; + else if (v > 0) + seenPositive = true; + else + seenZero = true; + } + } else + indeterminate = true; + } + } finally { + stack.sawOpcode(this, seen); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-10-28 18:33:16
|
Revision: 678 http://svn.sourceforge.net/fb-contrib/?rev=678&view=rev Author: dbrosius Date: 2006-10-28 11:29:46 -0700 (Sat, 28 Oct 2006) Log Message: ----------- adjust SC to SCRV Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Removed Paths: ------------- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-10-28 18:21:35 UTC (rev 677) +++ trunk/fb-contrib/etc/findbugs.xml 2006-10-28 18:29:46 UTC (rev 678) @@ -252,7 +252,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousComparator" speed="fast" - reports="SC_SUSPICIOUS_COMPARATOR"/> + reports="SC_SUSPICIOUS_COMPARATOR_RETURN_VALUES"/> <!-- BugPattern --> @@ -318,5 +318,5 @@ <BugPattern abbrev="URV" type="URV_CHANGE_RETURN_TYPE" category="STYLE" /> <BugPattern abbrev="URV" type="URV_INHERITED_METHOD_WITH_RELATED_TYPES" category="STYLE" /> <BugPattern abbrev="PIS" type="PIS_POSSIBLE_INCOMPLETE_SERIALIZATION" category="CORRECTNESS" /> - <BugPattern abbrev="SC" type="SC_SUSPICIOUS_COMPARATOR" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="SCRV" type="SC_SUSPICIOUS_COMPARATOR_RETURN_VALUES" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-10-28 18:21:35 UTC (rev 677) +++ trunk/fb-contrib/etc/messages.xml 2006-10-28 18:29:46 UTC (rev 678) @@ -1496,7 +1496,7 @@ </Details> </BugPattern> - <BugPattern type="SC_SUSPICIOUS_COMPARATOR"> + <BugPattern type="SC_SUSPICIOUS_COMPARATOR_RETURN_VALUES"> <ShortDescription>Comparator method doesn't seem to return all ordering values</ShortDescription> <LongDescription>Comparator method {1} doesn't seem to return all ordering values</LongDescription> <Details> @@ -1565,5 +1565,5 @@ <BugCode abbrev="TR">Tail Recursion</BugCode> <BugCode abbrev="URV">Unrelated Return Values</BugCode> <BugCode abbrev="PIS">Possible Incomplete Serialization</BugCode> - <BugCode abbrev="SC">Suspicious Comparator</BugCode> + <BugCode abbrev="SCRV">Suspicious Comparator Return Values</BugCode> </MessageCollection> \ No newline at end of file Deleted: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java 2006-10-28 18:21:35 UTC (rev 677) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java 2006-10-28 18:29:46 UTC (rev 678) @@ -1,120 +0,0 @@ -package com.mebigfatguy.fbcontrib.detect; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.bcel.Repository; -import org.apache.bcel.classfile.Code; -import org.apache.bcel.classfile.JavaClass; -import org.apache.bcel.generic.Type; - -import edu.umd.cs.findbugs.BugInstance; -import edu.umd.cs.findbugs.BugReporter; -import edu.umd.cs.findbugs.BytecodeScanningDetector; -import edu.umd.cs.findbugs.OpcodeStack; -import edu.umd.cs.findbugs.ba.ClassContext; - -/** - * looks for class that implement Comparator or Comparable, and whose compare or compareTo - * methods return constant values only, but that don't represent the three possible choice - * (a negative number, 0, and a positive number). - */ -public class SuspiciousComparator extends BytecodeScanningDetector -{ - private static Map<JavaClass, String> compareClasses = new HashMap<JavaClass, String>(); - static { - try { - compareClasses.put(Repository.lookupClass("java/lang/Comparable"), "compare:2:I");; - compareClasses.put(Repository.lookupClass("java.lang/Comparator"), "compareTo:1:I"); - } catch (ClassNotFoundException cnfe) { - } - } - - private OpcodeStack stack; - private BugReporter bugReporter; - private String[] methodInfo; - private boolean indeterminate; - private boolean seenNegative; - private boolean seenPositive; - private boolean seenZero; - - - /** - * constructs a DRE detector given the reporter to report bugs on - * @param bugReporter the sync of bug reports - */ - public SuspiciousComparator(BugReporter bugReporter) { - this.bugReporter = bugReporter; - } - - public void visitClassContext(ClassContext classContext) { - try { - JavaClass cls = classContext.getJavaClass(); - for (Map.Entry<JavaClass, String> entry : compareClasses.entrySet()) { - if (cls.implementationOf(entry.getKey())) { - methodInfo = entry.getValue().split(":"); - stack = new OpcodeStack(); - super.visitClassContext(classContext); - break; - } - } - } catch (ClassNotFoundException cnfe) { - bugReporter.reportMissingClass(cnfe); - } finally { - methodInfo = null; - stack = null; - } - } - - public void visitCode(Code obj) { - String methodName = getMethodName(); - String methodSig = getMethodSig(); - if (methodName.equals(methodInfo[0]) - && methodSig.endsWith(methodInfo[2]) - && (Type.getArgumentTypes(methodSig).length == Integer.valueOf(methodInfo[1]))) { - stack.resetForMethodEntry(this); - indeterminate = false; - seenNegative = false; - seenPositive = false; - seenZero = false; - super.visitCode(obj); - if (!indeterminate) { - boolean seenAll = seenNegative & seenPositive & seenZero; - if (!seenAll) { - bugReporter.reportBug(new BugInstance(this, "SC_SUSPICIOUS_COMPARATOR", NORMAL_PRIORITY) - .addClass(this) - .addMethod(this) - .addSourceLine(this, 0)); - } - } - } - } - - public void sawOpcode(int seen) { - try { - if (indeterminate) - return; - - if (seen == IRETURN) { - if (stack.getStackDepth() > 0) { - OpcodeStack.Item item = stack.getStackItem(0); - Integer returnValue = (Integer)item.getConstant(); - if (returnValue == null) - indeterminate = true; - else { - int v = returnValue.intValue(); - if (v < 0) - seenNegative = true; - else if (v > 0) - seenPositive = true; - else - seenZero = true; - } - } else - indeterminate = true; - } - } finally { - stack.sawOpcode(this, seen); - } - } -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-11-19 03:16:45
|
Revision: 685 http://svn.sourceforge.net/fb-contrib/?rev=685&view=rev Author: dbrosius Date: 2006-11-18 19:16:44 -0800 (Sat, 18 Nov 2006) Log Message: ----------- Initial checkin, new SPP detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/SPP_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-10-29 05:27:40 UTC (rev 684) +++ trunk/fb-contrib/etc/findbugs.xml 2006-11-19 03:16:44 UTC (rev 685) @@ -254,6 +254,10 @@ speed="fast" reports="SC_SUSPICIOUS_COMPARATOR_RETURN_VALUES"/> + <Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri" + speed="fast" + reports="SPP_NEGATIVE_BITSET_ITEM"/> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -319,4 +323,6 @@ <BugPattern abbrev="URV" type="URV_INHERITED_METHOD_WITH_RELATED_TYPES" category="STYLE" /> <BugPattern abbrev="PIS" type="PIS_POSSIBLE_INCOMPLETE_SERIALIZATION" category="CORRECTNESS" /> <BugPattern abbrev="SCRV" type="SC_SUSPICIOUS_COMPARATOR_RETURN_VALUES" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="SPP" type="SPP_NEGATIVE_BITSET_ITEM" category="CORRECTNESS" experimental="true" /> + </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-10-29 05:27:40 UTC (rev 684) +++ trunk/fb-contrib/etc/messages.xml 2006-11-19 03:16:44 UTC (rev 685) @@ -686,6 +686,14 @@ </Details> </Detector> + <Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri"> + <Details> + <![CDATA[ + <p>looks for a potpourri of small problems that do not fit into a common pattern.</p> + ]]> + </Details> + </Detector> + <!-- BugPattern --> <BugPattern type="ISB_INEFFICIENT_STRING_BUFFERING"> @@ -1508,6 +1516,17 @@ </Details> </BugPattern> + <BugPattern type="SPP_NEGATIVE_BITSET_ITEM"> + <ShortDescription>Method passes a negative number as a bit to a BitSet which isn't supported</ShortDescription> + <LongDescription>Method {1} passes a negative number as a bit to a BitSet which isn't supported</LongDescription> + <Details> + <![CDATA[ + <p>This method passes a constant negative value as a bit position to a java.util.BitSet. The BitSet class + doesn't support negative values, and thus this method call will not work as expected.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1566,4 +1585,6 @@ <BugCode abbrev="URV">Unrelated Return Values</BugCode> <BugCode abbrev="PIS">Possible Incomplete Serialization</BugCode> <BugCode abbrev="SCRV">Suspicious Comparator Return Values</BugCode> + <BugCode abbrev="SPP">Sillyness Pot Pourri</BugCode> + </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/SPP_Sample.java =================================================================== --- trunk/fb-contrib/samples/SPP_Sample.java (rev 0) +++ trunk/fb-contrib/samples/SPP_Sample.java 2006-11-19 03:16:44 UTC (rev 685) @@ -0,0 +1,10 @@ +import java.util.BitSet; + +public class SPP_Sample +{ + public void testSPPBitSet(BitSet b) + { + b.set(-1); + } + +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-19 03:16:44 UTC (rev 685) @@ -0,0 +1,100 @@ +/* + * fb-contrib - Auxilliary detectors for Java programs + * Copyright (C) 2005-2006 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 + */ +package com.mebigfatguy.fbcontrib.detect; + +import org.apache.bcel.classfile.Code; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.OpcodeStack; +import edu.umd.cs.findbugs.ba.ClassContext; + +/** + * looks for silly bugs that are simple but do not fit into one large pattern. + */ +public class SillynessPotPourri extends BytecodeScanningDetector +{ + private BugReporter bugReporter; + private OpcodeStack stack; + /** + * constructs a SPP detector given the reporter to report bugs on + * @param bugReporter the sync of bug reports + */ + public SillynessPotPourri(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + public void visitClassContext(ClassContext classContext) { + try { + stack = new OpcodeStack(); + super.visitClassContext(classContext); + } finally { + stack = null; + } + } + + /** + * implements the visitor to reset the opcode stack + * + * @param obj the context object for the currently parsed Code + */ + public void visitCode(Code obj) { + stack.resetForMethodEntry(this); + super.visitCode(obj); + } + + /** + * implements the visitor to look for various silly bugs + * + * @param seen the opcode of the currently parsed instruction + */ + public void sawOpcode(int seen) { + try { + stack.mergeJumps(this); + + if (seen == INVOKEVIRTUAL) { + String className = getClassConstantOperand(); + if ("java/util/BitSet".equals(className)) { + String methodName = getNameConstantOperand(); + if ("clear".equals(methodName) + || "flip".equals(methodName) + || "get".equals(methodName) + || "set".equals(methodName)) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item item = stack.getStackItem(0); + Object o =item.getConstant(); + if (o instanceof Integer) { + if (((Integer) o).intValue() < 0) { + bugReporter.reportBug(new BugInstance(this, "SPP_NEGATIVE_BITSET_ITEM", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } + } + } + } + + } finally { + stack.sawOpcode(this, seen); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-11-19 03:38:31
|
Revision: 686 http://svn.sourceforge.net/fb-contrib/?rev=686&view=rev Author: dbrosius Date: 2006-11-18 19:38:28 -0800 (Sat, 18 Nov 2006) Log Message: ----------- add Constant string interning to SPP Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/SPP_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-11-19 03:16:44 UTC (rev 685) +++ trunk/fb-contrib/etc/findbugs.xml 2006-11-19 03:38:28 UTC (rev 686) @@ -256,7 +256,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri" speed="fast" - reports="SPP_NEGATIVE_BITSET_ITEM"/> + reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT"/> <!-- BugPattern --> @@ -324,5 +324,6 @@ <BugPattern abbrev="PIS" type="PIS_POSSIBLE_INCOMPLETE_SERIALIZATION" category="CORRECTNESS" /> <BugPattern abbrev="SCRV" type="SC_SUSPICIOUS_COMPARATOR_RETURN_VALUES" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_NEGATIVE_BITSET_ITEM" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="SPP" type="SPP_INTERN_ON_CONSTANT" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-11-19 03:16:44 UTC (rev 685) +++ trunk/fb-contrib/etc/messages.xml 2006-11-19 03:38:28 UTC (rev 686) @@ -1527,6 +1527,17 @@ </Details> </BugPattern> + <BugPattern type="SPP_INTERN_ON_CONSTANT"> + <ShortDescription>Method calls intern on a string constant</ShortDescription> + <LongDescription>Method {1} calls intern on a string constant</LongDescription> + <Details> + <![CDATA[ + <p>This method calls intern on a constant string. As constant strings are already interned, this call + is superfluous</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> Modified: trunk/fb-contrib/samples/SPP_Sample.java =================================================================== --- trunk/fb-contrib/samples/SPP_Sample.java 2006-11-19 03:16:44 UTC (rev 685) +++ trunk/fb-contrib/samples/SPP_Sample.java 2006-11-19 03:38:28 UTC (rev 686) @@ -2,9 +2,15 @@ public class SPP_Sample { + public void testSPPBitSet(BitSet b) { b.set(-1); } + + public String testSPPIntern() + { + return "FOO".intern(); //and yes i've seen this! + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-19 03:16:44 UTC (rev 685) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-19 03:38:28 UTC (rev 686) @@ -33,6 +33,7 @@ { private BugReporter bugReporter; private OpcodeStack stack; + /** * constructs a SPP detector given the reporter to report bugs on * @param bugReporter the sync of bug reports @@ -71,8 +72,8 @@ if (seen == INVOKEVIRTUAL) { String className = getClassConstantOperand(); + String methodName = getNameConstantOperand(); if ("java/util/BitSet".equals(className)) { - String methodName = getNameConstantOperand(); if ("clear".equals(methodName) || "flip".equals(methodName) || "get".equals(methodName) @@ -90,6 +91,18 @@ } } } + } else if ("java/lang/String".equals(className)) { + if ("intern".equals(methodName)) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item item = stack.getStackItem(0); + if (item.getConstant() != null) { + bugReporter.reportBug(new BugInstance(this, "SPP_INTERN_ON_CONSTANT", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-11-19 03:56:32
|
Revision: 687 http://svn.sourceforge.net/fb-contrib/?rev=687&view=rev Author: dbrosius Date: 2006-11-18 19:56:31 -0800 (Sat, 18 Nov 2006) Log Message: ----------- add StringBuffer(char) to SPP Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/SPP_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-11-19 03:38:28 UTC (rev 686) +++ trunk/fb-contrib/etc/findbugs.xml 2006-11-19 03:56:31 UTC (rev 687) @@ -256,7 +256,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri" speed="fast" - reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT"/> + reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR"/> <!-- BugPattern --> @@ -325,5 +325,6 @@ <BugPattern abbrev="SCRV" type="SC_SUSPICIOUS_COMPARATOR_RETURN_VALUES" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_NEGATIVE_BITSET_ITEM" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_INTERN_ON_CONSTANT" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="SPP" type="SPP_NO_CHAR_SB_CTOR" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-11-19 03:38:28 UTC (rev 686) +++ trunk/fb-contrib/etc/messages.xml 2006-11-19 03:56:31 UTC (rev 687) @@ -1538,6 +1538,19 @@ </Details> </BugPattern> + <BugPattern type="SPP_NO_CHAR_SB_CTOR"> + <ShortDescription>Method passes character to StringBuffer or StringBuilder integer constructor</ShortDescription> + <LongDescription>Method {1} passes character to StringBuffer or StringBuilder integer cosntructor</LongDescription> + <Details> + <![CDATA[ + <p>This method constructs a StringBuffer or a StringBuilder using the constructor that takes an integer, but + passes a character instead. It is probable that the author assumed that character would be appended to the + StringBuffer/Builder, but instead the integer value of the character is used as an initial size for the buffer. + </p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> Modified: trunk/fb-contrib/samples/SPP_Sample.java =================================================================== --- trunk/fb-contrib/samples/SPP_Sample.java 2006-11-19 03:38:28 UTC (rev 686) +++ trunk/fb-contrib/samples/SPP_Sample.java 2006-11-19 03:56:31 UTC (rev 687) @@ -12,5 +12,11 @@ { return "FOO".intern(); //and yes i've seen this! } - + + public String testSBWithChars() + { + StringBuffer sb = new StringBuffer('v'); + sb.append("ictory"); + return sb.toString(); + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-19 03:38:28 UTC (rev 686) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-19 03:56:31 UTC (rev 687) @@ -33,6 +33,7 @@ { private BugReporter bugReporter; private OpcodeStack stack; + private int lastOpcode; /** * constructs a SPP detector given the reporter to report bugs on @@ -58,6 +59,7 @@ */ public void visitCode(Code obj) { stack.resetForMethodEntry(this); + lastOpcode = -1; super.visitCode(obj); } @@ -104,10 +106,28 @@ } } } + } else if (seen == INVOKESPECIAL) { + String className = getClassConstantOperand(); + if ("java/lang/StringBuffer".equals(className) + || "java/lang/StringBuilder".equals(className)) { + String methodName = getNameConstantOperand(); + if ("<init>".equals(methodName)) { + String signature = getSigConstantOperand(); + if ("(I)V".equals(signature)) { + if (lastOpcode == BIPUSH) { + bugReporter.reportBug(new BugInstance(this, "SPP_NO_CHAR_SB_CTOR", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } + } } } finally { stack.sawOpcode(this, seen); + lastOpcode = seen; } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-11-19 05:18:32
|
Revision: 691 http://svn.sourceforge.net/fb-contrib/?rev=691&view=rev Author: dbrosius Date: 2006-11-18 21:18:32 -0800 (Sat, 18 Nov 2006) Log Message: ----------- add non Math.constants to SPP detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/SPP_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-11-19 04:36:12 UTC (rev 690) +++ trunk/fb-contrib/etc/findbugs.xml 2006-11-19 05:18:32 UTC (rev 691) @@ -256,7 +256,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri" speed="fast" - reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR"/> + reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT"/> <!-- BugPattern --> @@ -326,5 +326,6 @@ <BugPattern abbrev="SPP" type="SPP_NEGATIVE_BITSET_ITEM" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_INTERN_ON_CONSTANT" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_NO_CHAR_SB_CTOR" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="SPP" type="SPP_USE_MATH_CONSTANT" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-11-19 04:36:12 UTC (rev 690) +++ trunk/fb-contrib/etc/messages.xml 2006-11-19 05:18:32 UTC (rev 691) @@ -1551,6 +1551,17 @@ </Details> </BugPattern> + <BugPattern type="SPP_USE_MATH_CONSTANT"> + <ShortDescription>Method uses non standard math constant</ShortDescription> + <LongDescription>Method {1} uses non standard math constant</LongDescription> + <Details> + <![CDATA[ + <p>This method defines its own version of <b>PI</b> or <b>e</b> and the value is not as precise as the + one defined in the constants Math.PI or Math.E. Use these constants instead.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> Modified: trunk/fb-contrib/samples/SPP_Sample.java =================================================================== --- trunk/fb-contrib/samples/SPP_Sample.java 2006-11-19 04:36:12 UTC (rev 690) +++ trunk/fb-contrib/samples/SPP_Sample.java 2006-11-19 05:18:32 UTC (rev 691) @@ -2,7 +2,9 @@ public class SPP_Sample { - + private static final double pi = 3.14; + private static final double e = 2.72; + public void testSPPBitSet(BitSet b) { b.set(-1); @@ -19,4 +21,9 @@ sb.append("ictory"); return sb.toString(); } + + public double area(double radius) + { + return pi * radius * radius; + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-19 04:36:12 UTC (rev 690) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-19 05:18:32 UTC (rev 691) @@ -19,6 +19,7 @@ package com.mebigfatguy.fbcontrib.detect; import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.ConstantDouble; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; @@ -72,7 +73,22 @@ try { stack.mergeJumps(this); - if (seen == INVOKEVIRTUAL) { + if (seen == LDC2_W) { + Object con = getConstantRefOperand(); + if (con instanceof ConstantDouble) { + double d = ((ConstantDouble) con).getBytes(); + double piDelta = Math.abs(d - Math.PI); + double eDelta = Math.abs(d - Math.E); + + if (((piDelta > 0.0) && (piDelta < 0.002)) + || ((eDelta > 0.0) && (eDelta < 0.002))) { + bugReporter.reportBug(new BugInstance(this, "SPP_USE_MATH_CONSTANT", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } else if (seen == INVOKEVIRTUAL) { String className = getClassConstantOperand(); String methodName = getNameConstantOperand(); if ("java/util/BitSet".equals(className)) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-11-19 05:42:57
|
Revision: 692 http://svn.sourceforge.net/fb-contrib/?rev=692&view=rev Author: dbrosius Date: 2006-11-18 21:42:56 -0800 (Sat, 18 Nov 2006) Log Message: ----------- try to make SPP for StringBuffer(int) with char less prone to false +, and reenable Modified Paths: -------------- trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-11-19 05:18:32 UTC (rev 691) +++ trunk/fb-contrib/etc/messages.xml 2006-11-19 05:42:56 UTC (rev 692) @@ -1539,12 +1539,12 @@ </BugPattern> <BugPattern type="SPP_NO_CHAR_SB_CTOR"> - <ShortDescription>Method passes character to StringBuffer or StringBuilder integer constructor</ShortDescription> - <LongDescription>Method {1} passes character to StringBuffer or StringBuilder integer constructor</LongDescription> + <ShortDescription>Method appears to pass character to StringBuffer or StringBuilder integer constructor</ShortDescription> + <LongDescription>Method {1} appears to pass character to StringBuffer or StringBuilder integer constructor</LongDescription> <Details> <![CDATA[ <p>This method constructs a StringBuffer or a StringBuilder using the constructor that takes an integer, but - passes a character instead. It is probable that the author assumed that character would be appended to the + appears to pass a character instead. It is probable that the author assumed that character would be appended to the StringBuffer/Builder, but instead the integer value of the character is used as an initial size for the buffer. </p> ]]> Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-19 05:18:32 UTC (rev 691) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-19 05:42:56 UTC (rev 692) @@ -131,10 +131,23 @@ String signature = getSigConstantOperand(); if ("(I)V".equals(signature)) { if (lastOpcode == BIPUSH) { - //bugReporter.reportBug(new BugInstance(this, "SPP_NO_CHAR_SB_CTOR", NORMAL_PRIORITY) - // .addClass(this) - // .addMethod(this) - // .addSourceLine(this)); + if (stack.getStackDepth() > 0) { + OpcodeStack.Item item = stack.getStackItem(0); + Object o = item.getConstant(); + if (o instanceof Integer) { + int parm = ((Integer) o).intValue(); + if ((parm > 32) + && (parm < 127) + && (parm != 64) + && ((parm % 10) != 0) + && ((parm % 5) != 0)) { + bugReporter.reportBug(new BugInstance(this, "SPP_NO_CHAR_SB_CTOR", LOW_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-11-20 01:31:31
|
Revision: 694 http://svn.sourceforge.net/fb-contrib/?rev=694&view=rev Author: dbrosius Date: 2006-11-19 17:31:22 -0800 (Sun, 19 Nov 2006) Log Message: ----------- add assignment stutter checking to SPP Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/SPP_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-11-19 05:52:18 UTC (rev 693) +++ trunk/fb-contrib/etc/findbugs.xml 2006-11-20 01:31:22 UTC (rev 694) @@ -256,7 +256,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri" speed="fast" - reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT"/> + reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT,SPP_STUTTERED_ASSIGNMENT"/> <!-- BugPattern --> @@ -327,5 +327,6 @@ <BugPattern abbrev="SPP" type="SPP_INTERN_ON_CONSTANT" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_NO_CHAR_SB_CTOR" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_USE_MATH_CONSTANT" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="SPP" type="SPP_STUTTERED_ASSIGNMENT" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-11-19 05:52:18 UTC (rev 693) +++ trunk/fb-contrib/etc/messages.xml 2006-11-20 01:31:22 UTC (rev 694) @@ -1562,6 +1562,18 @@ </Details> </BugPattern> + <BugPattern type="SPP_STUTTERED_ASSIGNMENT"> + <ShortDescription>Method assigns a value to a local twice in a row</ShortDescription> + <LongDescription>Method {1} assigns a value to a local twice in a row</LongDescription> + <Details> + <![CDATA[ + <p>This method assigns a value twice in a row in a stuttered way such as + <code>a = a = 5;</code> This is most probably a cut and paste error where the duplicate + assignment can be removed.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> Modified: trunk/fb-contrib/samples/SPP_Sample.java =================================================================== --- trunk/fb-contrib/samples/SPP_Sample.java 2006-11-19 05:52:18 UTC (rev 693) +++ trunk/fb-contrib/samples/SPP_Sample.java 2006-11-20 01:31:22 UTC (rev 694) @@ -26,4 +26,9 @@ { return pi * radius * radius; } + + public void testStutter(String s) + { + String a = a = s; + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-19 05:52:18 UTC (rev 693) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-20 01:31:22 UTC (rev 694) @@ -21,6 +21,8 @@ import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.ConstantDouble; +import com.mebigfatguy.fbcontrib.utils.RegisterUtils; + import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; @@ -35,6 +37,7 @@ private BugReporter bugReporter; private OpcodeStack stack; private int lastOpcode; + private int lastReg; /** * constructs a SPP detector given the reporter to report bugs on @@ -61,6 +64,7 @@ public void visitCode(Code obj) { stack.resetForMethodEntry(this); lastOpcode = -1; + lastReg = -1; super.visitCode(obj); } @@ -70,6 +74,7 @@ * @param seen the opcode of the currently parsed instruction */ public void sawOpcode(int seen) { + int reg = -1; try { stack.mergeJumps(this); @@ -88,6 +93,16 @@ .addSourceLine(this)); } } + } else if (((seen >= ASTORE_0) && (seen < ASTORE_3)) || (seen == ASTORE)) { + reg = RegisterUtils.getAStoreReg(this, seen); + if (seen == lastOpcode) { + if (reg == lastReg) { + bugReporter.reportBug(new BugInstance(this, "SPP_STUTTERED_ASSIGNMENT", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } } else if (seen == INVOKEVIRTUAL) { String className = getClassConstantOperand(); String methodName = getNameConstantOperand(); @@ -157,6 +172,7 @@ } finally { stack.sawOpcode(this, seen); lastOpcode = seen; + lastReg = reg; } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-11-23 19:15:06
|
Revision: 695 http://svn.sourceforge.net/fb-contrib/?rev=695&view=rev Author: dbrosius Date: 2006-11-23 11:15:03 -0800 (Thu, 23 Nov 2006) Log Message: ----------- add checking nan by doing == Double.NaN Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/SPP_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-11-20 01:31:22 UTC (rev 694) +++ trunk/fb-contrib/etc/findbugs.xml 2006-11-23 19:15:03 UTC (rev 695) @@ -256,7 +256,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri" speed="fast" - reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT,SPP_STUTTERED_ASSIGNMENT"/> + reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT,SPP_STUTTERED_ASSIGNMENT,SPP_USE_ISNAN"/> <!-- BugPattern --> @@ -328,5 +328,5 @@ <BugPattern abbrev="SPP" type="SPP_NO_CHAR_SB_CTOR" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_USE_MATH_CONSTANT" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_STUTTERED_ASSIGNMENT" category="CORRECTNESS" experimental="true" /> - + <BugPattern abbrev="SPP" type="SPP_USE_ISNAN" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-11-20 01:31:22 UTC (rev 694) +++ trunk/fb-contrib/etc/messages.xml 2006-11-23 19:15:03 UTC (rev 695) @@ -1574,6 +1574,17 @@ </Details> </BugPattern> + <BugPattern type="SPP_USE_ISNAN"> + <ShortDescription>Method compares a double to Double.NAN</ShortDescription> + <LongDescription>Method {1} compares a double to Double.NAN</LongDescription> + <Details> + <![CDATA[ + <p>This method compares a douhle to the constant Double.NaN. You should use + Double.isNaN(d) if a primitive; or d.isNaN() if a boxed double, instead.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> Modified: trunk/fb-contrib/samples/SPP_Sample.java =================================================================== --- trunk/fb-contrib/samples/SPP_Sample.java 2006-11-20 01:31:22 UTC (rev 694) +++ trunk/fb-contrib/samples/SPP_Sample.java 2006-11-23 19:15:03 UTC (rev 695) @@ -31,4 +31,10 @@ { String a = a = s; } + + public void testNAN(double d) + { + if (d == Double.NaN) + System.out.println("It's a nan"); + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-20 01:31:22 UTC (rev 694) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-23 19:15:03 UTC (rev 695) @@ -93,6 +93,20 @@ .addSourceLine(this)); } } + } else if (seen == DCMPL) { + if (stack.getStackDepth() > 1) { + OpcodeStack.Item item = stack.getStackItem(0); + Double d1 = (Double)item.getConstant(); + item = stack.getStackItem(1); + Double d2 = (Double)item.getConstant(); + + if (((d1 != null) && d1.isNaN()) || ((d2 != null) && d2.isNaN())) { + bugReporter.reportBug(new BugInstance(this, "SPP_USE_ISNAN", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } } else if (((seen >= ASTORE_0) && (seen < ASTORE_3)) || (seen == ASTORE)) { reg = RegisterUtils.getAStoreReg(this, seen); if (seen == lastOpcode) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-11-23 20:08:59
|
Revision: 696 http://svn.sourceforge.net/fb-contrib/?rev=696&view=rev Author: dbrosius Date: 2006-11-23 12:08:54 -0800 (Thu, 23 Nov 2006) Log Message: ----------- add checks for BigDecimal(2.1) to SPP Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/SPP_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-11-23 19:15:03 UTC (rev 695) +++ trunk/fb-contrib/etc/findbugs.xml 2006-11-23 20:08:54 UTC (rev 696) @@ -256,7 +256,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri" speed="fast" - reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT,SPP_STUTTERED_ASSIGNMENT,SPP_USE_ISNAN"/> + reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT,SPP_STUTTERED_ASSIGNMENT,SPP_USE_ISNAN,SPP_USE_BIGDECIMAL_STRING_CTOR"/> <!-- BugPattern --> @@ -329,4 +329,5 @@ <BugPattern abbrev="SPP" type="SPP_USE_MATH_CONSTANT" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_STUTTERED_ASSIGNMENT" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_USE_ISNAN" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="SPP" type="SPP_USE_BIGDECIMAL_STRING_CTOR" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-11-23 19:15:03 UTC (rev 695) +++ trunk/fb-contrib/etc/messages.xml 2006-11-23 20:08:54 UTC (rev 696) @@ -1585,6 +1585,17 @@ </Details> </BugPattern> + <BugPattern type="SPP_USE_BIGDECIMAL_STRING_CTOR"> + <ShortDescription>Method passes double value to BigDecimal Constructor</ShortDescription> + <LongDescription>Method {1} passes double value to BigDecimal Constructor</LongDescription> + <Details> + <![CDATA[ + <p>This method calls the BigDecimal constructor that takes a double, and passes a literal double constant value. Since + the use of BigDecimal is to get better precision than double, by passing a double, you only get the precision of double number + space. To take advantage of the BigDecimal space, pass the number as a string. </p> + ]]> + </Details> + </BugPattern> <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> Modified: trunk/fb-contrib/samples/SPP_Sample.java =================================================================== --- trunk/fb-contrib/samples/SPP_Sample.java 2006-11-23 19:15:03 UTC (rev 695) +++ trunk/fb-contrib/samples/SPP_Sample.java 2006-11-23 20:08:54 UTC (rev 696) @@ -1,3 +1,4 @@ +import java.math.BigDecimal; import java.util.BitSet; public class SPP_Sample @@ -37,4 +38,9 @@ if (d == Double.NaN) System.out.println("It's a nan"); } + + public void testBigDecimal() + { + BigDecimal d = new BigDecimal(2.1); + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-23 19:15:03 UTC (rev 695) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2006-11-23 20:08:54 UTC (rev 696) @@ -180,6 +180,18 @@ } } } + } else if ("java/math/BigDecimal".equals(className)) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item item = stack.getStackItem(0); + Object constant = item.getConstant(); + if (constant instanceof Double) + { + bugReporter.reportBug(new BugInstance(this, "SPP_USE_BIGDECIMAL_STRING_CTOR", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-12-03 09:52:28
|
Revision: 699 http://svn.sourceforge.net/fb-contrib/?rev=699&view=rev Author: dbrosius Date: 2006-12-03 01:52:26 -0800 (Sun, 03 Dec 2006) Log Message: ----------- BAS starts to hobble along Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/BAS_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-11-30 06:05:35 UTC (rev 698) +++ trunk/fb-contrib/etc/findbugs.xml 2006-12-03 09:52:26 UTC (rev 699) @@ -257,7 +257,10 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri" speed="fast" reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT,SPP_STUTTERED_ASSIGNMENT,SPP_USE_ISNAN,SPP_USE_BIGDECIMAL_STRING_CTOR"/> - + + <Detector class="com.mebigfatguy.fbcontrib.detect.BloatedAssignmentScope" + speed="fast" + reports="BAS_BLOATED_ASSIGNMENT_SCOPE" /> <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -330,4 +333,5 @@ <BugPattern abbrev="SPP" type="SPP_STUTTERED_ASSIGNMENT" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_USE_ISNAN" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_USE_BIGDECIMAL_STRING_CTOR" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="BAS" type="BAS_BLOATED_ASSIGNMENT_SCOPE" category="PERFORMANCE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-11-30 06:05:35 UTC (rev 698) +++ trunk/fb-contrib/etc/messages.xml 2006-12-03 09:52:26 UTC (rev 699) @@ -693,6 +693,15 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.BloatedAssignmentScope"> + <Details> + <![CDATA[ + <p>looks for assignments to variables in a scope larger than it's use. As long as the evaluation of the assignment + does not have side effects, the assignment can be moved into the inner scope where it is used.</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1596,6 +1605,19 @@ ]]> </Details> </BugPattern> + + <BugPattern type="BAS_BLOATED_ASSIGNMENT_SCOPE"> + <ShortDescription>Method assigns a variable in a larger scope then is needed</ShortDescription> + <LongDescription>Method {1} assigns a variable in a larger scope then is needed</LongDescription> + <Details> + <![CDATA[ + <p>This method assigns a value to a variable in an outer scope compared to where the variable is actually used. + Assuming this evaluation does not have side effects, the assignment can be moved into the inner scope (if block) + so that its execution time isn't taken up if the if guard is false.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1655,5 +1677,6 @@ <BugCode abbrev="PIS">Possible Incomplete Serialization</BugCode> <BugCode abbrev="SCRV">Suspicious Comparator Return Values</BugCode> <BugCode abbrev="SPP">Sillyness Pot Pourri</BugCode> + <BugCode abbrev="BAS">Bloated Assignment Scope</BugCode> </MessageCollection> \ No newline at end of file Modified: trunk/fb-contrib/samples/BAS_Sample.java =================================================================== --- trunk/fb-contrib/samples/BAS_Sample.java 2006-11-30 06:05:35 UTC (rev 698) +++ trunk/fb-contrib/samples/BAS_Sample.java 2006-12-03 09:52:26 UTC (rev 699) @@ -20,5 +20,30 @@ } return s; } + + public String testFP2Scopes(String s) + { + Object o = new Object(); + if (s.equals("Boo")) + s = o.toString(); + else if (s.equals("Hoo")) + s = o.toString(); + + return s; + } + + public String test2InnerScopes(String s) + { + Object o = new Object(); + if (s != null) + { + if (s.equals("Boo")) + s = o.toString(); + else if (s.equals("Hoo")) + s = o.toString(); + } + + return s; + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2006-11-30 06:05:35 UTC (rev 698) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2006-12-03 09:52:26 UTC (rev 699) @@ -1,12 +1,18 @@ package com.mebigfatguy.fbcontrib.detect; +import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.Method; import com.mebigfatguy.fbcontrib.utils.RegisterUtils; +import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; import edu.umd.cs.findbugs.ba.ClassContext; @@ -18,19 +24,20 @@ */ public class BloatedAssignmentScope extends BytecodeScanningDetector { - private BugReporter bugReporter; + BugReporter bugReporter; private Map<Integer, Integer> regToLocationMap; - private Map<Integer, Integer> scopeBlockMap; + private Set<Integer> ignoreRegs; + private ScopeBlock rootScopeBlock; /** - * constructs a BLT detector given the reporter to report bugs on + * constructs a BAS detector given the reporter to report bugs on * @param bugReporter the sync of bug reports */ public BloatedAssignmentScope(BugReporter bugReporter) { this.bugReporter = bugReporter; } - + /** * implements the visitor to create and the clear the register to location map * @@ -40,11 +47,11 @@ public void visitClassContext(ClassContext classContext) { try { regToLocationMap = new HashMap<Integer, Integer>(); - scopeBlockMap = new HashMap<Integer, Integer>(); + ignoreRegs = new HashSet<Integer>(); super.visitClassContext(classContext); } finally { regToLocationMap = null; - scopeBlockMap = null; + ignoreRegs = null; } } @@ -55,23 +62,282 @@ */ @Override public void visitCode(Code obj) { - regToLocationMap.clear(); - scopeBlockMap.clear(); - super.visitCode(obj); + try { + + regToLocationMap.clear(); + ignoreRegs.clear(); + Method method = getMethod(); + if (!method.isStatic()) + ignoreRegs.add(Integer.valueOf(0)); + + int[] parmRegs = RegisterUtils.getParameterRegisters(method); + for (int parm : parmRegs) { + ignoreRegs.add(Integer.valueOf(parm)); + } + + rootScopeBlock = new ScopeBlock(0, obj.getLength()); + super.visitCode(obj); + + rootScopeBlock.findBugs(); + + } finally { + rootScopeBlock = null; + } } - + /** - * implements the visitor to look for variables assigned out side of the scope + * 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 */ @Override public void sawOpcode(int seen) { - if ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3))) { - int reg = RegisterUtils.getAStoreReg(this, seen); - } else if ((seen == ALOAD) || ((seen >= ALOAD_0) && (seen <= ALOAD_3))) { - int reg = RegisterUtils.getALoadReg(this, seen); + if ((seen == ASTORE) + || (seen == ISTORE) + || (seen == LSTORE) + || (seen == FSTORE) + || (seen == DSTORE) + || ((seen >= ASTORE_0) && (seen <= ASTORE_3)) + || ((seen >= ISTORE_0) && (seen <= ISTORE_3)) + || ((seen >= LSTORE_0) && (seen <= LSTORE_1)) + || ((seen >= FSTORE_0) && (seen <= FSTORE_1)) + || ((seen >= DSTORE_0) && (seen <= DSTORE_1))) { + int reg = RegisterUtils.getStoreReg(this, seen); + if (!ignoreRegs.contains(Integer.valueOf(reg))) { + ScopeBlock sb = findScopeBlock(rootScopeBlock, getPC()); + if (sb != null) + sb.addStore(reg, getPC()); + else + ignoreRegs.add(Integer.valueOf(reg)); + } + + } else if ((seen == ALOAD) + || (seen == ILOAD) + || (seen == LLOAD) + || (seen == FLOAD) + || (seen == DLOAD) + || ((seen >= ALOAD_0) && (seen <= ALOAD_3)) + || ((seen >= ILOAD_0) && (seen <= ILOAD_3)) + || ((seen >= LLOAD_0) && (seen <= LLOAD_1)) + || ((seen >= FLOAD_0) && (seen <= FLOAD_1)) + || ((seen >= DLOAD_0) && (seen <= DLOAD_1))) { + int reg = RegisterUtils.getLoadReg(this, seen); + if (!ignoreRegs.contains(Integer.valueOf(reg))) { + ScopeBlock sb = findScopeBlock(rootScopeBlock, getPC()); + if (sb != null) + sb.addLoad(reg, getPC()); + else + ignoreRegs.add(Integer.valueOf(reg)); + } + } else if (((seen >= IFEQ) && (seen <= GOTO)) || (seen == GOTO_W)) { + int target = getBranchTarget(); + if (target > getPC()) { + ScopeBlock sb = new ScopeBlock(getPC(), target); + rootScopeBlock.addChild(sb); + } else { + ScopeBlock sb = findScopeBlock(rootScopeBlock, getPC()); + if (sb != null) + sb.setLoop(); + } } } + + /** + * 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 the current program counter + * @return the scope block or null if not found + */ + private ScopeBlock findScopeBlock(ScopeBlock sb, int pc) { + + if ((pc > sb.getStart()) && (pc < sb.getFinish())) { + if (sb.children != null) { + for (ScopeBlock child : sb.children) { + sb = findScopeBlock(child, pc); + if (sb != null) + return sb; + } + } + return sb; + } + return null; + } + + /** holds the description of a scope { } block, be it a for, if, while block + */ + private class ScopeBlock + { + private int startLocation; + private int finishLocation; + private boolean isLoop; + private Map<Integer, Integer> loads; + private Map<Integer, Integer> stores; + private List<ScopeBlock> children; + + /** construts a new scope block + * + * @param start the beginning of the block + * @param finish the end of the block + */ + public ScopeBlock(int start, int finish) { + startLocation = start; + finishLocation = finish; + isLoop = false; + loads = null; + stores = null; + children = null; + } + + /** + * returns a string representation of the scope block + * + * @returns a string representation + */ + public String toString() { + return "Start=" + startLocation + " Finish=" + finishLocation + " Loop=" + isLoop + " Loads=" + loads + " Stores=" + stores; + } + + /** returns the start of the block + * + * @return the start of the block + */ + public int getStart() { + return startLocation; + } + + /** returns the end of the block + * + * @return the end of the block + */ + public int getFinish() { + return finishLocation; + } + + /** + * sets that this block is a loop + */ + public void setLoop() { + isLoop = true; + } + + /** + * adds the register as a store in this scope block + * + * @param reg the register that was stored + * @param pc the instruction that did the store + */ + public void addStore(int reg, int pc) { + if (stores == null) + stores = new HashMap<Integer, Integer>(); + + stores.put(Integer.valueOf(reg), Integer.valueOf(pc)); + } + + /** + * adds the register as a load in this scope block + * + * @param reg the register that was loaded + * @param pc the instruction that did the load + */ + public void addLoad(int reg, int pc) { + if (loads == null) + loads = new HashMap<Integer, Integer>(); + + loads.put(Integer.valueOf(reg), Integer.valueOf(pc)); + } + + /** + * adds a scope block to this subtree by finding the correct place in the hierarchy to store it + * + * @param child the scope block to add to the tree + */ + public void addChild(ScopeBlock newChild) { + if (children != null) { + for (ScopeBlock child : children) { + if ((newChild.startLocation > child.startLocation) && (newChild.finishLocation < child.finishLocation)) { + child.addChild(newChild); + return; + } + } + int pos = 0; + for (ScopeBlock child : children) { + if (newChild.startLocation < child.startLocation) { + children.add(pos, newChild); + return; + } + pos++; + } + children.add(newChild); + return; + } + children = new ArrayList<ScopeBlock>(); + children.add(newChild); + } + + /** + * report stores that occur at scopes higher than associated loads that are not involved with loops + */ + public void findBugs() { + if (isLoop) + return; + + if (stores != null) { + if (loads != null) + stores.keySet().removeAll(loads.keySet()); + + if (children != null) { + for (Map.Entry<Integer, Integer> entry : stores.entrySet()) { + int childUseCount = 0; + boolean inLoop = false; + for (ScopeBlock child : children) { + if (child.usesReg(entry.getKey())) { + if (child.isLoop) { + inLoop = true; + break; + } + childUseCount++; + } + } + if ((!inLoop) && (childUseCount == 1)) { + bugReporter.reportBug(new BugInstance(BloatedAssignmentScope.this, "BAS_BLOATED_ASSIGNMENT_SCOPE", NORMAL_PRIORITY) + .addClass(BloatedAssignmentScope.this) + .addMethod(BloatedAssignmentScope.this) + .addSourceLine(BloatedAssignmentScope.this, entry.getValue())); + } + } + } + } + + if (children != null) { + for (ScopeBlock child : children) { + child.findBugs(); + } + } + } + + /** + * 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) { + if ((loads != null) && (loads.containsKey(reg))) + return true; + if ((stores != null) && (stores.containsKey(reg))) + return true; + + if (children != null) { + for (ScopeBlock child : children) { + if (child.usesReg(reg)) + return true; + } + } + + return false; + } + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |