summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp55
1 files changed, 38 insertions, 17 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index cd35ef095dc..0126e03d60d 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -827,6 +827,21 @@ void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
}
}
+namespace {
+class CollectReachableSymbolsCallback final : public SymbolVisitor {
+ InvalidatedSymbols Symbols;
+
+public:
+ explicit CollectReachableSymbolsCallback(ProgramStateRef State) {}
+ const InvalidatedSymbols &getSymbols() const { return Symbols; }
+
+ bool VisitSymbol(SymbolRef Sym) override {
+ Symbols.insert(Sym);
+ return true;
+ }
+};
+} // end anonymous namespace
+
void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
ExplodedNodeSet &DstTop) {
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
@@ -1103,8 +1118,29 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
resultType,
currBldrCtx->blockCount());
- ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result);
- Bldr2.generateNode(S, N, state);
+ ProgramStateRef State = N->getState()->BindExpr(Ex, LCtx, result);
+
+ // Escape pointers passed into the list, unless it's an ObjC boxed
+ // expression which is not a boxable C structure.
+ if (!(isa<ObjCBoxedExpr>(Ex) &&
+ !cast<ObjCBoxedExpr>(Ex)->getSubExpr()
+ ->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);
+ }
+
+ Bldr2.generateNode(S, N, State);
}
getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
@@ -2237,21 +2273,6 @@ void ExprEngine::VisitAtomicExpr(const AtomicExpr *AE, ExplodedNode *Pred,
getCheckerManager().runCheckersForPostStmt(Dst, AfterInvalidateSet, AE, *this);
}
-namespace {
-class CollectReachableSymbolsCallback final : public SymbolVisitor {
- InvalidatedSymbols Symbols;
-
-public:
- CollectReachableSymbolsCallback(ProgramStateRef State) {}
- const InvalidatedSymbols &getSymbols() const { return Symbols; }
-
- bool VisitSymbol(SymbolRef Sym) override {
- Symbols.insert(Sym);
- return true;
- }
-};
-} // end anonymous namespace
-
// A value escapes in three possible cases:
// (1) We are binding to something that is not a memory region.
// (2) We are binding to a MemrRegion that does not have stack storage.
OpenPOWER on IntegriCloud