summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
authorGabor Horvath <xazax@google.com>2019-12-06 17:11:37 -0800
committerGabor Horvath <xazax@google.com>2019-12-10 08:51:33 -0800
commitf3a28202ef58551db15818f8f51afd21e0f3e231 (patch)
treea1233f2ddbe0698f6513f47dc8803da57fc7a2fb /clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
parenta6e50e40e6ddaaefff944dc97379b51af7687cae (diff)
downloadbcm5719-llvm-f3a28202ef58551db15818f8f51afd21e0f3e231.tar.gz
bcm5719-llvm-f3a28202ef58551db15818f8f51afd21e0f3e231.zip
[analyzer] Keep track of escaped locals
We want to escape all symbols that are stored into escaped regions. The problem is, we did not know which local regions were escaped. Until now. This should fix some false positives like the one in the tests. Differential Revision: https://reviews.llvm.org/D71152
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp18
1 files changed, 16 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index efbc20f0925..b6f6481c369 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -193,6 +193,8 @@ typedef llvm::ImmutableMap<ConstructedObjectKey, SVal>
REGISTER_TRAIT_WITH_PROGRAMSTATE(ObjectsUnderConstruction,
ObjectsUnderConstructionMap)
+REGISTER_SET_WITH_PROGRAMSTATE(EscapedLocals, const MemRegion *)
+
//===----------------------------------------------------------------------===//
// Engine construction and deletion.
//===----------------------------------------------------------------------===//
@@ -723,6 +725,12 @@ void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
SymReaper.markLive(MR);
}
+ EscapedLocalsTy EscapedRegions = CleanedState->get<EscapedLocals>();
+ for (const MemRegion *MR : EscapedRegions) {
+ if (!SymReaper.isLiveRegion(MR))
+ CleanedState = CleanedState->remove<EscapedLocals>(MR);
+ }
+
getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper);
// Create a state in which dead bindings are removed from the environment
@@ -1194,6 +1202,11 @@ ProgramStateRef ExprEngine::escapeValue(ProgramStateRef State, SVal V,
State, Scanner.getSymbols(), /*CallEvent*/ nullptr, K, nullptr);
}
+ProgramStateRef ExprEngine::processLocalRegionEscape(ProgramStateRef State,
+ const MemRegion *R) const {
+ return State->add<EscapedLocals>(R);
+}
+
void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
ExplodedNodeSet &DstTop) {
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
@@ -2680,7 +2693,8 @@ void ExprEngine::VisitAtomicExpr(const AtomicExpr *AE, ExplodedNode *Pred,
// A value escapes in four possible cases:
// (1) We are binding to something that is not a memory region.
-// (2) We are binding to a MemRegion that does not have stack storage.
+// (2) We are binding to a MemRegion that does not have stack storage
+// or the stack storage is escaped.
// (3) We are binding to a top-level parameter region with a non-trivial
// destructor. We won't see the destructor during analysis, but it's there.
// (4) We are binding to a MemRegion with stack storage that the store
@@ -2691,7 +2705,7 @@ ExprEngine::processPointerEscapedOnBind(ProgramStateRef State, SVal Loc,
// Cases (1) and (2).
const MemRegion *MR = Loc.getAsRegion();
- if (!MR || !MR->hasStackStorage())
+ if (!MR || !MR->hasStackStorage() || State->contains<EscapedLocals>(MR))
return escapeValue(State, Val, PSK_EscapeOnBind);
// Case (3).
OpenPOWER on IntegriCloud