void IteratorChecker::checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const { // Cleanup auto State = C.getState(); auto RegionMap = State->get<IteratorRegionMap>(); for (const auto Reg : RegionMap) { if (!SR.isLiveRegion(Reg.first)) { State = State->remove<IteratorRegionMap>(Reg.first); } } auto SymbolMap = State->get<IteratorSymbolMap>(); for (const auto Sym : SymbolMap) { if (!SR.isLive(Sym.first)) { State = State->remove<IteratorSymbolMap>(Sym.first); } } auto ContMap = State->get<ContainerMap>(); for (const auto Cont : ContMap) { if (!SR.isLiveRegion(Cont.first)) { State = State->remove<ContainerMap>(Cont.first); } } auto ComparisonMap = State->get<IteratorComparisonMap>(); for (const auto Comp : ComparisonMap) { if (!SR.isLive(Comp.first)) { State = State->remove<IteratorComparisonMap>(Comp.first); } } }
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 MoveChecker::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { ProgramStateRef State = C.getState(); TrackedRegionMapTy TrackedRegions = State->get<TrackedRegionMap>(); for (TrackedRegionMapTy::value_type E : TrackedRegions) { const MemRegion *Region = E.first; bool IsRegDead = !SymReaper.isLiveRegion(Region); // Remove the dead regions from the region map. if (IsRegDead) { State = State->remove<TrackedRegionMap>(Region); } } C.addTransition(State); }
/// 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) { if (!SR.isLiveRegion(I->first)) { 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 (checkPreconditionViolation(State, C.getPredecessor(), C)) return; C.addTransition(State); }
void InnerPointerChecker::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { ProgramStateRef State = C.getState(); PtrSet::Factory &F = State->getStateManager().get_context<PtrSet>(); RawPtrMapTy RPM = State->get<RawPtrMap>(); for (const auto Entry : RPM) { if (!SymReaper.isLiveRegion(Entry.first)) { // Due to incomplete destructor support, some dead regions might // remain in the program state map. Clean them up. State = State->remove<RawPtrMap>(Entry.first); } if (const PtrSet *OldSet = State->get<RawPtrMap>(Entry.first)) { PtrSet CleanedUpSet = *OldSet; for (const auto Symbol : Entry.second) { if (!SymReaper.isLive(Symbol)) CleanedUpSet = F.remove(CleanedUpSet, Symbol); } State = CleanedUpSet.isEmpty() ? State->remove<RawPtrMap>(Entry.first) : State->set<RawPtrMap>(Entry.first, CleanedUpSet); } } C.addTransition(State); }
void MPIChecker::checkMissingWaits(SymbolReaper &SymReaper, CheckerContext &Ctx) const { if (!SymReaper.hasDeadSymbols()) return; ProgramStateRef State = Ctx.getState(); const auto &Requests = State->get<RequestMap>(); if (Requests.isEmpty()) return; static CheckerProgramPointTag Tag("MPI-Checker", "MissingWait"); ExplodedNode *ErrorNode{nullptr}; auto ReqMap = State->get<RequestMap>(); for (const auto &Req : ReqMap) { if (!SymReaper.isLiveRegion(Req.first)) { if (Req.second.CurrentState == Request::State::Nonblocking) { if (!ErrorNode) { ErrorNode = Ctx.generateNonFatalErrorNode(State, &Tag); State = ErrorNode->getState(); } BReporter.reportMissingWait(Req.second, Req.first, ErrorNode, Ctx.getBugReporter()); } State = State->remove<RequestMap>(Req.first); } } // Transition to update the state regarding removed requests. if (!ErrorNode) { Ctx.addTransition(State); } else { Ctx.addTransition(State, ErrorNode); } }