class EndFunction {
template <typename CHECKER>
- static void _checkEndFunction(void *checker,
+ static void _checkEndFunction(void *checker, const ReturnStmt *RS,
CheckerContext &C) {
- ((const CHECKER *)checker)->checkEndFunction(C);
+ ((const CHECKER *)checker)->checkEndFunction(RS, C);
}
public:
void runCheckersForEndFunction(NodeBuilderContext &BC,
ExplodedNodeSet &Dst,
ExplodedNode *Pred,
- ExprEngine &Eng);
+ ExprEngine &Eng,
+ const ReturnStmt *RS);
/// Run checkers for branch condition.
void runCheckersForBranchCondition(const Stmt *condition,
using CheckBeginFunctionFunc = CheckerFn<void (CheckerContext &)>;
- using CheckEndFunctionFunc = CheckerFn<void (CheckerContext &)>;
+ using CheckEndFunctionFunc =
+ CheckerFn<void (const ReturnStmt *, CheckerContext &)>;
using CheckBranchConditionFunc =
CheckerFn<void (const Stmt *, CheckerContext &)>;
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
- void _registerForBeginFunction(CheckEndFunctionFunc checkfn);
+ void _registerForBeginFunction(CheckBeginFunctionFunc checkfn);
void _registerForEndFunction(CheckEndFunctionFunc checkfn);
void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
const CallEvent *Call,
PointerEscapeKind Kind) const;
void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
- void checkEndFunction(CheckerContext &Ctx) const;
+ void checkEndFunction(const ReturnStmt *RS, CheckerContext &Ctx) const;
private:
void diagnoseMissingReleases(CheckerContext &C) const;
/// Check for missing releases even when -dealloc does not call
/// '[super dealloc]'.
void ObjCDeallocChecker::checkEndFunction(
- CheckerContext &C) const {
+ const ReturnStmt *RS, CheckerContext &C) const {
diagnoseMissingReleases(C);
}
/// level or is inlined.
///
/// check::EndFunction
- void checkEndFunction(CheckerContext &Ctx) const {}
+ void checkEndFunction(const ReturnStmt *RS, CheckerContext &Ctx) const {}
/// Called after all the paths in the ExplodedGraph reach end of path
/// - the symbolic execution graph is fully explored.
: public Checker<check::PreCall, check::PostCall, check::EndFunction,
check::DeadSymbols, check::RegionChanges> {
public:
- void checkEndFunction(CheckerContext &C) const;
+ void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
void checkPreCall(const CallEvent &MC, CheckerContext &C) const;
void checkPostCall(const CallEvent &MC, CheckerContext &C) const;
void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
// Removing the function parameters' MemRegion from the state. This is needed
// for PODs where the trivial destructor does not even created nor executed.
-void MisusedMovedObjectChecker::checkEndFunction(CheckerContext &C) const {
+void MisusedMovedObjectChecker::checkEndFunction(const ReturnStmt *RS,
+ CheckerContext &C) const {
auto State = C.getState();
TrackedRegionMapTy Objects = State->get<TrackedRegionMap>();
if (Objects.isEmpty())
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
void checkBeginFunction(CheckerContext &C) const;
- void checkEndFunction(CheckerContext &C) const;
+ void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym,
RefVal V, ArgEffect E, RefVal::Kind &hasErr,
Ctx.addTransition(state);
}
-void RetainCountChecker::checkEndFunction(CheckerContext &Ctx) const {
+void RetainCountChecker::checkEndFunction(const ReturnStmt *RS,
+ CheckerContext &Ctx) const {
ProgramStateRef state = Ctx.getState();
RefBindingsTy B = state->get<RefBindings>();
ExplodedNode *Pred = Ctx.getPredecessor();
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
- void checkEndFunction(CheckerContext &Ctx) const;
+ void checkEndFunction(const ReturnStmt *RS, CheckerContext &Ctx) const;
private:
void checkReturnedBlockCaptures(const BlockDataRegion &B,
EmitStackError(C, R, RetE);
}
-void StackAddrEscapeChecker::checkEndFunction(CheckerContext &Ctx) const {
+void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
+ CheckerContext &Ctx) const {
if (!ChecksEnabled[CK_StackAddrEscapeChecker])
return;
public:
void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
void checkBranchCondition(const Stmt *Condition, CheckerContext &C) const;
- void checkEndFunction(CheckerContext &C) const;
+ void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
void setDivZeroMap(SVal Var, CheckerContext &C) const;
bool hasDivZeroMap(SVal Var, const CheckerContext &C) const;
bool isZero(SVal S, CheckerContext &C) const;
}
}
-void TestAfterDivZeroChecker::checkEndFunction(CheckerContext &C) const {
+void TestAfterDivZeroChecker::checkEndFunction(const ReturnStmt *RS,
+ CheckerContext &C) const {
ProgramStateRef State = C.getState();
DivZeroMapTy DivZeroes = State->get<DivZeroMap>();
public:
void checkBranchCondition(const Stmt *Condition, CheckerContext &C) const;
void checkBeginFunction(CheckerContext &C) const;
- void checkEndFunction(CheckerContext &C) const;
+ void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
};
}
llvm::outs() << "--BEGIN FUNCTION--\n";
}
-void TraversalDumper::checkEndFunction(CheckerContext &C) const {
+void TraversalDumper::checkEndFunction(const ReturnStmt *RS,
+ CheckerContext &C) const {
llvm::outs() << "--END FUNCTION--\n";
}
UninitializedObjectChecker()
: BT_uninitField(new BuiltinBug(this, "Uninitialized fields")) {}
- void checkEndFunction(CheckerContext &C) const;
+ void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
};
/// Represents a field chain. A field chain is a vector of fields where the
//===----------------------------------------------------------------------===//
void UninitializedObjectChecker::checkEndFunction(
- CheckerContext &Context) const {
+ const ReturnStmt *RS, CheckerContext &Context) const {
const auto *CtorDecl = dyn_cast_or_null<CXXConstructorDecl>(
Context.getLocationContext()->getDecl());
DefaultBool IsPureOnly;
void checkBeginFunction(CheckerContext &C) const;
- void checkEndFunction(CheckerContext &C) const;
+ void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
private:
}
// The EndFunction callback when leave a constructor or a destructor.
-void VirtualCallChecker::checkEndFunction(CheckerContext &C) const {
+void VirtualCallChecker::checkEndFunction(const ReturnStmt *RS,
+ CheckerContext &C) const {
registerCtorDtorCallInState(false, C);
}
void CheckerManager::runCheckersForEndFunction(NodeBuilderContext &BC,
ExplodedNodeSet &Dst,
ExplodedNode *Pred,
- ExprEngine &Eng) {
+ ExprEngine &Eng,
+ const ReturnStmt *RS) {
// We define the builder outside of the loop bacause if at least one checkers
// creates a sucsessor for Pred, we do not need to generate an
// autotransition for it.
Pred->getLocationContext(),
checkFn.Checker);
CheckerContext C(Bldr, Eng, Pred, L);
- checkFn(C);
+ checkFn(RS, C);
}
}
// Notify checkers.
for (const auto I : AfterRemovedDead)
- getCheckerManager().runCheckersForEndFunction(BC, Dst, I, *this);
+ getCheckerManager().runCheckersForEndFunction(BC, Dst, I, *this, RS);
} else {
- getCheckerManager().runCheckersForEndFunction(BC, Dst, Pred, *this);
+ getCheckerManager().runCheckersForEndFunction(BC, Dst, Pred, *this, RS);
}
Engine.enqueueEndOfFunction(Dst, RS);