blob: 7c33c1d3923571a483000cab970e77e84cbeb77d [file] [log] [blame]
Shih-wei Liaof8fd82b2010-02-10 11:10:31 -08001//===--- UndefinedAssignmentChecker.h ---------------------------*- 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 defines UndefinedAssginmentChecker, a builtin check in GRExprEngine that
11// checks for assigning undefined values.
12//
13//===----------------------------------------------------------------------===//
14
15#include "GRExprEngineInternalChecks.h"
16#include "clang/Checker/PathSensitive/CheckerVisitor.h"
17#include "clang/Checker/BugReporter/BugReporter.h"
18
19using namespace clang;
20
21namespace {
22class UndefinedAssignmentChecker
23 : public CheckerVisitor<UndefinedAssignmentChecker> {
24 BugType *BT;
25public:
26 UndefinedAssignmentChecker() : BT(0) {}
27 static void *getTag();
28 virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
29 const Stmt *StoreE, SVal location,
30 SVal val);
31};
32}
33
34void clang::RegisterUndefinedAssignmentChecker(GRExprEngine &Eng){
35 Eng.registerCheck(new UndefinedAssignmentChecker());
36}
37
38void *UndefinedAssignmentChecker::getTag() {
39 static int x = 0;
40 return &x;
41}
42
43void UndefinedAssignmentChecker::PreVisitBind(CheckerContext &C,
44 const Stmt *AssignE,
45 const Stmt *StoreE,
46 SVal location,
47 SVal val) {
48 if (!val.isUndef())
49 return;
50
51 ExplodedNode *N = C.GenerateSink();
52
53 if (!N)
54 return;
55
56 if (!BT)
57 BT = new BuiltinBug("Assigned value is garbage or undefined");
58
59 // Generate a report for this bug.
60 EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName(), N);
61
62 if (AssignE) {
63 const Expr *ex = 0;
64
65 if (const BinaryOperator *B = dyn_cast<BinaryOperator>(AssignE))
66 ex = B->getRHS();
67 else if (const DeclStmt *DS = dyn_cast<DeclStmt>(AssignE)) {
68 const VarDecl* VD = dyn_cast<VarDecl>(DS->getSingleDecl());
69 ex = VD->getInit();
70 }
71 if (ex) {
72 R->addRange(ex->getSourceRange());
73 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
74 }
75 }
76
77 C.EmitReport(R);
78}
79