summaryrefslogtreecommitdiffstats
path: root/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/TraversalChecker.cpp')
-rw-r--r--lib/StaticAnalyzer/Checkers/TraversalChecker.cpp33
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
index b97cd6c..57c9ed4 100644
--- a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
@@ -18,16 +18,17 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/Support/raw_ostream.h"
using namespace clang;
using namespace ento;
namespace {
class TraversalDumper : public Checker< check::BranchCondition,
- check::EndPath > {
+ check::EndFunction > {
public:
void checkBranchCondition(const Stmt *Condition, CheckerContext &C) const;
- void checkEndPath(CheckerContext &C) const;
+ void checkEndFunction(CheckerContext &C) const;
};
}
@@ -49,8 +50,8 @@ void TraversalDumper::checkBranchCondition(const Stmt *Condition,
<< Parent->getStmtClassName() << "\n";
}
-void TraversalDumper::checkEndPath(CheckerContext &C) const {
- llvm::outs() << "--END PATH--\n";
+void TraversalDumper::checkEndFunction(CheckerContext &C) const {
+ llvm::outs() << "--END FUNCTION--\n";
}
void ento::registerTraversalDumper(CheckerManager &mgr) {
@@ -60,9 +61,11 @@ void ento::registerTraversalDumper(CheckerManager &mgr) {
//------------------------------------------------------------------------------
namespace {
-class CallDumper : public Checker< check::PreCall > {
+class CallDumper : public Checker< check::PreCall,
+ check::PostCall > {
public:
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
+ void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
};
}
@@ -79,6 +82,26 @@ void CallDumper::checkPreCall(const CallEvent &Call, CheckerContext &C) const {
Call.dump(llvm::outs());
}
+void CallDumper::checkPostCall(const CallEvent &Call, CheckerContext &C) const {
+ const Expr *CallE = Call.getOriginExpr();
+ if (!CallE)
+ return;
+
+ unsigned Indentation = 0;
+ for (const LocationContext *LC = C.getLocationContext()->getParent();
+ LC != 0; LC = LC->getParent())
+ ++Indentation;
+
+ // It is mildly evil to print directly to llvm::outs() rather than emitting
+ // warnings, but this ensures things do not get filtered out by the rest of
+ // the static analyzer machinery.
+ llvm::outs().indent(Indentation);
+ if (Call.getResultType()->isVoidType())
+ llvm::outs() << "Returning void\n";
+ else
+ llvm::outs() << "Returning " << C.getSVal(CallE) << "\n";
+}
+
void ento::registerCallDumper(CheckerManager &mgr) {
mgr.registerChecker<CallDumper>();
}
OpenPOWER on IntegriCloud