23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/Support/raw_ostream.h"
26 using namespace clang;
30 class DereferenceChecker
31 :
public Checker< check::Location,
33 EventDispatcher<ImplicitNullDerefEvent> > {
34 mutable std::unique_ptr<BuiltinBug> BT_null;
35 mutable std::unique_ptr<BuiltinBug> BT_undef;
40 void checkLocation(
SVal location,
bool isLoad,
const Stmt*
S,
44 static void AddDerefSource(raw_ostream &os,
48 bool loadedFrom =
false);
53 DereferenceChecker::AddDerefSource(raw_ostream &os,
60 switch (Ex->getStmtClass()) {
63 case Stmt::DeclRefExprClass: {
66 os <<
" (" << (loadedFrom ?
"loaded from" :
"from")
67 <<
" variable '" << VD->getName() <<
"')";
68 Ranges.push_back(DR->getSourceRange());
72 case Stmt::MemberExprClass: {
74 os <<
" (" << (loadedFrom ?
"loaded from" :
"via")
80 case Stmt::ObjCIvarRefExprClass: {
82 os <<
" (" << (loadedFrom ?
"loaded from" :
"via")
92 const Expr *
E =
nullptr;
96 if (
const Expr *
expr = dyn_cast<Expr>(S))
97 E =
expr->IgnoreParenLValueCasts();
124 BT_null.reset(
new BuiltinBug(
this,
"Dereference of null pointer"));
127 llvm::raw_svector_ostream os(buf);
131 switch (S->getStmtClass()) {
132 case Stmt::ArraySubscriptExprClass: {
133 os <<
"Array access";
137 os <<
" results in a null pointer dereference";
140 case Stmt::OMPArraySectionExprClass: {
141 os <<
"Array access";
145 os <<
" results in a null pointer dereference";
148 case Stmt::UnaryOperatorClass: {
149 os <<
"Dereference of null pointer";
155 case Stmt::MemberExprClass: {
159 <<
"' results in a dereference of a null pointer";
165 case Stmt::ObjCIvarRefExprClass: {
167 os <<
"Access to instance variable '" << *IV->
getDecl()
168 <<
"' results in a dereference of a null pointer";
177 auto report = llvm::make_unique<BugReport>(
178 *BT_null, buf.empty() ? BT_null->getDescription() : StringRef(buf), N);
183 I = Ranges.begin(),
E = Ranges.end();
I!=
E; ++
I)
184 report->addRange(*
I);
189 void DereferenceChecker::checkLocation(
SVal l,
bool isLoad,
const Stmt* S,
196 new BuiltinBug(
this,
"Dereference of undefined pointer value"));
199 llvm::make_unique<BugReport>(*BT_undef, BT_undef->getDescription(), N);
216 std::tie(notNullState, nullState) = state->assume(location);
223 reportBug(nullState, expr, C);
234 dispatchEvent(event);
242 void DereferenceChecker::checkBind(
SVal L,
SVal V,
const Stmt *S,
265 reportBug(StNull, expr, C);
276 dispatchEvent(event);
const Expr * getBase() const
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
TypedValueRegion - An abstract class representing regions having a typed value.
const Expr * getDerefExpr(const Stmt *S)
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
MemRegion - The root abstract class for all memory regions.
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
SourceLocation getLocation() const
DeclarationNameInfo getMemberNameInfo() const
Retrieve the member declaration name info.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
virtual QualType getValueType() const =0
VarDecl - An instance of this class is created to represent a variable declaration or definition...
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
bool isReferenceType() const
static bool suppressReport(const Expr *E)
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()
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
detail::InMemoryDirectory::const_iterator I
We dereferenced a location that may be null.
const LocationContext * getLocationContext() const
OpenMP 4.0 [2.4, Array Sections].
std::pair< const clang::VarDecl *, const clang::Expr * > parseAssignment(const Stmt *S)
ProgramState - This class encapsulates:
Expr - This represents one expression.
const ProgramStateRef & getState() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Expr * getSubExpr() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
Encodes a location in the source.
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...
static const Expr * getDereferenceExpr(const Stmt *S, bool IsBind=false)
bool isDeclRefExprToReference(const Expr *E)
detail::InMemoryDirectory::const_iterator E
const MemRegion * getAsRegion() const
SourceLocation getMemberLoc() const
getMemberLoc - Return the location of the "member", in X->F, it is the location of 'F'...
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Ignore parentheses and lvalue casts.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
bool hasAddressSpace() const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
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.
A reference to a declared variable, function, enum, etc.
A trivial tuple used to represent a source range.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].