[cfe-dev] Proposed: change tracking for RegionStore
Jordy Rose
jediknil at belkadan.com
Wed Aug 4 23:01:05 PDT 2010
OK, here's a first pass at ProcessRegionChange.
The first note is that I didn't choose to call it for every change to the
store.
Included: bindLoc, bindDefault, InvalidateRegions
Excluded: bindCompoundLiteral, bindDecl, bindDeclWithNoInit, unbindLoc,
EnterStackFrame
The reason for this is that the excluded calls only /add/ regions to the
store; they do not change existing bindings. It follows that a checker
cannot already be tracking a region that has not existed until this point.
(Arguably, bindDefault should be here too, since it's currently only used
for new regions.) unbindLoc is a special case since it's not used for
regions at all.
The second note is that it requires a ridiculous cross-indexing sort of
search to be useful: if I'm tracking the strlen of region X, that length is
invalid if any of X's subregions /or/ super-regions change. This results in
the code seen in the attached txt snippet. Is there a better way to set
this up that would make this neater?
Finally, the bind* covers in GRState are getting a little bulky for inline
functions. At what point would we give up on the efficiency gain and move
them to GRState.cpp?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ProcessRegionChanges.patch
Type: text/x-diff
Size: 9387 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100804/ff1c06c2/attachment.patch>
-------------- next part --------------
const GRState *CStringChecker::EvalRegionChanges(const GRState *state,
const MemRegion * const *Begin,
const MemRegion * const *End,
bool *respondsToCallback) {
llvm::SmallPtrSet<const MemRegion *, 8> SuperRegions;
for ( ; Begin != End; ++Begin) {
CStringLength::EntryMap Entries = state->get<CStringLength>();
// First build a list of the changed region's super-regions.
const MemRegion *MR = *Begin;
SuperRegions.clear();
SuperRegions.insert(MR);
while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) {
MR = SR->getSuperRegion();
SuperRegions.insert(MR);
}
// Then loop over the entries in the current state.
for (CStringLength::EntryMap::iterator I = Entries.begin(),
E = Entries.end(); I != E; ++I) {
MR = I.getKey();
// Is this entry for a super-region of the changed region?
if (SuperRegions.count(MR)) {
state = state->remove<CStringLength>(MR);
continue;
}
// Is this entry for a sub-region of the changed region?
while (const SubRegion *SR = dyn_cast<SubRegion>(MR)) {
MR = SR->getSuperRegion();
if (MR == *Begin) {
state = state->remove<CStringLength>(MR);
break;
}
}
}
}
return state;
}
More information about the cfe-dev
mailing list