26 using namespace clang;
30 class NonNullParamChecker
31 :
public Checker< check::PreCall, EventDispatcher<ImplicitNullDerefEvent> > {
32 mutable std::unique_ptr<BugType> BTAttrNonNull;
33 mutable std::unique_ptr<BugType> BTNullRefArg;
39 std::unique_ptr<BugReport>
40 genReportNullAttrNonNull(
const ExplodedNode *ErrorN,
const Expr *ArgE)
const;
41 std::unique_ptr<BugReport>
42 genReportReferenceToNullPointer(
const ExplodedNode *ErrorN,
43 const Expr *ArgE)
const;
47 void NonNullParamChecker::checkPreCall(
const CallEvent &Call,
55 llvm::SmallBitVector AttrNonNull(NumArgs);
58 AttrNonNull.set(0, NumArgs);
61 for (
unsigned Val :
NonNull->args()) {
73 for (
unsigned idx = 0; idx < NumArgs; ++idx) {
77 bool haveRefTypeParam =
false;
79 haveRefTypeParam = (*TyI)->isReferenceType();
83 bool haveAttrNonNull = AttrNonNull[idx];
84 if (!haveAttrNonNull) {
87 if (idx < parms.size())
88 haveAttrNonNull = parms[idx]->hasAttr<NonNullAttr>();
91 if (!haveRefTypeParam && !haveAttrNonNull)
102 assert(!haveRefTypeParam || DV->getAs<
Loc>());
104 if (haveAttrNonNull && !DV->getAs<
Loc>()) {
118 assert(CSV_I != CSV->end());
121 assert(++CSV_I == CSV->end());
129 dyn_cast<InitListExpr>(CE->getInitializer()))
130 ArgE = dyn_cast<
Expr>(*(IE->begin()));
140 std::tie(stateNotNull, stateNull) = CM.
assumeDual(state, *DV);
148 std::unique_ptr<BugReport> R;
150 R = genReportNullAttrNonNull(errorNode, ArgE);
151 else if (haveRefTypeParam)
152 R = genReportReferenceToNullPointer(errorNode, ArgE);
168 dispatchEvent(event);
174 assert(stateNotNull);
175 state = stateNotNull;
183 std::unique_ptr<BugReport>
184 NonNullParamChecker::genReportNullAttrNonNull(
const ExplodedNode *ErrorNode,
185 const Expr *ArgE)
const {
190 BTAttrNonNull.reset(
new BugType(
191 this,
"Argument with 'nonnull' attribute passed null",
"API"));
193 auto R = llvm::make_unique<BugReport>(
195 "Null pointer passed as an argument to a 'nonnull' parameter", ErrorNode);
202 std::unique_ptr<BugReport> NonNullParamChecker::genReportReferenceToNullPointer(
205 BTNullRefArg.reset(
new BuiltinBug(
this,
"Dereference of null pointer"));
207 auto R = llvm::make_unique<BugReport>(
208 *BTNullRefArg,
"Forming reference to null pointer", ErrorNode);
const Expr * getDerefExpr(const Stmt *S)
Given that expression S represents a pointer that would be dereferenced, try to find a sub-expression...
A (possibly-)qualified type.
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
Decl - This represents one declaration (or definition), e.g.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
CompoundLiteralExpr - [C99 6.5.2.5].
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
llvm::mapped_iterator< ArrayRef< ParmVarDecl * >::iterator, GetTypeFn > param_type_iterator
param_type_iterator param_type_end() const
virtual const Expr * getArgExpr(unsigned Index) const
Returns the expression associated with a given argument.
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
BugReporter & getBugReporter()
Describes an C or C++ initializer list.
Values of this type can never be null.
param_type_iterator param_type_begin() const
Returns an iterator over the types of the call's formal parameters.
We dereferenced a location that may be null.
ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond)
Returns a pair of states (StTrue, StFalse) where the given condition is assumed to be true or false...
llvm::ImmutableList< SVal >::iterator iterator
Expr - This represents one expression.
virtual ArrayRef< ParmVarDecl * > parameters() const =0
Return call's formal parameters.
const FunctionProtoType * T
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
ConstraintManager & getConstraintManager()
RecordDecl * getDecl() const
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generate a sink node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Dataflow Directional Tag Classes.
virtual SourceRange getArgSourceRange(unsigned Index) const
Returns the source range for errors associated with this argument.
Represents an abstract call to a function or method along a particular path.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const ProgramStateRef & getState() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R, bool IsArg=false, bool EnableNullFPSuppression=true)
Attempts to add visitors to trace a null or undefined value back to its point of origin, whether it is a symbol constrained to null or an explicit assignment.
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.