ReturnUndefChecker.cpp revision dd82519ac6c322a6183954848b5b55deb6c364f7
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 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, C.getLocationContext()).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->disablePathPruning();
57  report->addRange(RetE->getSourceRange());
58  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, RetE,
59                                                                  report));
60
61  C.EmitReport(report);
62}
63
64void ento::registerReturnUndefChecker(CheckerManager &mgr) {
65  mgr.registerChecker<ReturnUndefChecker>();
66}
67