Revert "[analyzer] Keep track of escaped locals"

It was a step in the right direction but it is not clear how can this
fit into the checker API at this point. The pre-escape happens in the
analyzer core and the checker has no control over it. If the checker
is not interestd in a pre-escape it would need to do additional work
on each escape to check if the escaped symbol is originated from an
"uninteresting" pre-escaped memory region. In order to keep the
checker API simple we abandoned this solution for now.

We will reland this once we have a better answer for what to do on the
checker side.

This reverts commit f3a28202ef.
This commit is contained in:
Gabor Horvath 2019-12-10 16:42:03 -08:00
parent 21bc8631fe
commit 8434fbbee6
6 changed files with 12 additions and 48 deletions

View File

@ -627,9 +627,6 @@ protected:
const CallEvent *Call,
RegionAndSymbolInvalidationTraits &ITraits) override;
ProgramStateRef processLocalRegionEscape(ProgramStateRef State,
const MemRegion *R) const override;
/// A simple wrapper when you only need to notify checkers of pointer-escape
/// of a single value.
ProgramStateRef escapeValue(ProgramStateRef State, SVal V,

View File

@ -27,7 +27,7 @@
namespace llvm {
class APSInt;
} // namespace llvm
}
namespace clang {
class ASTContext;
@ -872,8 +872,8 @@ public:
bool scan(const SymExpr *sym);
};
} // namespace ento
} // end ento namespace
} // namespace clang
} // end clang namespace
#endif

View File

@ -149,16 +149,14 @@ public:
}
virtual ProgramStateRef
processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val,
const LocationContext *LCtx) = 0;
virtual ProgramStateRef notifyCheckersOfPointerEscape(
ProgramStateRef State, const InvalidatedSymbols *Invalidated,
ArrayRef<const MemRegion *> ExplicitRegions, const CallEvent *Call,
RegionAndSymbolInvalidationTraits &HTraits) = 0;
processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val, const LocationContext *LCtx) = 0;
virtual ProgramStateRef
processLocalRegionEscape(ProgramStateRef State, const MemRegion *R) const = 0;
notifyCheckersOfPointerEscape(ProgramStateRef State,
const InvalidatedSymbols *Invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
const CallEvent *Call,
RegionAndSymbolInvalidationTraits &HTraits) = 0;
/// printJson - Called by ProgramStateManager to print checker-specific data.
virtual void printJson(raw_ostream &Out, ProgramStateRef State,

View File

@ -193,8 +193,6 @@ typedef llvm::ImmutableMap<ConstructedObjectKey, SVal>
REGISTER_TRAIT_WITH_PROGRAMSTATE(ObjectsUnderConstruction,
ObjectsUnderConstructionMap)
REGISTER_SET_WITH_PROGRAMSTATE(EscapedLocals, const MemRegion *)
//===----------------------------------------------------------------------===//
// Engine construction and deletion.
//===----------------------------------------------------------------------===//
@ -725,12 +723,6 @@ 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
@ -1202,11 +1194,6 @@ 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(),
@ -2693,8 +2680,7 @@ 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
// or the stack storage is escaped.
// (2) We are binding to a MemRegion that does not have stack storage.
// (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
@ -2705,7 +2691,7 @@ ExprEngine::processPointerEscapedOnBind(ProgramStateRef State, SVal Loc,
// Cases (1) and (2).
const MemRegion *MR = Loc.getAsRegion();
if (!MR || !MR->hasStackStorage() || State->contains<EscapedLocals>(MR))
if (!MR || !MR->hasStackStorage())
return escapeValue(State, Val, PSK_EscapeOnBind);
// Case (3).

View File

@ -41,8 +41,7 @@ void ProgramStateRelease(const ProgramState *state) {
Mgr.freeStates.push_back(s);
}
}
} // namespace ento
} // namespace clang
}}
ProgramState::ProgramState(ProgramStateManager *mgr, const Environment& env,
StoreRef st, GenericDataMap gdm)
@ -210,13 +209,6 @@ ProgramState::invalidateRegionsImpl(ValueList Values,
ProgramStateRef newState = makeWithStore(newStore);
if (CausedByPointerEscape) {
for (const MemRegion *R : Invalidated) {
if (!R->hasStackStorage())
continue;
newState = Eng.processLocalRegionEscape(newState, R->getBaseRegion());
}
newState = Eng.notifyCheckersOfPointerEscape(newState, IS,
TopLevelInvalidated,
Call,

View File

@ -31,12 +31,3 @@ C **indirect_escape_in_bitwise_op() {
return Baz;
}
void save_ptr(int **);
void delete_saved();
void store_to_escaped_region() {
int *p;
save_ptr(&p);
p = new int;
delete_saved();
} // no-warning