void DynamicTypePropagation::checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const { ProgramStateRef State = C.getState(); DynamicTypeMapImpl TypeMap = State->get<DynamicTypeMap>(); for (DynamicTypeMapImpl::iterator I = TypeMap.begin(), E = TypeMap.end(); I != E; ++I) { if (!SR.isLiveRegion(I->first)) { State = State->remove<DynamicTypeMap>(I->first); } } if (!SR.hasDeadSymbols()) { C.addTransition(State); return; } MostSpecializedTypeArgsMapTy TyArgMap = State->get<MostSpecializedTypeArgsMap>(); for (MostSpecializedTypeArgsMapTy::iterator I = TyArgMap.begin(), E = TyArgMap.end(); I != E; ++I) { if (SR.isDead(I->first)) { State = State->remove<MostSpecializedTypeArgsMap>(I->first); } } C.addTransition(State); }
void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { if (!SymReaper.hasDeadSymbols()) return; const GRState *state = C.getState(); RegionStateTy RS = state->get<RegionState>(); RegionStateTy::Factory &F = state->get_context<RegionState>(); for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { if (SymReaper.isDead(I->first)) { if (I->second.isAllocated()) { if (ExplodedNode *N = C.generateNode()) { if (!BT_Leak) BT_Leak.reset(new BuiltinBug("Memory leak", "Allocated memory never released. Potential memory leak.")); // FIXME: where it is allocated. BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N); C.EmitReport(R); } } // Remove the dead symbol from the map. RS = F.remove(RS, I->first); } } C.generateNode(state->set<RegionState>(RS)); }
void ObjCLoopChecker::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { ProgramStateRef State = C.getState(); // Remove the dead symbols from the collection count map. ContainerCountMapTy Tracked = State->get<ContainerCountMap>(); for (ContainerCountMapTy::iterator I = Tracked.begin(), E = Tracked.end(); I != E; ++I) { SymbolRef Sym = I->first; if (SymReaper.isDead(Sym)) State = State->remove<ContainerCountMap>(Sym); } C.addTransition(State); }
void PthreadLockChecker::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { ProgramStateRef State = C.getState(); // TODO: Clean LockMap when a mutex region dies. DestroyRetValTy TrackedSymbols = State->get<DestroyRetVal>(); for (DestroyRetValTy::iterator I = TrackedSymbols.begin(), E = TrackedSymbols.end(); I != E; ++I) { const SymbolRef Sym = I->second; const MemRegion *lockR = I->first; bool IsSymDead = SymReaper.isDead(Sym); // Remove the dead symbol from the return value symbols map. if (IsSymDead) State = resolvePossiblyDestroyedMutex(State, lockR, &Sym); } C.addTransition(State); }
// Use not for leaks but useful to remove our stored symbols void iOSAppSecInsecureKeyChainStorageChecker::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { ProgramStateRef pProgState = C.getState() ; StreamMapTy TrackedStreams = pProgState ->get<StreamMap>() ; for (StreamMapTy::iterator I = TrackedStreams.begin(), E = TrackedStreams.end(); I != E; ++I) { SymbolRef pSymbol = I ->first ; // Remove the dead symbol from the streams map. if ( SymReaper.isDead( pSymbol ) ) { pProgState = pProgState -> remove<StreamMap>( pSymbol ) ; } } C.addTransition( pProgState ) ; }
/// Cleaning up the program state. void NullabilityChecker::checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const { ProgramStateRef State = C.getState(); NullabilityMapTy Nullabilities = State->get<NullabilityMap>(); for (NullabilityMapTy::iterator I = Nullabilities.begin(), E = Nullabilities.end(); I != E; ++I) { const auto *Region = I->first->getAs<SymbolicRegion>(); assert(Region && "Non-symbolic region is tracked."); if (SR.isDead(Region->getSymbol())) { State = State->remove<NullabilityMap>(I->first); } } // When one of the nonnull arguments are constrained to be null, nullability // preconditions are violated. It is not enough to check this only when we // actually report an error, because at that time interesting symbols might be // reaped. if (checkInvariantViolation(State, C.getPredecessor(), C)) return; C.addTransition(State); }
void SimpleStreamChecker::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { ProgramStateRef State = C.getState(); SymbolVector LeakedStreams; StreamMapTy TrackedStreams = State->get<StreamMap>(); for (StreamMapTy::iterator I = TrackedStreams.begin(), E = TrackedStreams.end(); I != E; ++I) { SymbolRef Sym = I->first; bool IsSymDead = SymReaper.isDead(Sym); // Collect leaked symbols. if (isLeaked(Sym, I->second, IsSymDead, State)) LeakedStreams.push_back(Sym); // Remove the dead symbol from the streams map. if (IsSymDead) State = State->remove<StreamMap>(Sym); } ExplodedNode *N = C.addTransition(State); reportLeaks(LeakedStreams, C, N); }