Package edu.umd.cs.findbugs.detect
Class FindNullDeref
- java.lang.Object
-
- edu.umd.cs.findbugs.detect.FindNullDeref
-
- All Implemented Interfaces:
NullDerefAndRedundantComparisonCollector
,Detector
,Priorities
,UseAnnotationDatabase
public class FindNullDeref extends java.lang.Object implements Detector, UseAnnotationDatabase, NullDerefAndRedundantComparisonCollector
A Detector to find instructions where a NullPointerException might be raised. We also look for useless reference comparisons involving null and non-null values.- See Also:
IsNullValueAnalysis
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description (package private) static class
FindNullDeref.CheckCallSitesAndReturnInstructions
-
Field Summary
Fields Modifier and Type Field Description private BugAccumulator
bugAccumulator
private BugReporter
bugReporter
static java.util.Set<java.lang.String>
catchTypesForNull
private boolean
checkedDatabases
private static java.lang.String
CLASS
private ClassContext
classContext
static boolean
DEBUG
private static boolean
DEBUG_NULLARG
private static boolean
DEBUG_NULLRETURN
private IsNullValueDataflow
invDataflow
private org.slf4j.Logger
log
private static boolean
MARK_DOOMED
private org.apache.bcel.classfile.Method
method
private static java.lang.String
METHOD_NAME
private NullnessAnnotation
methodAnnotation
private java.util.BitSet
previouslyDeadBlocks
private ParameterNullnessPropertyDatabase
unconditionalDerefParamDatabase
private ValueNumberDataflow
vnaDataflow
-
Fields inherited from interface edu.umd.cs.findbugs.Priorities
EXP_PRIORITY, HIGH_PRIORITY, IGNORE_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY
-
-
Constructor Summary
Constructors Constructor Description FindNullDeref(BugReporter bugReporter)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description private void
addParamAnnotations(Location location, java.util.BitSet definitelyNullArgSet, java.util.BitSet violatedParamSet, WarningPropertySet<? super NullArgumentWarningProperty> propertySet, BugInstance warning)
private void
addPropertiesForDereferenceLocations(WarningPropertySet<WarningProperty> propertySet, java.util.Collection<Location> derefLocationSet, boolean isConsistent)
private void
addPropertiesForMethodContainingWarning(WarningPropertySet<WarningProperty> propertySet)
private void
analyzeMethod(ClassContext classContext, org.apache.bcel.classfile.Method method)
(package private) boolean
callToAssertionMethod(Location loc)
static boolean
catchesNull(org.apache.bcel.classfile.ConstantPool constantPool, org.apache.bcel.classfile.Code code, Location location)
private void
checkCallSitesAndReturnInstructions()
private void
checkDatabases()
Check whether the various interprocedural databases we can use exist and are nonempty.private void
checkNonNullParam(Location location, org.apache.bcel.generic.ConstantPoolGen cpg, TypeDataflow typeDataflow, org.apache.bcel.generic.InvokeInstruction invokeInstruction, java.util.BitSet nullArgSet, java.util.BitSet definitelyNullArgSet)
We have a method invocation in which a possibly or definitely null parameter is passed.private void
checkUnconditionallyDereferencedParam(Location location, org.apache.bcel.generic.ConstantPoolGen cpg, TypeDataflow typeDataflow, org.apache.bcel.generic.InvokeInstruction invokeInstruction, java.util.BitSet nullArgSet, java.util.BitSet definitelyNullArgSet)
private void
decorateWarning(Location location, WarningPropertySet<WarningProperty> propertySet, BugInstance warning)
private void
examineCallSite(Location location, org.apache.bcel.generic.ConstantPoolGen cpg, TypeDataflow typeDataflow)
private void
examinePutfieldInstruction(Location location, org.apache.bcel.generic.PUTFIELD ins, org.apache.bcel.generic.ConstantPoolGen cpg)
private void
examineReturnInstruction(Location location)
private java.util.BitSet
findPreviouslyDeadBlocks()
Find set of blocks which were known to be dead before doing the null pointer analysis.void
foundGuaranteedNullDeref(java.util.Set<Location> assignedNullLocationSet, java.util.Set<Location> derefLocationSet, java.util.SortedSet<Location> doomedLocations, ValueNumberDataflow vna, ValueNumber refValue, BugAnnotation variableAnnotation, NullValueUnconditionalDeref deref, boolean npeIfStatementCovered)
Subclasses should override this method to capture values assigned null (or that become null through a comparison and branch) that are guaranteed to reach a dereference (ignoring implicit exception paths).void
foundNullDeref(Location location, ValueNumber valueNumber, IsNullValue refValue, ValueNumberFrame vnaFrame)
Deprecated.void
foundNullDeref(Location location, ValueNumber valueNumber, IsNullValue refValue, ValueNumberFrame vnaFrame, boolean isConsistent)
Subclasses should override this method to capture locations where a null pointer is dereferenced.void
foundRedundantNullCheck(Location location, RedundantBranch redundantBranch)
Subclasses should override this method to capture locations where a redundant null comparison is performed.private java.lang.String
getDescription(Location loc, ValueNumber refValue)
private NullnessAnnotation
getMethodNullnessAnnotation()
See if the currently-visited method declares a(package private) BugAnnotation
getVariableAnnotation(Location location)
private boolean
hasManyPreceedingNullTests(int pc)
private boolean
inExplicitCatchNullBlock(Location loc)
private boolean
inIndirectCatchNullBlock(Location loc)
private boolean
isDoomed(Location loc)
boolean
isDuplicated(WarningPropertySet<WarningProperty> propertySet, int pc, boolean isConsistent)
static boolean
isGeneratedCodeInCatchBlock(org.apache.bcel.classfile.Method method, int pc)
Java 11+ compiler generates redundant null checks for try-with-resources.private static boolean
isGeneratedCodeInCatchBlockViaLineNumber(org.apache.bcel.classfile.ConstantPool cp, org.apache.bcel.classfile.LineNumberTable lineNumberTable, int line, org.apache.bcel.generic.InstructionList instructions, java.util.List<org.apache.bcel.classfile.CodeException> throwables)
Java 11+ compiler generates redundant null checks for try-with-resources.private boolean
isGoto(org.apache.bcel.generic.Instruction instruction)
Determine whether the given instruction is a goto.static boolean
isThrower(BasicBlock target)
(package private) int
maxPC(java.util.Collection<Location> locs)
(package private) int
minPC(java.util.Collection<Location> locs)
void
report()
This method is called after all classes to be visited.private void
reportNullDeref(WarningPropertySet<WarningProperty> propertySet, Location location, java.lang.String type, int priority, BugAnnotation variable)
private boolean
safeCallToPrimateParseMethod(XMethod calledMethod, Location location)
private boolean
skipIfInsideCatchNull()
private boolean
uniqueLocations(java.util.Collection<Location> derefLocationSet)
void
visitClassContext(ClassContext classContext)
Visit the ClassContext for a class which should be analyzed for instances of bug patterns.
-
-
-
Field Detail
-
log
private final org.slf4j.Logger log
-
DEBUG
public static final boolean DEBUG
-
DEBUG_NULLARG
private static final boolean DEBUG_NULLARG
-
DEBUG_NULLRETURN
private static final boolean DEBUG_NULLRETURN
-
MARK_DOOMED
private static final boolean MARK_DOOMED
-
METHOD_NAME
private static final java.lang.String METHOD_NAME
-
CLASS
private static final java.lang.String CLASS
-
bugReporter
private final BugReporter bugReporter
-
bugAccumulator
private final BugAccumulator bugAccumulator
-
unconditionalDerefParamDatabase
private ParameterNullnessPropertyDatabase unconditionalDerefParamDatabase
-
checkedDatabases
private boolean checkedDatabases
-
classContext
private ClassContext classContext
-
method
private org.apache.bcel.classfile.Method method
-
invDataflow
private IsNullValueDataflow invDataflow
-
vnaDataflow
private ValueNumberDataflow vnaDataflow
-
previouslyDeadBlocks
private java.util.BitSet previouslyDeadBlocks
-
methodAnnotation
private NullnessAnnotation methodAnnotation
-
catchTypesForNull
@StaticConstant public static final java.util.Set<java.lang.String> catchTypesForNull
-
-
Constructor Detail
-
FindNullDeref
public FindNullDeref(BugReporter bugReporter)
-
-
Method Detail
-
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 interfaceDetector
- Parameters:
classContext
- the ClassContext
-
analyzeMethod
private void analyzeMethod(ClassContext classContext, org.apache.bcel.classfile.Method method) throws DataflowAnalysisException, CFGBuilderException
-
findPreviouslyDeadBlocks
private java.util.BitSet findPreviouslyDeadBlocks() throws DataflowAnalysisException, CFGBuilderException
Find set of blocks which were known to be dead before doing the null pointer analysis.- Returns:
- set of previously dead blocks, indexed by block id
- Throws:
CFGBuilderException
DataflowAnalysisException
-
checkDatabases
private void checkDatabases()
Check whether the various interprocedural databases we can use exist and are nonempty.
-
getMethodNullnessAnnotation
private NullnessAnnotation getMethodNullnessAnnotation()
See if the currently-visited method declares a
-
checkCallSitesAndReturnInstructions
private void checkCallSitesAndReturnInstructions()
-
examineCallSite
private void examineCallSite(Location location, org.apache.bcel.generic.ConstantPoolGen cpg, TypeDataflow typeDataflow) throws DataflowAnalysisException, CFGBuilderException, java.lang.ClassNotFoundException
- Throws:
DataflowAnalysisException
CFGBuilderException
java.lang.ClassNotFoundException
-
examinePutfieldInstruction
private void examinePutfieldInstruction(Location location, org.apache.bcel.generic.PUTFIELD ins, org.apache.bcel.generic.ConstantPoolGen cpg) throws DataflowAnalysisException
- Throws:
DataflowAnalysisException
-
examineReturnInstruction
private void examineReturnInstruction(Location location) throws DataflowAnalysisException, CFGBuilderException
-
hasManyPreceedingNullTests
private boolean hasManyPreceedingNullTests(int pc)
-
catchesNull
public static boolean catchesNull(org.apache.bcel.classfile.ConstantPool constantPool, org.apache.bcel.classfile.Code code, Location location)
-
safeCallToPrimateParseMethod
private boolean safeCallToPrimateParseMethod(XMethod calledMethod, Location location)
-
checkUnconditionallyDereferencedParam
private void checkUnconditionallyDereferencedParam(Location location, org.apache.bcel.generic.ConstantPoolGen cpg, TypeDataflow typeDataflow, org.apache.bcel.generic.InvokeInstruction invokeInstruction, java.util.BitSet nullArgSet, java.util.BitSet definitelyNullArgSet) throws DataflowAnalysisException, java.lang.ClassNotFoundException
- Throws:
DataflowAnalysisException
java.lang.ClassNotFoundException
-
decorateWarning
private void decorateWarning(Location location, WarningPropertySet<WarningProperty> propertySet, BugInstance warning)
-
addParamAnnotations
private void addParamAnnotations(Location location, java.util.BitSet definitelyNullArgSet, java.util.BitSet violatedParamSet, WarningPropertySet<? super NullArgumentWarningProperty> propertySet, BugInstance warning)
-
checkNonNullParam
private void checkNonNullParam(Location location, org.apache.bcel.generic.ConstantPoolGen cpg, TypeDataflow typeDataflow, org.apache.bcel.generic.InvokeInstruction invokeInstruction, java.util.BitSet nullArgSet, java.util.BitSet definitelyNullArgSet)
We have a method invocation in which a possibly or definitely null parameter is passed. Check it against the library of nonnull annotations.- Parameters:
location
-cpg
-typeDataflow
-invokeInstruction
-nullArgSet
-definitelyNullArgSet
-
-
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.
-
skipIfInsideCatchNull
private boolean skipIfInsideCatchNull()
-
foundNullDeref
@Deprecated public void foundNullDeref(Location location, ValueNumber valueNumber, IsNullValue refValue, ValueNumberFrame vnaFrame)
Deprecated.Description copied from interface:NullDerefAndRedundantComparisonCollector
Subclasses should override this method to capture locations where a null pointer is dereferenced.- Specified by:
foundNullDeref
in interfaceNullDerefAndRedundantComparisonCollector
- Parameters:
location
- the Location of the null dereferencevalueNumber
- the ValueNumber of the possibly-null valuerefValue
- the kind of possibly-null value dereferencedvnaFrame
- The ValueNumber Frame at the point where the dereference occurred
-
foundNullDeref
public void foundNullDeref(Location location, ValueNumber valueNumber, IsNullValue refValue, ValueNumberFrame vnaFrame, boolean isConsistent)
Description copied from interface:NullDerefAndRedundantComparisonCollector
Subclasses should override this method to capture locations where a null pointer is dereferenced.- Specified by:
foundNullDeref
in interfaceNullDerefAndRedundantComparisonCollector
- Parameters:
location
- the Location of the null dereferencevalueNumber
- the ValueNumber of the possibly-null valuerefValue
- the kind of possibly-null value dereferencedvnaFrame
- The ValueNumber Frame at the point where the dereference occurredisConsistent
- true if the refValue is identical at all clones of the same instruction
-
isDuplicated
public boolean isDuplicated(WarningPropertySet<WarningProperty> propertySet, int pc, boolean isConsistent)
-
reportNullDeref
private void reportNullDeref(WarningPropertySet<WarningProperty> propertySet, Location location, java.lang.String type, int priority, @CheckForNull BugAnnotation variable)
-
isThrower
public static boolean isThrower(BasicBlock target)
-
foundRedundantNullCheck
public void foundRedundantNullCheck(Location location, RedundantBranch redundantBranch)
Description copied from interface:NullDerefAndRedundantComparisonCollector
Subclasses should override this method to capture locations where a redundant null comparison is performed.- Specified by:
foundRedundantNullCheck
in interfaceNullDerefAndRedundantComparisonCollector
- Parameters:
location
- the Location of the redundant null checkredundantBranch
- the RedundantBranch
-
getVariableAnnotation
BugAnnotation getVariableAnnotation(Location location)
-
isGoto
private boolean isGoto(org.apache.bcel.generic.Instruction instruction)
Determine whether the given instruction is a goto.- Parameters:
instruction
- the instruction- Returns:
- true if the instruction is a goto, false otherwise
-
minPC
int minPC(java.util.Collection<Location> locs)
-
maxPC
int maxPC(java.util.Collection<Location> locs)
-
callToAssertionMethod
boolean callToAssertionMethod(Location loc)
-
foundGuaranteedNullDeref
public void foundGuaranteedNullDeref(@Nonnull java.util.Set<Location> assignedNullLocationSet, @Nonnull java.util.Set<Location> derefLocationSet, java.util.SortedSet<Location> doomedLocations, ValueNumberDataflow vna, ValueNumber refValue, @CheckForNull BugAnnotation variableAnnotation, NullValueUnconditionalDeref deref, boolean npeIfStatementCovered)
Description copied from interface:NullDerefAndRedundantComparisonCollector
Subclasses should override this method to capture values assigned null (or that become null through a comparison and branch) that are guaranteed to reach a dereference (ignoring implicit exception paths).- Specified by:
foundGuaranteedNullDeref
in interfaceNullDerefAndRedundantComparisonCollector
- Parameters:
assignedNullLocationSet
- set of locations where the value becomes nullderefLocationSet
- set of locations where dereferences occurdoomedLocations
- locations at which the value is doomedvna
- ValueNumberDataflowrefValue
- the null valuevariableAnnotation
- TODOderef
- TODOnpeIfStatementCovered
- true if doom location is a statement
-
addPropertiesForDereferenceLocations
private void addPropertiesForDereferenceLocations(WarningPropertySet<WarningProperty> propertySet, java.util.Collection<Location> derefLocationSet, boolean isConsistent)
-
uniqueLocations
private boolean uniqueLocations(java.util.Collection<Location> derefLocationSet)
-
addPropertiesForMethodContainingWarning
private void addPropertiesForMethodContainingWarning(WarningPropertySet<WarningProperty> propertySet)
-
isDoomed
private boolean isDoomed(Location loc)
-
getDescription
private java.lang.String getDescription(Location loc, ValueNumber refValue)
-
inExplicitCatchNullBlock
private boolean inExplicitCatchNullBlock(Location loc)
-
inIndirectCatchNullBlock
private boolean inIndirectCatchNullBlock(Location loc)
-
isGeneratedCodeInCatchBlock
public static boolean isGeneratedCodeInCatchBlock(@NonNull org.apache.bcel.classfile.Method method, int pc)
Java 11+ compiler generates redundant null checks for try-with-resources. This method detects theifnull
bytecode generated by javac, to help the detector to avoid to report needlessRCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE
bug.- Parameters:
method
- the methodpc
- the program counter- Returns:
- true if the pc specifies redundant null check generated by javac
- See Also:
- false positive RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE on try-with-resources, false positive RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE on try-with-resources
-
isGeneratedCodeInCatchBlockViaLineNumber
private static boolean isGeneratedCodeInCatchBlockViaLineNumber(@NonNull org.apache.bcel.classfile.ConstantPool cp, @NonNull org.apache.bcel.classfile.LineNumberTable lineNumberTable, int line, @NonNull org.apache.bcel.generic.InstructionList instructions, @NonNull java.util.List<org.apache.bcel.classfile.CodeException> throwables)
Java 11+ compiler generates redundant null checks for try-with-resources. This method tries to distinguish such code from manually written code by analysing null numbers.- Parameters:
cp
- the constant poollineNumberTable
- the table with the line numbersline
- the line which belongs to the program counterinstructions
- the list of instructionsthrowables
- the list of Throwables in this method- Returns:
- true if the pc specifies redundant null check generated by javac
-
-