]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Checker/ReturnUndefChecker.cpp
Update clang to r94309.
[FreeBSD/FreeBSD.git] / lib / Checker / ReturnUndefChecker.cpp
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 "GRExprEngineInternalChecks.h"
17 #include "clang/Checker/PathSensitive/GRExprEngine.h"
18 #include "clang/Checker/BugReporter/BugReporter.h"
19 #include "clang/Checker/PathSensitive/CheckerVisitor.h"
20 #include "llvm/ADT/SmallString.h"
21
22 using namespace clang;
23
24 namespace {
25 class ReturnUndefChecker : 
26     public CheckerVisitor<ReturnUndefChecker> {      
27   BuiltinBug *BT;
28 public:
29     ReturnUndefChecker() : BT(0) {}
30     static void *getTag();
31     void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS);
32 };
33 }
34
35 void clang::RegisterReturnUndefChecker(GRExprEngine &Eng) {
36   Eng.registerCheck(new ReturnUndefChecker());
37 }
38
39 void *ReturnUndefChecker::getTag() {
40   static int x = 0; return &x;
41 }
42
43 void 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   
53   ExplodedNode *N = C.GenerateSink();
54
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 = 
63     new EnhancedBugReport(*BT, BT->getDescription(), N);
64
65   report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, RetE);
66
67   C.EmitReport(report);
68 }