summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2018-04-19 23:24:32 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2018-04-19 23:24:32 +0000
commit468bc0d8b9c5ca13af4c3d87b36dc544ccae9265 (patch)
tree68c990ba688dbc5a6a2f7ea0535c9584d9a77ac5 /clang/lib/StaticAnalyzer
parentb72daf00f45a92a07cd539025cf83f975ba65079 (diff)
downloadbcm5719-llvm-468bc0d8b9c5ca13af4c3d87b36dc544ccae9265.tar.gz
bcm5719-llvm-468bc0d8b9c5ca13af4c3d87b36dc544ccae9265.zip
[analyzer] When we fail to evaluate a pointer cast, escape the pointer.
If a pointer cast fails (evaluates to an UnknownVal, i.e. not implemented in the analyzer) and such cast is in fact the last use of the pointer, the pointer symbol is no longer referenced by the program state and a leak is (mis-)diagnosed. "Escape" the pointer upon a failed cast, i.e. inform the checker that we can no longer reliably track it. Differential Revision: https://reviews.llvm.org/D45698 llvm-svn: 330380
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp51
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp7
2 files changed, 24 insertions, 34 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 51c6f25e98c..1e0bfcea2d7 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1231,23 +1231,27 @@ void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
}
}
-namespace {
+ProgramStateRef ExprEngine::escapeValue(ProgramStateRef State, SVal V,
+ PointerEscapeKind K) const {
+ class CollectReachableSymbolsCallback final : public SymbolVisitor {
+ InvalidatedSymbols Symbols;
-class CollectReachableSymbolsCallback final : public SymbolVisitor {
- InvalidatedSymbols Symbols;
+ public:
+ explicit CollectReachableSymbolsCallback(ProgramStateRef State) {}
-public:
- explicit CollectReachableSymbolsCallback(ProgramStateRef State) {}
+ const InvalidatedSymbols &getSymbols() const { return Symbols; }
- const InvalidatedSymbols &getSymbols() const { return Symbols; }
-
- bool VisitSymbol(SymbolRef Sym) override {
- Symbols.insert(Sym);
- return true;
- }
-};
+ bool VisitSymbol(SymbolRef Sym) override {
+ Symbols.insert(Sym);
+ return true;
+ }
+ };
-} // namespace
+ const CollectReachableSymbolsCallback &Scanner =
+ State->scanReachableSymbols<CollectReachableSymbolsCallback>(V);
+ return getCheckerManager().runCheckersForPointerEscape(
+ State, Scanner.getSymbols(), /*CallEvent*/ nullptr, K, nullptr);
+}
void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
ExplodedNodeSet &DstTop) {
@@ -1529,17 +1533,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
->getType()->isRecordType()))
for (auto Child : Ex->children()) {
assert(Child);
-
SVal Val = State->getSVal(Child, LCtx);
-
- CollectReachableSymbolsCallback Scanner =
- State->scanReachableSymbols<CollectReachableSymbolsCallback>(
- Val);
- const InvalidatedSymbols &EscapedSymbols = Scanner.getSymbols();
-
- State = getCheckerManager().runCheckersForPointerEscape(
- State, EscapedSymbols,
- /*CallEvent*/ nullptr, PSK_EscapeOther, nullptr);
+ State = escapeValue(State, Val, PSK_EscapeOther);
}
Bldr2.generateNode(S, N, State);
@@ -2759,15 +2754,7 @@ ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
// Otherwise, find all symbols referenced by 'val' that we are tracking
// and stop tracking them.
- CollectReachableSymbolsCallback Scanner =
- State->scanReachableSymbols<CollectReachableSymbolsCallback>(Val);
- const InvalidatedSymbols &EscapedSymbols = Scanner.getSymbols();
- State = getCheckerManager().runCheckersForPointerEscape(State,
- EscapedSymbols,
- /*CallEvent*/ nullptr,
- PSK_EscapeOnBind,
- nullptr);
-
+ State = escapeValue(State, Val, PSK_EscapeOnBind);
return State;
}
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 55ee2cefc91..5a306a5c5f2 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -258,12 +258,15 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr,
ExplodedNode* Pred) {
// Delegate to SValBuilder to process.
- SVal V = state->getSVal(Ex, LCtx);
- V = svalBuilder.evalCast(V, T, ExTy);
+ SVal OrigV = state->getSVal(Ex, LCtx);
+ SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
// Negate the result if we're treating the boolean as a signed i1
if (CastE->getCastKind() == CK_BooleanToSignedIntegral)
V = evalMinus(V);
state = state->BindExpr(CastE, LCtx, V);
+ if (V.isUnknown() && !OrigV.isUnknown()) {
+ state = escapeValue(state, OrigV, PSK_EscapeOther);
+ }
Bldr.generateNode(CastE, Pred, state);
return state;
OpenPOWER on IntegriCloud