diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-11-06 02:24:13 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-11-06 02:24:13 +0000 |
commit | 1053d246f451c399468248625d1146e3d845e21e (patch) | |
tree | 3a3ff1f9d0efd20a2998769ad42e2872e645f3e9 /lib/Analysis/ReturnUndefChecker.cpp | |
parent | b653c52d9176a4faecf923f792758f4454f7f78c (diff) |
static analyzer: refactor checking logic for returning the address of a stack variable or a garbage
value into their own respective subclasses of Checker (and put them in .cpp files where their
implementation details are hidden from GRExprEngine).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86215 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ReturnUndefChecker.cpp')
-rw-r--r-- | lib/Analysis/ReturnUndefChecker.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/Analysis/ReturnUndefChecker.cpp b/lib/Analysis/ReturnUndefChecker.cpp new file mode 100644 index 0000000000..adde3f5d25 --- /dev/null +++ b/lib/Analysis/ReturnUndefChecker.cpp @@ -0,0 +1,68 @@ +//== ReturnUndefChecker.cpp -------------------------------------*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines ReturnUndefChecker, which is a path-sensitive +// check which looks for undefined or garbage values being returned to the +// caller. +// +//===----------------------------------------------------------------------===// + +#include "GRExprEngineInternalChecks.h" +#include "clang/Analysis/PathSensitive/GRExprEngine.h" +#include "clang/Analysis/PathSensitive/BugReporter.h" +#include "clang/Analysis/PathSensitive/CheckerVisitor.h" +#include "llvm/ADT/SmallString.h" + +using namespace clang; + +namespace { +class VISIBILITY_HIDDEN ReturnUndefChecker : + public CheckerVisitor<ReturnUndefChecker> { + BuiltinBug *BT; +public: + ReturnUndefChecker() : BT(0) {} + static void *getTag(); + void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS); +}; +} + +void clang::RegisterReturnUndefChecker(GRExprEngine &Eng) { + Eng.registerCheck(new ReturnUndefChecker()); +} + +void *ReturnUndefChecker::getTag() { + static int x = 0; return &x; +} + +void ReturnUndefChecker::PreVisitReturnStmt(CheckerContext &C, + const ReturnStmt *RS) { + + const Expr *RetE = RS->getRetValue(); + if (!RetE) + return; + + if (!C.getState()->getSVal(RetE).isUndef()) + return; + + ExplodedNode *N = C.GenerateNode(RS, C.getState(), true); + + if (!N) + return; + + if (!BT) + BT = new BuiltinBug("Garbage return value", + "Undefined or garbage value returned to caller"); + + EnhancedBugReport *report = + new EnhancedBugReport(*BT, BT->getDescription().c_str(), N); + + report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, RetE); + + C.EmitReport(report); +} |