void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR,
                                               CheckerContext &C) const {
  ProgramStateRef State = C.getState();
  AllocatedDataTy ASet = State->get<AllocatedData>();
  if (ASet.isEmpty())
    return;

  bool Changed = false;
  AllocationPairVec Errors;
  for (AllocatedDataTy::iterator I = ASet.begin(), E = ASet.end(); I != E; ++I) {
    if (SR.isLive(I->first))
      continue;

    Changed = true;
    State = State->remove<AllocatedData>(I->first);
    // If the allocated symbol is null or if the allocation call might have
    // returned an error, do not report.
    ConstraintManager &CMgr = State->getConstraintManager();
    ConditionTruthVal AllocFailed = CMgr.isNull(State, I.getKey());
    if (AllocFailed.isConstrainedTrue() ||
        definitelyReturnedError(I->second.Region, State, C.getSValBuilder()))
      continue;
    Errors.push_back(std::make_pair(I->first, &I->second));
  }
  if (!Changed) {
    // Generate the new, cleaned up state.
    C.addTransition(State);
    return;
  }

  static SimpleProgramPointTag Tag("MacOSKeychainAPIChecker : DeadSymbolsLeak");
  ExplodedNode *N = C.addTransition(C.getState(), C.getPredecessor(), &Tag);

  // Generate the error reports.
  for (AllocationPairVec::iterator I = Errors.begin(), E = Errors.end();
                                                       I != E; ++I) {
    C.emitReport(generateAllocatedDataNotReleasedReport(*I, N, C));
  }

  // Generate the new, cleaned up state.
  C.addTransition(State, N);
}
// TODO: Remove this after we ensure that checkDeadSymbols are always called.
void MacOSKeychainAPIChecker::checkEndPath(CheckerContext &Ctx) const {
  const ProgramState *state = Ctx.getState();
  AllocatedSetTy AS = state->get<AllocatedData>();
  if (AS.isEmpty())
    return;

  // Anything which has been allocated but not freed (nor escaped) will be
  // found here, so report it.
  bool Changed = false;
  AllocationPairVec Errors;
  for (AllocatedSetTy::iterator I = AS.begin(), E = AS.end(); I != E; ++I ) {
    Changed = true;
    state = state->remove<AllocatedData>(I->first);
    // If the allocated symbol is null or if error code was returned at
    // allocation, do not report.
    if (state->getSymVal(I.getKey()) ||
        definitelyReturnedError(I->second.Region, state,
                                Ctx.getSValBuilder())) {
      continue;
    }
    Errors.push_back(std::make_pair(I->first, &I->second));
  }

  // If no change, do not generate a new state.
  if (!Changed)
    return;

  ExplodedNode *N = Ctx.addTransition(state);
  if (!N)
    return;

  // Generate the error reports.
  for (AllocationPairVec::iterator I = Errors.begin(), E = Errors.end();
                                                       I != E; ++I) {
    Ctx.EmitReport(generateAllocatedDataNotReleasedReport(*I, N));
  }
}
void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR,
                                               CheckerContext &C) const {
  const ProgramState *State = C.getState();
  AllocatedSetTy ASet = State->get<AllocatedData>();
  if (ASet.isEmpty())
    return;

  bool Changed = false;
  AllocationPairVec Errors;
  for (AllocatedSetTy::iterator I = ASet.begin(), E = ASet.end(); I != E; ++I) {
    if (SR.isLive(I->first))
      continue;

    Changed = true;
    State = State->remove<AllocatedData>(I->first);
    // If the allocated symbol is null or if the allocation call might have
    // returned an error, do not report.
    if (State->getSymVal(I->first) ||
        definitelyReturnedError(I->second.Region, State, C.getSValBuilder()))
      continue;
    Errors.push_back(std::make_pair(I->first, &I->second));
  }
  if (!Changed)
    return;

  // Generate the new, cleaned up state.
  ExplodedNode *N = C.addTransition(State);
  if (!N)
    return;

  // Generate the error reports.
  for (AllocationPairVec::iterator I = Errors.begin(), E = Errors.end();
                                                       I != E; ++I) {
    C.EmitReport(generateAllocatedDataNotReleasedReport(*I, N));
  }
}