class PointerEscape {
template <typename CHECKER>
static ProgramStateRef
- _checkPointerEscape(void *checker,
+ _checkPointerEscape(void *Checker,
ProgramStateRef State,
const InvalidatedSymbols &Escaped,
const CallEvent *Call,
PointerEscapeKind Kind,
- bool IsConst) {
- if (!IsConst)
- return ((const CHECKER *)checker)->checkPointerEscape(State,
+ RegionAndSymbolInvalidationTraits *ETraits) {
+
+ if (!ETraits)
+ return ((const CHECKER *)Checker)->checkPointerEscape(State,
Escaped,
Call,
Kind);
- return State;
+
+ InvalidatedSymbols RegularEscape;
+ for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
+ E = Escaped.end(); I != E; ++I)
+ if (!ETraits->hasTrait(*I,
+ RegionAndSymbolInvalidationTraits::TK_PreserveContents))
+ RegularEscape.insert(*I);
+
+ if (RegularEscape.empty())
+ return State;
+
+ return ((const CHECKER *)Checker)->checkPointerEscape(State,
+ RegularEscape,
+ Call,
+ Kind);
}
public:
class ConstPointerEscape {
template <typename CHECKER>
static ProgramStateRef
- _checkConstPointerEscape(void *checker,
+ _checkConstPointerEscape(void *Checker,
ProgramStateRef State,
const InvalidatedSymbols &Escaped,
const CallEvent *Call,
PointerEscapeKind Kind,
- bool IsConst) {
- if (IsConst)
- return ((const CHECKER *)checker)->checkConstPointerEscape(State,
- Escaped,
- Call,
- Kind);
- return State;
+ RegionAndSymbolInvalidationTraits *ETraits) {
+
+ if (!ETraits)
+ return State;
+
+ InvalidatedSymbols ConstEscape;
+ for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
+ E = Escaped.end(); I != E; ++I)
+ if (ETraits->hasTrait(*I,
+ RegionAndSymbolInvalidationTraits::TK_PreserveContents))
+ ConstEscape.insert(*I);
+
+ if (ConstEscape.empty())
+ return State;
+
+ return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
+ ConstEscape,
+ Call,
+ Kind);
}
public:
/// \param Escaped The list of escaped symbols.
/// \param Call The corresponding CallEvent, if the symbols escape as
/// parameters to the given call.
- /// \param IsConst Specifies if the pointer is const.
+ /// \param Kind The reason of pointer escape.
+ /// \param ITraits Information about invalidation for a particular
+ /// region/symbol.
/// \returns Checkers can modify the state by returning a new one.
ProgramStateRef
runCheckersForPointerEscape(ProgramStateRef State,
const InvalidatedSymbols &Escaped,
const CallEvent *Call,
PointerEscapeKind Kind,
- bool IsConst = false);
+ RegionAndSymbolInvalidationTraits *ITraits);
/// \brief Run checkers for handling assumptions on symbolic values.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
const InvalidatedSymbols &Escaped,
const CallEvent *Call,
PointerEscapeKind Kind,
- bool IsConst)>
+ RegionAndSymbolInvalidationTraits *ITraits)>
CheckPointerEscapeFunc;
typedef CheckerFn<ProgramStateRef (ProgramStateRef,
SVal Loc, SVal Val);
/// Call PointerEscape callback when a value escapes as a result of
/// region invalidation.
- /// \param[in] IsConst Specifies that the pointer is const.
+ /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
ProgramStateRef notifyCheckersOfPointerEscape(
ProgramStateRef State,
const InvalidatedSymbols *Invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call,
- bool IsConst);
+ RegionAndSymbolInvalidationTraits &ITraits);
public:
// FIXME: 'tag' should be removed, and a LocationContext should be used
inline ASTContext &MemRegion::getContext() const {
return getMemRegionManager()->getContext();
}
+
+//===----------------------------------------------------------------------===//
+// Means for storing region/symbol handling traits.
+//===----------------------------------------------------------------------===//
+
+/// Information about invalidation for a particular region/symbol.
+class RegionAndSymbolInvalidationTraits {
+ typedef unsigned char StorageTypeForKinds;
+ llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
+ llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
+
+ typedef llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator
+ const_region_iterator;
+ typedef llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator
+ const_symbol_iterator;
+
+public:
+ /// \brief Describes different invalidation traits.
+ enum InvalidationKinds {
+ /// Tells that a region's contents is not changed.
+ TK_PreserveContents = 0x1
+
+ // Do not forget to extend StorageTypeForKinds if number of traits exceed
+ // the number of bits StorageTypeForKinds can store.
+ };
+
+ void setTrait(SymbolRef Sym, InvalidationKinds IK);
+ void setTrait(const MemRegion *MR, InvalidationKinds IK);
+ bool hasTrait(SymbolRef Sym, InvalidationKinds IK);
+ bool hasTrait(const MemRegion *MR, InvalidationKinds IK);
+};
} // end GR namespace
/// \param IS the set of invalidated symbols.
/// \param Call if non-null, the invalidated regions represent parameters to
/// the call and should be considered directly invalidated.
- /// \param ConstRegions the set of regions whose contents are accessible,
- /// even though the regions themselves should not be invalidated.
+ /// \param HTraits information about special handling for a particular
+ /// region/symbol.
ProgramStateRef
invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
unsigned BlockCount, const LocationContext *LCtx,
bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
const CallEvent *Call = 0,
- ArrayRef<const MemRegion *> ConstRegions =
- ArrayRef<const MemRegion *>()) const;
+ RegionAndSymbolInvalidationTraits *HTraits = 0) const;
ProgramStateRef
invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
unsigned BlockCount, const LocationContext *LCtx,
bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
const CallEvent *Call = 0,
- ArrayRef<SVal> ConstRegions = ArrayRef<SVal>()) const;
+ RegionAndSymbolInvalidationTraits *HTraits = 0) const;
/// enterStackFrame - Returns the state for entry to the given stack frame,
/// preserving the current state.
const Expr *E, unsigned BlockCount,
const LocationContext *LCtx,
bool ResultsInSymbolEscape,
- InvalidatedSymbols &IS,
- const CallEvent *Call,
- ArrayRef<SVal> ConstValues) const;
+ InvalidatedSymbols *IS,
+ RegionAndSymbolInvalidationTraits *HTraits,
+ const CallEvent *Call) const;
};
//===----------------------------------------------------------------------===//
/// the given regions. Optionally, invalidates non-static globals as well.
/// \param[in] store The initial store
/// \param[in] Values The values to invalidate.
- /// \param[in] ConstValues The values to invalidate; these are known to be
- /// const, so only regions accesible from them should be invalidated.
/// \param[in] E The current statement being evaluated. Used to conjure
/// symbols to mark the values of invalidated regions.
/// \param[in] Count The current block count. Used to conjure
/// globals should get invalidated.
/// \param[in,out] IS A set to fill with any symbols that are no longer
/// accessible. Pass \c NULL if this information will not be used.
- /// \param[in,out] ConstIS A set to fill with any symbols corresponding to
- /// the ConstValues.
+ /// \param[in] ITraits Information about invalidation for a particular
+ /// region/symbol.
/// \param[in,out] InvalidatedTopLevel A vector to fill with regions
- //// explicitely being invalidated. Pass \c NULL if this
- /// information will not be used.
- /// \param[in,out] InvalidatedTopLevelConst A vector to fill with const
- //// regions explicitely being invalidated. Pass \c NULL if this
+ //// explicitly being invalidated. Pass \c NULL if this
/// information will not be used.
/// \param[in,out] Invalidated A vector to fill with any regions being
/// invalidated. This should include any regions explicitly invalidated
/// information will not be used.
virtual StoreRef invalidateRegions(Store store,
ArrayRef<SVal> Values,
- ArrayRef<SVal> ConstValues,
const Expr *E, unsigned Count,
const LocationContext *LCtx,
const CallEvent *Call,
InvalidatedSymbols &IS,
- InvalidatedSymbols &ConstIS,
+ RegionAndSymbolInvalidationTraits &ITraits,
InvalidatedRegions *InvalidatedTopLevel,
- InvalidatedRegions *InvalidatedTopLevelConst,
InvalidatedRegions *Invalidated) = 0;
/// enterStackFrame - Let the StoreManager to do something when execution
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call,
- bool IsConst = false) = 0;
+ RegionAndSymbolInvalidationTraits &HTraits) = 0;
/// printState - Called by ProgramStateManager to print checker-specific data.
virtual void printState(raw_ostream &Out, ProgramStateRef State,
ProgramStateRef Orig) const {
ProgramStateRef Result = (Orig ? Orig : getState());
- SmallVector<SVal, 8> ConstValues;
SmallVector<SVal, 8> ValuesToInvalidate;
+ RegionAndSymbolInvalidationTraits ETraits;
getExtraInvalidatedValues(ValuesToInvalidate);
// Mark this region for invalidation. We batch invalidate regions
// below for efficiency.
if (PreserveArgs.count(Idx))
- ConstValues.push_back(getArgSVal(Idx));
- else
- ValuesToInvalidate.push_back(getArgSVal(Idx));
+ if (const MemRegion *MR = getArgSVal(Idx).getAsRegion())
+ ETraits.setTrait(MR->StripCasts(),
+ RegionAndSymbolInvalidationTraits::TK_PreserveContents);
+ // TODO: Factor this out + handle the lower level const pointers.
+
+ ValuesToInvalidate.push_back(getArgSVal(Idx));
}
// Invalidate designated regions using the batch invalidation API.
return Result->invalidateRegions(ValuesToInvalidate, getOriginExpr(),
BlockCount, getLocationContext(),
/*CausedByPointerEscape*/ true,
- /*Symbols=*/0, this, ConstValues);
+ /*Symbols=*/0, this, &ETraits);
}
ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
/// \brief Run checkers to process symbol escape event.
ProgramStateRef
CheckerManager::runCheckersForPointerEscape(ProgramStateRef State,
- const InvalidatedSymbols &Escaped,
- const CallEvent *Call,
- PointerEscapeKind Kind,
- bool IsConst) {
+ const InvalidatedSymbols &Escaped,
+ const CallEvent *Call,
+ PointerEscapeKind Kind,
+ RegionAndSymbolInvalidationTraits *ETraits) {
assert((Call != NULL ||
(Kind != PSK_DirectEscapeOnCall &&
Kind != PSK_IndirectEscapeOnCall)) &&
// way), bail out.
if (!State)
return NULL;
- State = PointerEscapeCheckers[i](State, Escaped, Call, Kind, IsConst);
+ State = PointerEscapeCheckers[i](State, Escaped, Call, Kind, ETraits);
}
return State;
}
State = getCheckerManager().runCheckersForPointerEscape(State,
EscapedSymbols,
/*CallEvent*/ 0,
- PSK_EscapeOnBind);
+ PSK_EscapeOnBind,
+ 0);
return State;
}
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call,
- bool IsConst) {
+ RegionAndSymbolInvalidationTraits &ITraits) {
if (!Invalidated || Invalidated->empty())
return State;
*Invalidated,
0,
PSK_EscapeOther,
- IsConst);
-
- // Note: Due to current limitations of RegionStore, we only process the top
- // level const pointers correctly. The lower level const pointers are
- // currently treated as non-const.
- if (IsConst)
- return getCheckerManager().runCheckersForPointerEscape(State,
- *Invalidated,
- Call,
- PSK_DirectEscapeOnCall,
- true);
+ &ITraits);
// If the symbols were invalidated by a call, we want to find out which ones
// were invalidated directly due to being arguments to the call.
if (!SymbolsDirectlyInvalidated.empty())
State = getCheckerManager().runCheckersForPointerEscape(State,
- SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall);
+ SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall, &ITraits);
// Notify about the symbols that get indirectly invalidated by the call.
if (!SymbolsIndirectlyInvalidated.empty())
State = getCheckerManager().runCheckersForPointerEscape(State,
- SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall);
+ SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall, &ITraits);
return State;
}
}
return 0;
}
+
+//===----------------------------------------------------------------------===//
+// RegionAndSymbolInvalidationTraits
+//===----------------------------------------------------------------------===//
+
+void RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym,
+ InvalidationKinds IK) {
+ SymTraitsMap[Sym] |= IK;
+}
+
+void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
+ InvalidationKinds IK) {
+ assert(MR);
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
+ setTrait(SR->getSymbol(), IK);
+ else
+ MRTraitsMap[MR] |= IK;
+}
+
+bool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym,
+ InvalidationKinds IK) {
+ const_symbol_iterator I = SymTraitsMap.find(Sym);
+ if (I != SymTraitsMap.end())
+ return I->second & IK;
+
+ return false;
+}
+
+bool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR,
+ InvalidationKinds IK) {
+ if (!MR)
+ return false;
+
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
+ return hasTrait(SR->getSymbol(), IK);
+
+ const_region_iterator I = MRTraitsMap.find(MR);
+ if (I != MRTraitsMap.end())
+ return I->second & IK;
+
+ return false;
+}
ProgramStateRef
ProgramState::invalidateRegions(RegionList Regions,
- const Expr *E, unsigned Count,
- const LocationContext *LCtx,
- bool CausedByPointerEscape,
- InvalidatedSymbols *IS,
- const CallEvent *Call,
- RegionList ConstRegions) const {
+ const Expr *E, unsigned Count,
+ const LocationContext *LCtx,
+ bool CausedByPointerEscape,
+ InvalidatedSymbols *IS,
+ const CallEvent *Call,
+ RegionAndSymbolInvalidationTraits *ITraits) const {
SmallVector<SVal, 8> Values;
for (RegionList::const_iterator I = Regions.begin(),
End = Regions.end(); I != End; ++I)
Values.push_back(loc::MemRegionVal(*I));
- SmallVector<SVal, 8> ConstValues;
- for (RegionList::const_iterator I = ConstRegions.begin(),
- End = ConstRegions.end(); I != End; ++I)
- ConstValues.push_back(loc::MemRegionVal(*I));
-
- if (!IS) {
- InvalidatedSymbols invalidated;
- return invalidateRegionsImpl(Values, E, Count, LCtx,
- CausedByPointerEscape,
- invalidated, Call, ConstValues);
- }
return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
- *IS, Call, ConstValues);
+ IS, ITraits, Call);
}
ProgramStateRef
ProgramState::invalidateRegions(ValueList Values,
- const Expr *E, unsigned Count,
- const LocationContext *LCtx,
- bool CausedByPointerEscape,
- InvalidatedSymbols *IS,
- const CallEvent *Call,
- ValueList ConstValues) const {
- if (!IS) {
- InvalidatedSymbols invalidated;
- return invalidateRegionsImpl(Values, E, Count, LCtx,
- CausedByPointerEscape,
- invalidated, Call, ConstValues);
- }
+ const Expr *E, unsigned Count,
+ const LocationContext *LCtx,
+ bool CausedByPointerEscape,
+ InvalidatedSymbols *IS,
+ const CallEvent *Call,
+ RegionAndSymbolInvalidationTraits *ITraits) const {
+
return invalidateRegionsImpl(Values, E, Count, LCtx, CausedByPointerEscape,
- *IS, Call, ConstValues);
+ IS, ITraits, Call);
}
ProgramStateRef
const Expr *E, unsigned Count,
const LocationContext *LCtx,
bool CausedByPointerEscape,
- InvalidatedSymbols &IS,
- const CallEvent *Call,
- ValueList ConstValues) const {
+ InvalidatedSymbols *IS,
+ RegionAndSymbolInvalidationTraits *ITraits,
+ const CallEvent *Call) const {
ProgramStateManager &Mgr = getStateManager();
SubEngine* Eng = Mgr.getOwningEngine();
InvalidatedSymbols ConstIS;
+ InvalidatedSymbols Invalidated;
+ if (!IS)
+ IS = &Invalidated;
+
+ RegionAndSymbolInvalidationTraits ITraitsLocal;
+ if (!ITraits)
+ ITraits = &ITraitsLocal;
+
if (Eng) {
StoreManager::InvalidatedRegions TopLevelInvalidated;
- StoreManager::InvalidatedRegions TopLevelConstInvalidated;
StoreManager::InvalidatedRegions Invalidated;
const StoreRef &newStore
- = Mgr.StoreMgr->invalidateRegions(getStore(), Values, ConstValues,
- E, Count, LCtx, Call,
- IS, ConstIS,
- &TopLevelInvalidated,
- &TopLevelConstInvalidated,
+ = Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
+ *IS, *ITraits, &TopLevelInvalidated,
&Invalidated);
ProgramStateRef newState = makeWithStore(newStore);
if (CausedByPointerEscape) {
- newState = Eng->notifyCheckersOfPointerEscape(newState, &IS,
+ newState = Eng->notifyCheckersOfPointerEscape(newState, IS,
TopLevelInvalidated,
- Invalidated, Call);
- if (!ConstValues.empty()) {
- StoreManager::InvalidatedRegions Empty;
- newState = Eng->notifyCheckersOfPointerEscape(newState, &ConstIS,
- TopLevelConstInvalidated,
- Empty, Call,
- true);
- }
+ Invalidated, Call,
+ *ITraits);
}
- return Eng->processRegionChanges(newState, &IS,
- TopLevelInvalidated, Invalidated,
- Call);
+ return Eng->processRegionChanges(newState, IS, TopLevelInvalidated,
+ Invalidated, Call);
}
const StoreRef &newStore =
- Mgr.StoreMgr->invalidateRegions(getStore(), Values, ConstValues,
- E, Count, LCtx, Call,
- IS, ConstIS, NULL, NULL, NULL);
+ Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
+ *IS, *ITraits, NULL, NULL);
return makeWithStore(newStore);
}
/// regions.
void populateWorkList(invalidateRegionsWorker &W,
ArrayRef<SVal> Values,
- bool IsArrayOfConstRegions,
InvalidatedRegions *TopLevelRegions);
public:
StoreRef invalidateRegions(Store store,
ArrayRef<SVal> Values,
- ArrayRef<SVal> ConstValues,
const Expr *E, unsigned Count,
const LocationContext *LCtx,
const CallEvent *Call,
InvalidatedSymbols &IS,
- InvalidatedSymbols &ConstIS,
+ RegionAndSymbolInvalidationTraits &ITraits,
InvalidatedRegions *Invalidated,
- InvalidatedRegions *InvalidatedTopLevel,
- InvalidatedRegions *InvalidatedTopLevelConst);
+ InvalidatedRegions *InvalidatedTopLevel);
bool scanReachableSymbols(Store S, const MemRegion *R,
ScanReachableSymbols &Callbacks);
class ClusterAnalysis {
protected:
typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
- typedef llvm::PointerIntPair<const MemRegion *, 1, bool> WorkListElement;
+ typedef const MemRegion * WorkListElement;
typedef SmallVector<WorkListElement, 10> WorkList;
llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
return true;
}
- bool AddToWorkList(const MemRegion *R, bool Flag = false) {
+ bool AddToWorkList(const MemRegion *R) {
const MemRegion *BaseR = R->getBaseRegion();
- return AddToWorkList(WorkListElement(BaseR, Flag), getCluster(BaseR));
+ return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
}
void RunWorkList() {
while (!WL.empty()) {
WorkListElement E = WL.pop_back_val();
- const MemRegion *BaseR = E.getPointer();
+ const MemRegion *BaseR = E;
- static_cast<DERIVED*>(this)->VisitCluster(BaseR, getCluster(BaseR),
- E.getInt());
+ static_cast<DERIVED*>(this)->VisitCluster(BaseR, getCluster(BaseR));
}
}
unsigned Count;
const LocationContext *LCtx;
InvalidatedSymbols &IS;
- InvalidatedSymbols &ConstIS;
+ RegionAndSymbolInvalidationTraits &ITraits;
StoreManager::InvalidatedRegions *Regions;
public:
invalidateRegionsWorker(RegionStoreManager &rm,
const Expr *ex, unsigned count,
const LocationContext *lctx,
InvalidatedSymbols &is,
- InvalidatedSymbols &inConstIS,
+ RegionAndSymbolInvalidationTraits &ITraitsIn,
StoreManager::InvalidatedRegions *r,
GlobalsFilterKind GFK)
: ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b, GFK),
- Ex(ex), Count(count), LCtx(lctx), IS(is), ConstIS(inConstIS), Regions(r){}
+ Ex(ex), Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r){}
/// \param IsConst Specifies if the region we are invalidating is constant.
/// If it is, we invalidate all subregions, but not the base region itself.
- void VisitCluster(const MemRegion *baseR, const ClusterBindings *C,
- bool IsConst);
+ void VisitCluster(const MemRegion *baseR, const ClusterBindings *C);
void VisitBinding(SVal V);
};
}
}
void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
- const ClusterBindings *C,
- bool IsConst) {
+ const ClusterBindings *C) {
+
+ bool PreserveRegionsContents =
+ ITraits.hasTrait(baseR,
+ RegionAndSymbolInvalidationTraits::TK_PreserveContents);
+
if (C) {
for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I)
VisitBinding(I.getData());
- // Invalidate the contents of a non-const base region.
- if (!IsConst)
+ // Invalidate regions contents.
+ if (!PreserveRegionsContents)
B = B.remove(baseR);
}
}
// Symbolic region?
- if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
- SymbolRef RegionSym = SR->getSymbol();
-
- // Mark that symbol touched by the invalidation.
- if (IsConst)
- ConstIS.insert(RegionSym);
- else
- IS.insert(RegionSym);
- }
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
+ IS.insert(SR->getSymbol());
- // Nothing else should be done for a const region.
- if (IsConst)
+ // Nothing else should be done in the case when we preserve regions context.
+ if (PreserveRegionsContents)
return;
// Otherwise, we have a normal data region. Record that we touched the region.
if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
// Invalidate the region by setting its default value to
- // conjured symbol. The type of the symbol is irrelavant.
+ // conjured symbol. The type of the symbol is irrelevant.
DefinedOrUnknownSVal V =
svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.IntTy, Count);
B = B.addBinding(baseR, BindingKey::Default, V);
if (T->isStructureOrClassType()) {
// Invalidate the region by setting its default value to
- // conjured symbol. The type of the symbol is irrelavant.
+ // conjured symbol. The type of the symbol is irrelevant.
DefinedOrUnknownSVal V = svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
Ctx.IntTy, Count);
B = B.addBinding(baseR, BindingKey::Default, V);
void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
ArrayRef<SVal> Values,
- bool IsArrayOfConstRegions,
InvalidatedRegions *TopLevelRegions) {
for (ArrayRef<SVal>::iterator I = Values.begin(),
E = Values.end(); I != E; ++I) {
// Note: the last argument is false here because these are
// non-top-level regions.
if (const MemRegion *R = (*I).getAsRegion())
- W.AddToWorkList(R, /*IsConst=*/ false);
+ W.AddToWorkList(R);
}
continue;
}
if (const MemRegion *R = V.getAsRegion()) {
if (TopLevelRegions)
TopLevelRegions->push_back(R);
- W.AddToWorkList(R, /*IsConst=*/ IsArrayOfConstRegions);
+ W.AddToWorkList(R);
continue;
}
}
StoreRef
RegionStoreManager::invalidateRegions(Store store,
- ArrayRef<SVal> Values,
- ArrayRef<SVal> ConstValues,
- const Expr *Ex, unsigned Count,
- const LocationContext *LCtx,
- const CallEvent *Call,
- InvalidatedSymbols &IS,
- InvalidatedSymbols &ConstIS,
- InvalidatedRegions *TopLevelRegions,
- InvalidatedRegions *TopLevelConstRegions,
- InvalidatedRegions *Invalidated) {
+ ArrayRef<SVal> Values,
+ const Expr *Ex, unsigned Count,
+ const LocationContext *LCtx,
+ const CallEvent *Call,
+ InvalidatedSymbols &IS,
+ RegionAndSymbolInvalidationTraits &ITraits,
+ InvalidatedRegions *TopLevelRegions,
+ InvalidatedRegions *Invalidated) {
GlobalsFilterKind GlobalsFilter;
if (Call) {
if (Call->isInSystemHeader())
}
RegionBindingsRef B = getRegionBindings(store);
- invalidateRegionsWorker W(*this, StateMgr, B, Ex, Count, LCtx, IS, ConstIS,
+ invalidateRegionsWorker W(*this, StateMgr, B, Ex, Count, LCtx, IS, ITraits,
Invalidated, GlobalsFilter);
// Scan the bindings and generate the clusters.
W.GenerateClusters();
// Add the regions to the worklist.
- populateWorkList(W, Values, /*IsArrayOfConstRegions*/ false,
- TopLevelRegions);
- populateWorkList(W, ConstValues, /*IsArrayOfConstRegions*/ true,
- TopLevelConstRegions);
+ populateWorkList(W, Values, TopLevelRegions);
W.RunWorkList();