Index: cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h =================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h +++ cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h @@ -254,9 +254,9 @@ class EndFunction { template - 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: Index: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h =================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -296,7 +296,8 @@ 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, @@ -438,7 +439,8 @@ using CheckBeginFunctionFunc = CheckerFn; - using CheckEndFunctionFunc = CheckerFn; + using CheckEndFunctionFunc = + CheckerFn; using CheckBranchConditionFunc = CheckerFn; @@ -496,7 +498,7 @@ void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); - void _registerForBeginFunction(CheckEndFunctionFunc checkfn); + void _registerForBeginFunction(CheckBeginFunctionFunc checkfn); void _registerForEndFunction(CheckEndFunctionFunc checkfn); void _registerForBranchCondition(CheckBranchConditionFunc checkfn); Index: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -126,7 +126,7 @@ 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; @@ -398,7 +398,7 @@ /// 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); } Index: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp @@ -192,7 +192,7 @@ /// 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. Index: cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp @@ -46,7 +46,7 @@ : public Checker { 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; @@ -222,7 +222,8 @@ // 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(); if (Objects.isEmpty()) Index: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -2743,7 +2743,7 @@ 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, @@ -3991,7 +3991,8 @@ 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(); ExplodedNode *Pred = Ctx.getPredecessor(); Index: cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp @@ -47,7 +47,7 @@ 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, @@ -287,7 +287,8 @@ EmitStackError(C, R, RetE); } -void StackAddrEscapeChecker::checkEndFunction(CheckerContext &Ctx) const { +void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS, + CheckerContext &Ctx) const { if (!ChecksEnabled[CK_StackAddrEscapeChecker]) return; Index: cfe/trunk/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp @@ -85,7 +85,7 @@ 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; @@ -180,7 +180,8 @@ } } -void TestAfterDivZeroChecker::checkEndFunction(CheckerContext &C) const { +void TestAfterDivZeroChecker::checkEndFunction(const ReturnStmt *RS, + CheckerContext &C) const { ProgramStateRef State = C.getState(); DivZeroMapTy DivZeroes = State->get(); Index: cfe/trunk/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp @@ -30,7 +30,7 @@ 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; }; } @@ -56,7 +56,8 @@ 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"; } Index: cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp @@ -47,7 +47,7 @@ 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 @@ -241,7 +241,7 @@ //===----------------------------------------------------------------------===// void UninitializedObjectChecker::checkEndFunction( - CheckerContext &Context) const { + const ReturnStmt *RS, CheckerContext &Context) const { const auto *CtorDecl = dyn_cast_or_null( Context.getLocationContext()->getDecl()); Index: cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp @@ -48,7 +48,7 @@ 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: @@ -167,7 +167,8 @@ } // 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); } Index: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -439,7 +439,8 @@ 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. @@ -449,7 +450,7 @@ Pred->getLocationContext(), checkFn.Checker); CheckerContext C(Bldr, Eng, Pred, L); - checkFn(C); + checkFn(RS, C); } } Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -2297,9 +2297,9 @@ // 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);