Package com.mebigfatguy.fbcontrib.detect
Class DeletingWhileIterating
java.lang.Object
edu.umd.cs.findbugs.visitclass.BetterVisitor
edu.umd.cs.findbugs.visitclass.PreorderVisitor
edu.umd.cs.findbugs.visitclass.AnnotationVisitor
edu.umd.cs.findbugs.visitclass.DismantleBytecode
edu.umd.cs.findbugs.BytecodeScanningDetector
com.mebigfatguy.fbcontrib.detect.AbstractCollectionScanningDetector
com.mebigfatguy.fbcontrib.detect.DeletingWhileIterating
- All Implemented Interfaces:
edu.umd.cs.findbugs.Detector,edu.umd.cs.findbugs.Priorities,org.apache.bcel.classfile.Visitor
looks for deletion of items from a collection using the remove method of the
collection at the same time that the collection is being iterated on. If this
occurs the iterator will become invalid and throw a
ConcurrentModificationException. Instead, the remove should be called on the
iterator itself.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static classrepresents aliases of some kind to some sort of a collection, or a related object like a keySet, or an iterator(package private) static classrepresents a simple loop -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate List<DeletingWhileIterating.GroupPair> private static Set<org.apache.bcel.classfile.JavaClass> private static final QMethodprivate static final QMethodprivate static org.apache.bcel.classfile.JavaClassprivate Map<Integer, DeletingWhileIterating.Loop> private static final QMethodFields inherited from class com.mebigfatguy.fbcontrib.detect.AbstractCollectionScanningDetector
bugReporter, collectionClass, stackFields inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode
codeBytes, lineNumberTable, M_BR, M_CP, M_INT, M_PAD, M_R, M_UINTFields inherited from interface edu.umd.cs.findbugs.Priorities
EXP_PRIORITY, HIGH_PRIORITY, IGNORE_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY -
Constructor Summary
ConstructorsConstructorDescriptionDeletingWhileIterating(edu.umd.cs.findbugs.BugReporter bugReporter) constructs a DWI detector given the reporter to report bugs on -
Method Summary
Modifier and TypeMethodDescriptionprivate booleanbreakFollows(DeletingWhileIterating.Loop loop, boolean needsPop) looks to see if the following instruction is a GOTO, preceded by potentially a popprivate voidprivate intfindCollectionGroup(edu.umd.cs.findbugs.OpcodeStack.Item itm, boolean addIfNotFound) private static Comparable<?> getGroupElement(edu.umd.cs.findbugs.OpcodeStack.Item itm) given an register or field, look to see if this thing is associated with an already discovered loopprivate booleanisCollection(String className) returns whether the class name is derived from java.util.Collectionprivate voidprivate voidremoveFromCollectionGroup(edu.umd.cs.findbugs.OpcodeStack.Item itm) private booleanreturnFollows(boolean couldSeePop) This attempts to see if there is some form of a return statement following the collection modifying statement in the loop.voidsawOpcode(int seen) implements the visitor to look for deletes on collections that are being iteratedvoidvisitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext) implements the visitor to setup the opcode stack, collectionGroups, groupToIterator and loopsvoidvisitCode(org.apache.bcel.classfile.Code obj) implements the visitor to reset the stack, collectionGroups, groupToIterator and loopsMethods inherited from class com.mebigfatguy.fbcontrib.detect.AbstractCollectionScanningDetector
isLocalCollectionMethods inherited from class edu.umd.cs.findbugs.BytecodeScanningDetector
getClassContext, report, shouldVisitCodeMethods inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode
afterOpcode, areOppositeBranches, atCatchBlock, beforeOpcode, getBranchFallThrough, getBranchOffset, getBranchTarget, getClassConstantOperand, getClassDescriptorOperand, getCodeByte, getConstantRefOperand, getDefaultSwitchOffset, getDottedClassConstantOperand, getFieldDescriptorOperand, getIntConstant, getLongConstant, getMaxPC, getMethodDescriptorOperand, getNameConstantOperand, getNextCodeByte, getNextOpcode, getNextPC, getOpcode, getPC, getPrevOpcode, getRefConstantOperand, getRefFieldIsStatic, getRegisterOperand, getSigConstantOperand, getStringConstantOperand, getSwitchLabels, getSwitchOffsets, getXClassOperand, getXFieldOperand, getXMethodOperand, isBranch, isMethodCall, isRegisterLoad, isRegisterStore, isRegisterStore, isReturn, isShift, isSwitch, isWideOpcode, printOpCode, sawBranchTo, sawClass, sawDouble, sawField, sawFloat, sawIMethod, sawInt, sawLong, sawMethod, sawRegister, sawString, visitMethods inherited from class edu.umd.cs.findbugs.visitclass.AnnotationVisitor
getAnnotationParameterAsEnum, getAnnotationParameterAsString, getAnnotationParameterAsStringArray, visitAnnotation, visitAnnotation, visitParameterAnnotation, visitParameterAnnotation, visitSyntheticParameterAnnotationMethods inherited from class edu.umd.cs.findbugs.visitclass.PreorderVisitor
amVisitingMainMethod, asUnsignedByte, doVisitMethod, getClassDescriptor, getClassName, getCode, getConstantPool, getDottedClassName, getDottedFieldSig, getDottedMethodSig, getDottedSuperclassName, getField, getFieldDescriptor, getFieldIsStatic, getFieldName, getFieldSig, getFullyQualifiedFieldName, getFullyQualifiedMethodName, getMethod, getMethodDescriptor, getMethodName, getMethodSig, getMethodVisitOrder, getNumberArguments, getNumberMethodArguments, getPackageName, getSizeOfSurroundingTryBlock, getSizeOfSurroundingTryBlock, getSourceFile, getStringFromIndex, getSuperclassName, getSurroundingCaughtExceptions, getSurroundingCaughtExceptions, getSurroundingCaughtExceptionTypes, getSurroundingTryBlock, getSurroundingTryBlock, getThisClass, getXClass, getXField, getXMethod, hasInterestingClass, hasInterestingMethod, isVisitMethodsInCallOrder, setupVisitorForClass, setVisitMethodsInCallOrder, shouldVisit, toString, visitAfter, visitAfter, visitAnnotationDefault, visitAnnotationEntry, visitBootstrapMethods, visitConstantInvokeDynamic, visitConstantMethodHandle, visitConstantMethodType, visitConstantModule, visitConstantPackage, visitConstantPool, visitEnclosingMethod, visitingField, visitingMethod, visitInnerClasses, visitJavaClass, visitLineNumberTable, visitLocalVariableTable, visitMethodParameters, visitParameterAnnotationEntry, visitStackMap, visitStackMapEntryMethods inherited from class edu.umd.cs.findbugs.visitclass.BetterVisitor
clone, report, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visitCodeException, visitConstantClass, visitConstantDouble, visitConstantFieldref, visitConstantFloat, visitConstantInteger, visitConstantInterfaceMethodref, visitConstantLong, visitConstantMethodref, visitConstantNameAndType, visitConstantString, visitConstantUtf8, visitConstantValue, visitDeprecated, visitExceptionTable, visitField, visitInnerClass, visitLineNumber, visitLocalVariable, visitLocalVariableTypeTable, visitMethod, visitSignature, visitSourceFile, visitSynthetic, visitUnknownMethods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.apache.bcel.classfile.Visitor
visitConstantDynamic, visitMethodParameter, visitModule, visitModuleExports, visitModuleMainClass, visitModuleOpens, visitModulePackages, visitModuleProvides, visitModuleRequires, visitNestHost, visitNestMembers, visitRecord, visitRecordComponent, visitStackMapType
-
Field Details
-
iteratorClass
private static org.apache.bcel.classfile.JavaClass iteratorClass -
exceptionClasses
-
collectionMethods
-
modifyingMethods
-
ITERATOR
-
REMOVE
-
HASNEXT
-
collectionGroups
-
groupToIterator
-
loops
-
endOfScopes
-
-
Constructor Details
-
DeletingWhileIterating
public DeletingWhileIterating(edu.umd.cs.findbugs.BugReporter bugReporter) constructs a DWI detector given the reporter to report bugs on- Parameters:
bugReporter- the sync of bug reports
-
-
Method Details
-
visitClassContext
public void visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext) implements the visitor to setup the opcode stack, collectionGroups, groupToIterator and loops- Specified by:
visitClassContextin interfaceedu.umd.cs.findbugs.Detector- Overrides:
visitClassContextin classAbstractCollectionScanningDetector- Parameters:
classContext- the context object of the currently parsed class
-
visitCode
public void visitCode(org.apache.bcel.classfile.Code obj) implements the visitor to reset the stack, collectionGroups, groupToIterator and loops- Specified by:
visitCodein interfaceorg.apache.bcel.classfile.Visitor- Overrides:
visitCodein classAbstractCollectionScanningDetector- Parameters:
obj- the context object of the currently parsed code block
-
sawOpcode
public void sawOpcode(int seen) implements the visitor to look for deletes on collections that are being iterated- Overrides:
sawOpcodein classedu.umd.cs.findbugs.visitclass.DismantleBytecode- Parameters:
seen- the opcode of the currently parsed instruction
-
breakFollows
looks to see if the following instruction is a GOTO, preceded by potentially a pop- Parameters:
loop- the loop structure we are checkingneedsPop- whether we expect to see a pop next- Returns:
- whether a GOTO is found
-
returnFollows
private boolean returnFollows(boolean couldSeePop) This attempts to see if there is some form of a return statement following the collection modifying statement in the loop. It is a bad cheat, because, we may allow a POP, or an ALOAD/ILOAD etc before the return. this is sloppy tho as it might be a multibyte instruction. It also might be a complex piece of code to load the return, or the method may not allow returns. But hopefully it's better than it was.- Parameters:
couldSeePop- if the preceding instruction returns a value, and thus might need to be popped- Returns:
- when a following instruction issues some sort of return
-
isCollection
returns whether the class name is derived from java.util.Collection- Parameters:
className- the class to check- Returns:
- whether the class is a collection
-
getGroupElement
given an register or field, look to see if this thing is associated with an already discovered loop- Parameters:
itm- the item containing the register or field- Returns:
- the group element
-
findCollectionGroup
private int findCollectionGroup(edu.umd.cs.findbugs.OpcodeStack.Item itm, boolean addIfNotFound) -
removeFromCollectionGroup
private void removeFromCollectionGroup(edu.umd.cs.findbugs.OpcodeStack.Item itm) -
buildVariableEndScopeMap
private void buildVariableEndScopeMap() -
processEndOfScopes
-