ReturnUndefChecker.cpp revision 50bbc165b063155cc23c360deb7b865502e068e2
1//== 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 "ClangSACheckers.h"
17#include "clang/StaticAnalyzer/Core/Checker.h"
18#include "clang/StaticAnalyzer/Core/CheckerManager.h"
19#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
20#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
21
22using namespace clang;
23using namespace ento;
24
25namespace {
26class ReturnUndefChecker :
27    public Checker< check::PreStmt<ReturnStmt> > {
28  mutable llvm::OwningPtr<BuiltinBug> BT;
29public:
30  void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
31};
32}
33
34void ReturnUndefChecker::checkPreStmt(const ReturnStmt *RS,
35                                      CheckerContext &C) const {
36
37  const Expr *RetE = RS->getRetValue();
38  if (!RetE)
39    return;
40
41  if (!C.getState()->getSVal(RetE).isUndef())
42    return;
43
44  ExplodedNode *N = C.generateSink();
45
46  if (!N)
47    return;
48
49  if (!BT)
50    BT.reset(new BuiltinBug("Garbage return value",
51                            "Undefined or garbage value returned to caller"));
52
53  BugReport *report =
54    new BugReport(*BT, BT->getDescription(), N);
55
56  report->addRange(RetE->getSourceRange());
57  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, RetE));
58
59  C.EmitReport(report);
60}
61
62void ento::registerReturnUndefChecker(CheckerManager &mgr) {
63  mgr.registerChecker<ReturnUndefChecker>();
64}
65