Class FindRefComparison

java.lang.Object
edu.umd.cs.findbugs.detect.FindRefComparison
All Implemented Interfaces:
ExtendedTypes, Detector, Priorities

public class FindRefComparison extends Object implements Detector, ExtendedTypes
Find suspicious reference comparisons. This includes:
  • Strings and other java.lang objects compared by reference equality
  • Calls to equals(Object) where the argument is a different type than the receiver object
  • Field Details

    • DEBUG

      private static final boolean DEBUG
    • BASE_ES_PRIORITY

      private static final int BASE_ES_PRIORITY
    • DEFAULT_SUSPICIOUS_SET

      @StaticConstant private static final Set<String> DEFAULT_SUSPICIOUS_SET
      Classes that are suspicious if compared by reference.
    • invokeInstanceSet

      private static final BitSet invokeInstanceSet
      Set of opcodes that invoke instance methods on an object.
    • prescreenSet

      private static final BitSet prescreenSet
      Set of bytecodes using for prescreening.
    • T_DYNAMIC_STRING

      private static final byte T_DYNAMIC_STRING
      See Also:
    • T_STATIC_STRING

      private static final byte T_STATIC_STRING
      See Also:
    • T_PARAMETER_STRING

      private static final byte T_PARAMETER_STRING
      See Also:
    • STRING_SIGNATURE

      private static final String STRING_SIGNATURE
      See Also:
    • dynamicStringTypeInstance

      private static final org.apache.bcel.generic.Type dynamicStringTypeInstance
    • staticStringTypeInstance

      private static final org.apache.bcel.generic.Type staticStringTypeInstance
    • emptyStringTypeInstance

      private static final org.apache.bcel.generic.Type emptyStringTypeInstance
    • parameterStringTypeInstance

      private static final org.apache.bcel.generic.Type parameterStringTypeInstance
    • bugReporter

      private final BugReporter bugReporter
    • bugAccumulator

      private final BugAccumulator bugAccumulator
    • classContext

      private ClassContext classContext
    • suspiciousSet

      private final Set<String> suspiciousSet
    • testingEnabled

      private final boolean testingEnabled
    • comparedForEqualityInThisMethod

      private Map<String,Integer> comparedForEqualityInThisMethod
  • Constructor Details

    • FindRefComparison

      public FindRefComparison(BugReporter bugReporter)
  • Method Details

    • reportAllRefComparisons

      private boolean reportAllRefComparisons()
    • visitClassContext

      public void visitClassContext(ClassContext classContext)
      Description copied from interface: Detector
      Visit the ClassContext for a class which should be analyzed for instances of bug patterns.
      Specified by:
      visitClassContext in interface Detector
      Parameters:
      classContext - the ClassContext
    • isLombokWithMethod

      private boolean isLombokWithMethod(org.apache.bcel.classfile.Method method)
      Lombok's "with" methods include an == comparison reported as RC_REF_COMPARISON.
      Returns:
      true if the method is generated with Lombok's @With annotation
    • analyzeMethod

      private void analyzeMethod(ClassContext classContext, org.apache.bcel.classfile.Method method) throws CFGBuilderException, DataflowAnalysisException
      Throws:
      CFGBuilderException
      DataflowAnalysisException
    • mightBeLaterCheckedUsingEquals

      boolean mightBeLaterCheckedUsingEquals(FindRefComparison.WarningWithProperties warning)
    • inspectLocation

      private void inspectLocation(org.apache.bcel.classfile.JavaClass jclass, org.apache.bcel.generic.ConstantPoolGen cpg, org.apache.bcel.classfile.Method method, org.apache.bcel.generic.MethodGen methodGen, LinkedList<FindRefComparison.WarningWithProperties> refComparisonList, LinkedList<FindRefComparison.WarningWithProperties> stringComparisonList, FindRefComparison.RefComparisonTypeFrameModelingVisitor visitor, TypeDataflow typeDataflow, Location location) throws DataflowAnalysisException
      Throws:
      DataflowAnalysisException
    • decorateWarnings

      private void decorateWarnings(LinkedList<FindRefComparison.WarningWithProperties> stringComparisonList, FindRefComparison.WarningDecorator warningDecorator)
    • reportBest

      private void reportBest(ClassContext classContext, org.apache.bcel.classfile.Method method, LinkedList<FindRefComparison.WarningWithProperties> warningList, boolean relaxed)
    • isComparisonInsideEqualsMethod

      private static boolean isComparisonInsideEqualsMethod(org.apache.bcel.classfile.JavaClass jClass, org.apache.bcel.classfile.Method method, org.apache.bcel.generic.Type lhsType, org.apache.bcel.generic.Type rhsType)
      Identifies if it's a comparison of two instances of the class inside its equals method or if it's a comparison of the class with Object. This should be OK as this is usually an optimization inside the equals method.
      Parameters:
      jClass - : the class where this check is running on
      method - : the method where the comparison is happening
      lhsType - : the type of the left hand side of the comparison
      rhsType - : the type of the right hand side of the comparison
      Returns:
      whether it's an acceptable comparison inside the equals method
    • checkRefComparison

      private void checkRefComparison(Location location, org.apache.bcel.classfile.JavaClass jclass, org.apache.bcel.classfile.Method method, org.apache.bcel.generic.MethodGen methodGen, FindRefComparison.RefComparisonTypeFrameModelingVisitor visitor, TypeDataflow typeDataflow, List<FindRefComparison.WarningWithProperties> stringComparisonList, List<FindRefComparison.WarningWithProperties> refComparisonList) throws DataflowAnalysisException
      Throws:
      DataflowAnalysisException
    • comparingEnumsSameType

      private static boolean comparingEnumsSameType(org.apache.bcel.generic.Type lhsType, org.apache.bcel.generic.Type rhsType)
    • resolveJavaClass

      private static org.apache.bcel.classfile.JavaClass resolveJavaClass(org.apache.bcel.generic.Type type)
    • comparingClasses

      private static boolean comparingClasses(org.apache.bcel.generic.Type lhsType, org.apache.bcel.generic.Type rhsType)
    • isClassType

      private static boolean isClassType(org.apache.bcel.generic.Type type)
    • handleStringComparison

      private void handleStringComparison(org.apache.bcel.classfile.JavaClass jclass, org.apache.bcel.classfile.Method method, org.apache.bcel.generic.MethodGen methodGen, FindRefComparison.RefComparisonTypeFrameModelingVisitor visitor, List<FindRefComparison.WarningWithProperties> stringComparisonList, Location location, org.apache.bcel.generic.Type lhsType, org.apache.bcel.generic.Type rhsType)
    • handleSuspiciousRefComparison

      private void handleSuspiciousRefComparison(org.apache.bcel.classfile.JavaClass jclass, org.apache.bcel.classfile.Method method, org.apache.bcel.generic.MethodGen methodGen, List<FindRefComparison.WarningWithProperties> refComparisonList, Location location, String lhs, org.apache.bcel.generic.ReferenceType lhsType, org.apache.bcel.generic.ReferenceType rhsType, Optional<Integer> priorityOverride)
    • addEqualsCheck

      void addEqualsCheck(String type, int pc)
    • checkEqualsComparison

      private void checkEqualsComparison(Location location, org.apache.bcel.classfile.JavaClass jclass, org.apache.bcel.classfile.Method method, org.apache.bcel.generic.MethodGen methodGen, org.apache.bcel.generic.ConstantPoolGen cpg, TypeDataflow typeDataflow) throws DataflowAnalysisException
      Throws:
      DataflowAnalysisException
    • getMethodCalledAnnotation

      @CheckForNull public MethodAnnotation getMethodCalledAnnotation(org.apache.bcel.generic.ConstantPoolGen cpg, org.apache.bcel.generic.InvokeInstruction inv)
    • getInvokedMethod

      public MethodDescriptor getInvokedMethod(org.apache.bcel.generic.ConstantPoolGen cpg, org.apache.bcel.generic.InvokeInstruction inv)
    • checkForWeirdEquals

      private boolean checkForWeirdEquals(String lhsSig, String rhsSig, Set<XMethod> targets)
    • report

      public void report()
      Description copied from interface: Detector
      This method is called after all classes to be visited. It should be used by any detectors which accumulate information over all visited classes to generate results.
      Specified by:
      report in interface Detector