Skip to content

Commit

Permalink
[analyzer] Make checkEndFunction() give access to the return statement.
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D49387

llvm-svn: 337215
  • Loading branch information
rnkovacs committed Jul 16, 2018
1 parent 810ed5b commit ed8c05c
Show file tree
Hide file tree
Showing 13 changed files with 35 additions and 26 deletions.
4 changes: 2 additions & 2 deletions clang/include/clang/StaticAnalyzer/Core/Checker.h
Expand Up @@ -254,9 +254,9 @@ class BeginFunction {

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:
Expand Down
8 changes: 5 additions & 3 deletions clang/include/clang/StaticAnalyzer/Core/CheckerManager.h
Expand Up @@ -296,7 +296,8 @@ class CheckerManager {
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,
Expand Down Expand Up @@ -438,7 +439,8 @@ class CheckerManager {

using CheckBeginFunctionFunc = CheckerFn<void (CheckerContext &)>;

using CheckEndFunctionFunc = CheckerFn<void (CheckerContext &)>;
using CheckEndFunctionFunc =
CheckerFn<void (const ReturnStmt *, CheckerContext &)>;

using CheckBranchConditionFunc =
CheckerFn<void (const Stmt *, CheckerContext &)>;
Expand Down Expand Up @@ -496,7 +498,7 @@ class CheckerManager {

void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);

void _registerForBeginFunction(CheckEndFunctionFunc checkfn);
void _registerForBeginFunction(CheckBeginFunctionFunc checkfn);
void _registerForEndFunction(CheckEndFunctionFunc checkfn);

void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
Expand Up @@ -126,7 +126,7 @@ class ObjCDeallocChecker
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;
Expand Down Expand Up @@ -398,7 +398,7 @@ void ObjCDeallocChecker::checkPostObjCMessage(
/// 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);
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
Expand Up @@ -192,7 +192,7 @@ class CheckerDocumentation : public Checker< check::PreStmt<ReturnStmt>,
/// 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.
Expand Down
Expand Up @@ -46,7 +46,7 @@ class MisusedMovedObjectChecker
: 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;
Expand Down Expand Up @@ -222,7 +222,8 @@ ExplodedNode *MisusedMovedObjectChecker::reportBug(const MemRegion *Region,

// 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())
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
Expand Up @@ -2743,7 +2743,7 @@ class RetainCountChecker

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,
Expand Down Expand Up @@ -3991,7 +3991,8 @@ void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const {
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();
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
Expand Up @@ -47,7 +47,7 @@ class StackAddrEscapeChecker

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,
Expand Down Expand Up @@ -287,7 +287,8 @@ void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,
EmitStackError(C, R, RetE);
}

void StackAddrEscapeChecker::checkEndFunction(CheckerContext &Ctx) const {
void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
CheckerContext &Ctx) const {
if (!ChecksEnabled[CK_StackAddrEscapeChecker])
return;

Expand Down
5 changes: 3 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
Expand Up @@ -85,7 +85,7 @@ class TestAfterDivZeroChecker
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;
Expand Down Expand Up @@ -180,7 +180,8 @@ void TestAfterDivZeroChecker::reportBug(SVal Val, 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>();
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
Expand Up @@ -30,7 +30,7 @@ class TraversalDumper : public Checker< check::BranchCondition,
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;
};
}

Expand All @@ -56,7 +56,8 @@ void TraversalDumper::checkBeginFunction(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";
}

Expand Down
Expand Up @@ -47,7 +47,7 @@ class UninitializedObjectChecker : public Checker<check::EndFunction> {

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
Expand Down Expand Up @@ -241,7 +241,7 @@ static StringRef getVariableName(const FieldDecl *Field);
//===----------------------------------------------------------------------===//

void UninitializedObjectChecker::checkEndFunction(
CheckerContext &Context) const {
const ReturnStmt *RS, CheckerContext &Context) const {

const auto *CtorDecl = dyn_cast_or_null<CXXConstructorDecl>(
Context.getLocationContext()->getDecl());
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
Expand Up @@ -48,7 +48,7 @@ class VirtualCallChecker
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:
Expand Down Expand Up @@ -167,7 +167,8 @@ void VirtualCallChecker::checkBeginFunction(CheckerContext &C) const {
}

// 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);
}

Expand Down
5 changes: 3 additions & 2 deletions clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
Expand Up @@ -439,7 +439,8 @@ void CheckerManager::runCheckersForBeginFunction(ExplodedNodeSet &Dst,
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.
Expand All @@ -449,7 +450,7 @@ void CheckerManager::runCheckersForEndFunction(NodeBuilderContext &BC,
Pred->getLocationContext(),
checkFn.Checker);
CheckerContext C(Bldr, Eng, Pred, L);
checkFn(C);
checkFn(RS, C);
}
}

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
Expand Up @@ -2297,9 +2297,9 @@ void ExprEngine::processEndOfFunction(NodeBuilderContext& BC,

// 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);
Expand Down

0 comments on commit ed8c05c

Please sign in to comment.