[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