Class FindImproperSynchronization

All Implemented Interfaces:
Detector, Priorities, org.apache.bcel.classfile.Visitor

public class FindImproperSynchronization extends OpcodeStackDetector
  • Field Details

  • Constructor Details

    • FindImproperSynchronization

      public FindImproperSynchronization(BugReporter bugReporter)
  • Method Details

    • isWrapperImplementation

      private static boolean isWrapperImplementation(MethodDescriptor methodDescriptor)
    • getStackOffset

      private static Integer getStackOffset(MethodDescriptor methodDescriptor)
    • isImmutableReturner

      private static boolean isImmutableReturner(String signature)
    • visit

      public void visit(org.apache.bcel.classfile.Method obj)
      Overrides:
      visit in class BetterVisitor
    • visit

      public void visit(org.apache.bcel.classfile.Field obj)
      Overrides:
      visit in class BetterVisitor
    • sawOpcode

      public void sawOpcode(int seen)
      Description copied from class: OpcodeStackDetector

      By default, this method will not be called when stack is TOP. To change this behavior, override #beforeOpcode(int) and change to return true even if stack is TOP.

      see Using FindBugs for Research to learn lattice and what TOP means.

      Specified by:
      sawOpcode in class OpcodeStackDetector
      See Also:
    • visitAfter

      public void visitAfter(org.apache.bcel.classfile.JavaClass obj)
      Overrides:
      visitAfter in class PreorderVisitor
    • isCollection

      private boolean isCollection(org.apache.bcel.generic.Type type)
    • isCollection

      private boolean isCollection(XField field)
    • isMethodCall

      private boolean isMethodCall(org.apache.bcel.generic.Instruction instruction)
    • isPackagePrivate

      private boolean isPackagePrivate(XField field)
    • isInitializerMethod

      private boolean isInitializerMethod(String methodName)
    • isInherited

      private boolean isInherited(XField lockObject)
      Check if the lock object is inherited from the current class. To ensure no false positives, we compare only the outer class name if the lock object is contained in an inner class. Only checking equality is enough, since the lock object is a field declared in a class. That means if the declaring class of the lock object is the same as the current class, the lock object is not inherited.
      Parameters:
      lockObject - the lock object to check for inheritance
      Returns:
      true if the lock object is inherited from the current class, false otherwise
    • analyzeWrappedField

      private void analyzeWrappedField(org.apache.bcel.classfile.Method currentMethod, ClassContext classContext, Location location, org.apache.bcel.generic.InstructionHandle handle, XField assignedField, Integer stackOffsetForWrapperMethodParameter)
      Analyze a wrapping method call and check if this the creation of a binding collection. There are specific methods that use their parameters to create a new collections, but they maintain a reference to the original collection. When a collection is wrapped by such a method and the result is assigned to a field, the wrapped collections becomes a backing collection.
      Parameters:
      currentMethod - the method in which the wrapping method call is located
      classContext - the class context of the currently analyzed class, in which the wrapping method call is located
      location - the location of the wrapping method call
      handle - the instruction handle of the wrapping method call
      assignedField - the field to which the result of the wrapping method call is assigned
      stackOffsetForWrapperMethodParameter - the stack offset of the wrapped collection parameter of the wrapping method call
    • analyzeAssignments

      private void analyzeAssignments(org.apache.bcel.classfile.Method obj, ClassContext classContext) throws CFGBuilderException
      Throws:
      CFGBuilderException
    • analyzeAssignments

      private void analyzeAssignments(org.apache.bcel.classfile.Method obj, ClassContext classContext, XField specificField) throws CFGBuilderException
      Throws:
      CFGBuilderException
    • analyzeAssignmentsInHierarchy

      private void analyzeAssignmentsInHierarchy(XField collectionLockObject)
    • checkLockUsageInHierarchy

      private void checkLockUsageInHierarchy(XField field, XMethod exposingMethod)
    • findExposureInHierarchy

      private Set<XMethod> findExposureInHierarchy(XField lockObject) throws ClassNotFoundException
      Throws:
      ClassNotFoundException
    • findLockUsageInHierarchy

      private Set<XMethod> findLockUsageInHierarchy(XField field) throws ClassNotFoundException
      Throws:
      ClassNotFoundException
    • buildMethodsMessage

      private String buildMethodsMessage(Collection<XMethod> methods)
    • reportExposingLockObjectBugs

      private void reportExposingLockObjectBugs(XField lock, Collection<XMethod> lockUsingMethods, Collection<XMethod> exposingMethods)
    • reportAccessibleObjectBug

      private void reportAccessibleObjectBug(XField lock, Collection<XMethod> definedLockAccessors, Map<XField,XMethod> synchronizedMethods)
    • reportInheritedObjectBugs

      private void reportInheritedObjectBugs(XField lock, Collection<XMethod> synchronizedMethods)
    • reportObjectBugs

      private void reportObjectBugs(XField lock, Collection<XMethod> synchronizedMethods)
    • reportAccessibleBackingCollectionBug

      private void reportAccessibleBackingCollectionBug(XField lock, MultiMap<XField, FindImproperSynchronization.BugInfo> possibleBugs, XField backingCollection, MultiMap<XField,XMethod> collectionAccessors)
    • reportInheritedBackingCollectionBug

      private void reportInheritedBackingCollectionBug(XField lock, MultiMap<XField, FindImproperSynchronization.BugInfo> possibleBugs, XField backingCollection)
    • reportBadCollectionObjectBugs

      private void reportBadCollectionObjectBugs(XField lock, MultiMap<XField, FindImproperSynchronization.BugInfo> possibleBugs, XField backingCollection)
    • clearState

      private void clearState()