ProgramStateRef
ObjCLoopChecker::checkPointerEscape(ProgramStateRef State,
                                    const InvalidatedSymbols &Escaped,
                                    const CallEvent *Call,
                                    PointerEscapeKind Kind) const {
  SymbolRef ImmutableReceiver = getMethodReceiverIfKnownImmutable(Call);

  // Remove the invalidated symbols form the collection count map.
  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
       E = Escaped.end();
       I != E; ++I) {
    SymbolRef Sym = *I;

    // Don't invalidate this symbol's count if we know the method being called
    // is declared on an immutable class. This isn't completely correct if the
    // receiver is also passed as an argument, but in most uses of NSArray,
    // NSDictionary, etc. this isn't likely to happen in a dangerous way.
    if (Sym == ImmutableReceiver)
      continue;

    // The symbol escaped. Pessimistically, assume that the count could have
    // changed.
    State = State->remove<ContainerCountMap>(Sym);
    State = State->remove<ContainerNonEmptyMap>(Sym);
  }
  return State;
}
Пример #2
0
ProgramStateRef
ObjCContainersChecker::checkPointerEscape(ProgramStateRef State,
                                          const InvalidatedSymbols &Escaped,
                                          const CallEvent *Call,
                                          PointerEscapeKind Kind) const {
  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
                                          E = Escaped.end();
                                          I != E; ++I) {
    SymbolRef Sym = *I;
    // When a symbol for a mutable array escapes, we can't reason precisely
    // about its size any more -- so remove it from the map.
    // Note that we aren't notified here when a CFMutableArrayRef escapes as a
    // CFArrayRef. This is because CFArrayRef is typedef'd as a pointer to a
    // const-qualified type.
    State = State->remove<ArraySizeMap>(Sym);
  }
  return State;
}
ProgramStateRef
ObjCLoopChecker::checkPointerEscape(ProgramStateRef State,
                                    const InvalidatedSymbols &Escaped,
                                    const CallEvent *Call,
                                    PointerEscapeKind Kind) const {
    // TODO: If we know that the call cannot change the collection count, there
    // is nothing to do, just return.

    // Remove the invalidated symbols form the collection count map.
    for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
            E = Escaped.end();
            I != E; ++I) {
        SymbolRef Sym = *I;

        // The symbol escaped. Pessimistically, assume that the count could have
        // changed.
        State = State->remove<ContainerCountMap>(Sym);
    }
    return State;
}
Пример #4
0
// If the pointer we are tracking escaped, do not track the symbol as
// we cannot reason about it anymore.
ProgramStateRef
SimpleStreamChecker::checkPointerEscape(ProgramStateRef State,
                                        const InvalidatedSymbols &Escaped,
                                        const CallEvent *Call,
                                        PointerEscapeKind Kind) const {
  // If we know that the call cannot close a file, there is nothing to do.
  if (Kind == PSK_DirectEscapeOnCall && guaranteedNotToCloseFile(*Call)) {
    return State;
  }

  for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
                                          E = Escaped.end();
                                          I != E; ++I) {
    SymbolRef Sym = *I;

    // The symbol escaped. Optimistically, assume that the corresponding file
    // handle will be closed somewhere else.
    State = State->remove<StreamMap>(Sym);
  }
  return State;
}