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)); }
/// Cleaning up the program state. void NullabilityChecker::checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const { if (!SR.hasDeadSymbols()) return; 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 (checkPreconditionViolation(State, C.getPredecessor(), C)) return; 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); } }