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,
63 case Stmt::DeclRefExprClass: {
66 os <<
" (" << (loadedFrom ?
"loaded from" :
"from")
67 <<
" variable '" << VD->getName() <<
"')";
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);
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: {
157 if (M->
isArrow() || bugreporter::isDeclRefExprToReference(M->
getBase())) {
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);
180 bugreporter::trackNullOrUndefValue(N, bugreporter::getDerefExpr(S), *report);
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);
200 bugreporter::trackNullOrUndefValue(N, bugreporter::getDerefExpr(S),
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);
TypedValueRegion - An abstract class representing regions having a typed value.
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.
Stmt - This represents one statement.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
virtual QualType getValueType() const =0
Represents a variable declaration or definition.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
static bool suppressReport(const Expr *E)
bool isReferenceType() const
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()
bool hasAddressSpace() const
const LocationContext * getLocationContext() const
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
We dereferenced a location that may be null.
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.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
SourceLocation getMemberLoc() const
getMemberLoc - Return the location of the "member", in X->F, it is the location of 'F'...
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
CHECKER * registerChecker(AT... Args)
Used to register checkers.
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
Encodes a location in the source.
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generate a sink node.
Expr * getSubExpr() const
const MemRegion * getAsRegion() const
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)
Dataflow Directional Tag Classes.
DeclarationNameInfo getMemberNameInfo() const
Retrieve the member declaration name info.
StmtClass getStmtClass() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
const ProgramStateRef & getState() const
SourceLocation getLocation() const
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Ignore parentheses and lvalue casts.
const Expr * getBase() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A reference to a declared variable, function, enum, etc.
A trivial tuple used to represent a source range.
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].