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

@CustomUserValue public class DeletingWhileIterating extends AbstractCollectionScanningDetector
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 Classes
    Modifier and Type
    Class
    Description
    (package private) static class 
    represents aliases of some kind to some sort of a collection, or a related object like a keySet, or an iterator
    (package private) static class 
    represents a simple loop
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
     
    private static final Set<QMethod>
     
    private Map<Integer,BitSet>
     
    private static Set<org.apache.bcel.classfile.JavaClass>
     
     
    private static final QMethod
     
    private static final QMethod
     
    private static org.apache.bcel.classfile.JavaClass
     
     
    private static final Map<QMethod,Integer>
     
    private static final QMethod
     

    Fields inherited from class com.mebigfatguy.fbcontrib.detect.AbstractCollectionScanningDetector

    bugReporter, collectionClass, stack

    Fields inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode

    codeBytes, lineNumberTable, M_BR, M_CP, M_INT, M_PAD, M_R, M_UINT

    Fields inherited from interface edu.umd.cs.findbugs.Priorities

    EXP_PRIORITY, HIGH_PRIORITY, IGNORE_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY
  • Constructor Summary

    Constructors
    Constructor
    Description
    DeletingWhileIterating(edu.umd.cs.findbugs.BugReporter bugReporter)
    constructs a DWI detector given the reporter to report bugs on
  • Method Summary

    Modifier and Type
    Method
    Description
    private boolean
    breakFollows(DeletingWhileIterating.Loop loop, boolean needsPop)
    looks to see if the following instruction is a GOTO, preceded by potentially a pop
    private void
     
    private int
    findCollectionGroup(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 loop
    private boolean
    isCollection(String className)
    returns whether the class name is derived from java.util.Collection
    private void
     
    private void
    removeFromCollectionGroup(edu.umd.cs.findbugs.OpcodeStack.Item itm)
     
    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.
    void
    sawOpcode(int seen)
    implements the visitor to look for deletes on collections that are being iterated
    void
    visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext)
    implements the visitor to setup the opcode stack, collectionGroups, groupToIterator and loops
    void
    visitCode(org.apache.bcel.classfile.Code obj)
    implements the visitor to reset the stack, collectionGroups, groupToIterator and loops

    Methods inherited from class com.mebigfatguy.fbcontrib.detect.AbstractCollectionScanningDetector

    isLocalCollection

    Methods inherited from class edu.umd.cs.findbugs.BytecodeScanningDetector

    getClassContext, report, shouldVisitCode

    Methods 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, visit

    Methods inherited from class edu.umd.cs.findbugs.visitclass.AnnotationVisitor

    getAnnotationParameterAsEnum, getAnnotationParameterAsString, getAnnotationParameterAsStringArray, visitAnnotation, visitAnnotation, visitParameterAnnotation, visitParameterAnnotation, visitSyntheticParameterAnnotation

    Methods 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, visitStackMapEntry

    Methods 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, visitUnknown

    Methods inherited from class java.lang.Object

    equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

    Methods inherited from interface org.apache.bcel.classfile.Visitor

    visitConstantDynamic, visitMethodParameter, visitModule, visitModuleExports, visitModuleMainClass, visitModuleOpens, visitModulePackages, visitModuleProvides, visitModuleRequires, visitNestHost, visitNestMembers, visitRecord, visitRecordComponent, visitStackMapType
  • Field Details

  • 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:
      visitClassContext in interface edu.umd.cs.findbugs.Detector
      Overrides:
      visitClassContext in class AbstractCollectionScanningDetector
      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:
      visitCode in interface org.apache.bcel.classfile.Visitor
      Overrides:
      visitCode in class AbstractCollectionScanningDetector
      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:
      sawOpcode in class edu.umd.cs.findbugs.visitclass.DismantleBytecode
      Parameters:
      seen - the opcode of the currently parsed instruction
    • breakFollows

      private boolean breakFollows(DeletingWhileIterating.Loop loop, boolean needsPop)
      looks to see if the following instruction is a GOTO, preceded by potentially a pop
      Parameters:
      loop - the loop structure we are checking
      needsPop - 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

      private boolean isCollection(@SlashedClassName String className)
      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

      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 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

      private void processEndOfScopes(Integer pc)