aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp6
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h3
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/StoreToImmutableChecker.cpp51
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp5
13 files changed, 34 insertions, 66 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
index 3b3def7..e64153d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
@@ -183,7 +183,8 @@ public:
llvm::errs() << "NewAllocator\n";
}
- void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const {
+ void checkBind(SVal Loc, SVal Val, const Stmt *S, bool AtDeclInit,
+ CheckerContext &C) const {
if (isCallbackEnabled(C, "Bind"))
llvm::errs() << "Bind\n";
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
index 837cbbc..921114a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
@@ -29,7 +29,8 @@ class BoolAssignmentChecker : public Checker<check::Bind> {
bool IsTainted = false) const;
public:
- void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const;
+ void checkBind(SVal Loc, SVal Val, const Stmt *S, bool AtDeclInit,
+ CheckerContext &C) const;
};
} // end anonymous namespace
@@ -55,6 +56,7 @@ static bool isBooleanType(QualType Ty) {
}
void BoolAssignmentChecker::checkBind(SVal Loc, SVal Val, const Stmt *S,
+ bool AtDeclInit,
CheckerContext &C) const {
// We are only interested in stores into Booleans.
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
index 350db4b..392c7ee 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
@@ -175,9 +175,12 @@ public:
/// \param Loc The value of the location (pointer).
/// \param Val The value which will be stored at the location Loc.
/// \param S The bind is performed while processing the statement S.
+ /// \param AtDeclInit Whether the bind is performed during declaration
+ /// initialization.
///
/// check::Bind
- void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &) const {}
+ void checkBind(SVal Loc, SVal Val, const Stmt *S, bool AtDeclInit,
+ CheckerContext &) const {}
/// Called after a CFG edge is taken within a function.
///
diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
index 152129e..395d724 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -48,7 +48,8 @@ class DereferenceChecker
public:
void checkLocation(SVal location, bool isLoad, const Stmt* S,
CheckerContext &C) const;
- void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
+ void checkBind(SVal L, SVal V, const Stmt *S, bool AtDeclInit,
+ CheckerContext &C) const;
static void AddDerefSource(raw_ostream &os,
SmallVectorImpl<SourceRange> &Ranges,
@@ -309,7 +310,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
}
void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
- CheckerContext &C) const {
+ bool AtDeclInit, CheckerContext &C) const {
// If we're binding to a reference, check if the value is known to be null.
if (V.isUndef())
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
index 7ad54c0..7eb9a1d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
@@ -150,7 +150,8 @@ public:
IteratorModeling() = default;
void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
- void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const;
+ void checkBind(SVal Loc, SVal Val, const Stmt *S, bool AtDeclInit,
+ CheckerContext &C) const;
void checkPostStmt(const UnaryOperator *UO, CheckerContext &C) const;
void checkPostStmt(const BinaryOperator *BO, CheckerContext &C) const;
void checkPostStmt(const MaterializeTemporaryExpr *MTE,
@@ -234,7 +235,7 @@ void IteratorModeling::checkPostCall(const CallEvent &Call,
}
void IteratorModeling::checkBind(SVal Loc, SVal Val, const Stmt *S,
- CheckerContext &C) const {
+ bool AtDeclInit, CheckerContext &C) const {
auto State = C.getState();
const auto *Pos = getIteratorPosition(State, Val);
if (Pos) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 369d619..efb9809 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -3156,7 +3156,7 @@ void MallocChecker::checkPreCall(const CallEvent &Call,
for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
SVal ArgSVal = Call.getArgSVal(I);
if (isa<Loc>(ArgSVal)) {
- SymbolRef Sym = ArgSVal.getAsSymbol();
+ SymbolRef Sym = ArgSVal.getAsSymbol(/*IncludeBaseRegions=*/true);
if (!Sym)
continue;
if (checkUseAfterFree(Sym, C, Call.getArgExpr(I)))
diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
index 9744d1a..eeb6b72 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
@@ -97,7 +97,8 @@ public:
// libraries.
bool NoDiagnoseCallsToSystemHeaders = false;
- void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
+ void checkBind(SVal L, SVal V, const Stmt *S, bool AtDeclInit,
+ CheckerContext &C) const;
void checkPostStmt(const ExplicitCastExpr *CE, CheckerContext &C) const;
void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
@@ -1250,7 +1251,7 @@ static bool isARCNilInitializedLocal(CheckerContext &C, const Stmt *S) {
/// Propagate the nullability information through binds and warn when nullable
/// pointer or null symbol is assigned to a pointer with a nonnull type.
void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S,
- CheckerContext &C) const {
+ bool AtDeclInit, CheckerContext &C) const {
const TypedValueRegion *TVR =
dyn_cast_or_null<TypedValueRegion>(L.getAsRegion());
if (!TVR)
diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
index ace3426..e40b4f8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
@@ -73,7 +73,8 @@ public:
void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
void checkLocation(SVal location, bool isLoad, const Stmt *S,
CheckerContext &C) const;
- void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
+ void checkBind(SVal loc, SVal val, const Stmt *S, bool AtDeclInit,
+ CheckerContext &C) const;
void checkPreCall(const CallEvent &CE, CheckerContext &C) const;
void checkPostCall(const CallEvent &CE, CheckerContext &C) const;
@@ -311,9 +312,8 @@ void ObjCSelfInitChecker::checkLocation(SVal location, bool isLoad,
C);
}
-
void ObjCSelfInitChecker::checkBind(SVal loc, SVal val, const Stmt *S,
- CheckerContext &C) const {
+ bool AtDeclInit, CheckerContext &C) const {
// Allow assignment of anything to self. Self is a local variable in the
// initializer, so it is legal to assign anything to it, like results of
// static functions/method calls. After self is assigned something we cannot
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 65ff902..1762505 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -1136,7 +1136,7 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
//===----------------------------------------------------------------------===//
void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
- CheckerContext &C) const {
+ bool AtDeclInit, CheckerContext &C) const {
ProgramStateRef state = C.getState();
const MemRegion *MR = loc.getAsRegion();
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
index 8854e10..dc8bad6 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
@@ -280,7 +280,8 @@ public:
void printState(raw_ostream &Out, ProgramStateRef State,
const char *NL, const char *Sep) const override;
- void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
+ void checkBind(SVal loc, SVal val, const Stmt *S, bool AtDeclInit,
+ CheckerContext &C) const;
void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
void checkPostStmt(const CastExpr *CE, CheckerContext &C) const;
diff --git a/clang/lib/StaticAnalyzer/Checkers/StoreToImmutableChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StoreToImmutableChecker.cpp
index afad419..2bb3917 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StoreToImmutableChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StoreToImmutableChecker.cpp
@@ -26,53 +26,11 @@ class StoreToImmutableChecker : public Checker<check::Bind> {
const BugType BT{this, "Write to immutable memory", "CERT Environment (ENV)"};
public:
- void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const;
+ void checkBind(SVal Loc, SVal Val, const Stmt *S, bool AtDeclInit,
+ CheckerContext &C) const;
};
} // end anonymous namespace
-static bool isInitializationContext(const Stmt *S, CheckerContext &C) {
- // Check if this is a DeclStmt (variable declaration)
- if (isa<DeclStmt>(S))
- return true;
-
- // This part is specific for initialization of const lambdas pre-C++17.
- // Lets look at the AST of the statement:
- // ```
- // const auto lambda = [](){};
- // ```
- //
- // The relevant part of the AST for this case prior to C++17 is:
- // ...
- // `-DeclStmt
- // `-VarDecl
- // `-ExprWithCleanups
- // `-CXXConstructExpr
- // ...
- // In C++17 and later, the AST is different:
- // ...
- // `-DeclStmt
- // `-VarDecl
- // `-ImplicitCastExpr
- // `-LambdaExpr
- // |-CXXRecordDecl
- // `-CXXConstructExpr
- // ...
- // And even beside this, the statement `S` that is given to the checkBind
- // callback is the VarDecl in C++17 and later, and the CXXConstructExpr in
- // C++14 and before. So in order to support the C++14 we need the following
- // ugly hack to detect whether this construction is used to initialize a
- // variable.
- //
- // FIXME: This should be eliminated by improving the API of checkBind to
- // ensure that it consistently passes the `VarDecl` (instead of the
- // `CXXConstructExpr`) when the constructor call denotes the initialization
- // of a variable with a lambda, or maybe less preferably, try the more
- // invasive approach of passing the information forward to the checkers
- // whether the current bind is an initialization or an assignment.
- const auto *ConstructExp = dyn_cast<CXXConstructExpr>(S);
- return ConstructExp && ConstructExp->isElidable();
-}
-
static bool isEffectivelyConstRegion(const MemRegion *MR, CheckerContext &C) {
if (isa<GlobalImmutableSpaceRegion>(MR))
return true;
@@ -128,6 +86,7 @@ getInnermostEnclosingConstDeclRegion(const MemRegion *MR, CheckerContext &C) {
}
void StoreToImmutableChecker::checkBind(SVal Loc, SVal Val, const Stmt *S,
+ bool AtDeclInit,
CheckerContext &C) const {
// We are only interested in stores to memory regions
const MemRegion *MR = Loc.getAsRegion();
@@ -136,9 +95,7 @@ void StoreToImmutableChecker::checkBind(SVal Loc, SVal Val, const Stmt *S,
// Skip variable declarations and initializations - we only want to catch
// actual writes
- // FIXME: If the API of checkBind would allow to distinguish between
- // initialization and assignment, we could use that instead.
- if (isInitializationContext(S, C))
+ if (AtDeclInit)
return;
// Check if the region is in the global immutable space
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
index e98de33..7f8923c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -26,13 +26,13 @@ class UndefinedAssignmentChecker
const BugType BT{this, "Assigned value is uninitialized"};
public:
- void checkBind(SVal location, SVal val, const Stmt *S,
+ void checkBind(SVal location, SVal val, const Stmt *S, bool AtDeclInit,
CheckerContext &C) const;
};
}
void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
- const Stmt *StoreE,
+ const Stmt *StoreE, bool AtDeclInit,
CheckerContext &C) const {
if (!val.isUndef())
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp
index cb73ac6..116dd93 100644
--- a/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp
@@ -62,7 +62,8 @@ public:
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
- void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
+ void checkBind(SVal L, SVal V, const Stmt *S, bool AtDeclInit,
+ CheckerContext &C) const;
void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
};
@@ -188,7 +189,7 @@ void VforkChecker::checkPreCall(const CallEvent &Call,
}
// Prohibit writes in child process (except for vfork's lhs).
-void VforkChecker::checkBind(SVal L, SVal V, const Stmt *S,
+void VforkChecker::checkBind(SVal L, SVal V, const Stmt *S, bool AtDeclInit,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
if (!isChildProcess(State))