blob: 7cd71265805b1b6b6d70c3f60d966f19de52638c [file] [log] [blame]
Ted Kremenek1053d242009-11-06 02:24:13 +00001//== ReturnUndefChecker.cpp -------------------------------------*- C++ -*--==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines ReturnUndefChecker, which is a path-sensitive
11// check which looks for undefined or garbage values being returned to the
12// caller.
13//
14//===----------------------------------------------------------------------===//
15
16#include "GRExprEngineInternalChecks.h"
17#include "clang/Analysis/PathSensitive/GRExprEngine.h"
18#include "clang/Analysis/PathSensitive/BugReporter.h"
19#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
20#include "llvm/ADT/SmallString.h"
21
22using namespace clang;
23
24namespace {
Kovarththanan Rajaratnamba5fb5a2009-11-28 06:07:30 +000025class ReturnUndefChecker :
Ted Kremenek1053d242009-11-06 02:24:13 +000026 public CheckerVisitor<ReturnUndefChecker> {
27 BuiltinBug *BT;
28public:
29 ReturnUndefChecker() : BT(0) {}
30 static void *getTag();
31 void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
32};
33}
34
35void clang::RegisterReturnUndefChecker(GRExprEngine &Eng) {
36 Eng.registerCheck(new ReturnUndefChecker());
37}
38
39void *ReturnUndefChecker::getTag() {
40 static int x = 0; return &x;
41}
42
43void ReturnUndefChecker::PreVisitReturnStmt(CheckerContext &C,
44 const ReturnStmt *RS) {
45
46 const Expr *RetE = RS->getRetValue();
47 if (!RetE)
48 return;
49
50 if (!C.getState()->getSVal(RetE).isUndef())
51 return;
52
Ted Kremenek19d67b52009-11-23 22:22:01 +000053 ExplodedNode *N = C.GenerateSink();
Ted Kremenek1053d242009-11-06 02:24:13 +000054
55 if (!N)
56 return;
57
58 if (!BT)
59 BT = new BuiltinBug("Garbage return value",
60 "Undefined or garbage value returned to caller");
61
62 EnhancedBugReport *report =
Benjamin Kramerd02e2322009-11-14 12:08:24 +000063 new EnhancedBugReport(*BT, BT->getDescription(), N);
Ted Kremenek1053d242009-11-06 02:24:13 +000064
65 report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, RetE);
66
67 C.EmitReport(report);
68}