UndefinedAssignmentChecker.cpp revision 218893
1//===--- 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 ExprEngine that
11// checks for assigning undefined values.
12//
13//===----------------------------------------------------------------------===//
14
15#include "InternalChecks.h"
16#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
17#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h"
18
19using namespace clang;
20using namespace ento;
21
22namespace {
23class UndefinedAssignmentChecker
24  : public CheckerVisitor<UndefinedAssignmentChecker> {
25  BugType *BT;
26public:
27  UndefinedAssignmentChecker() : BT(0) {}
28  static void *getTag();
29  virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
30                            SVal location, SVal val);
31};
32}
33
34void ento::RegisterUndefinedAssignmentChecker(ExprEngine &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 *StoreE,
45                                              SVal location,
46                                              SVal val) {
47  if (!val.isUndef())
48    return;
49
50  ExplodedNode *N = C.generateSink();
51
52  if (!N)
53    return;
54
55  const char *str = "Assigned value is garbage or undefined";
56
57  if (!BT)
58    BT = new BuiltinBug(str);
59
60  // Generate a report for this bug.
61  const Expr *ex = 0;
62
63  while (StoreE) {
64    if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) {
65      if (B->isCompoundAssignmentOp()) {
66        const GRState *state = C.getState();
67        if (state->getSVal(B->getLHS()).isUndef()) {
68          str = "The left expression of the compound assignment is an "
69                "uninitialized value. The computed value will also be garbage";
70          ex = B->getLHS();
71          break;
72        }
73      }
74
75      ex = B->getRHS();
76      break;
77    }
78
79    if (const DeclStmt *DS = dyn_cast<DeclStmt>(StoreE)) {
80      const VarDecl* VD = dyn_cast<VarDecl>(DS->getSingleDecl());
81      ex = VD->getInit();
82    }
83
84    break;
85  }
86
87  EnhancedBugReport *R = new EnhancedBugReport(*BT, str, N);
88  if (ex) {
89    R->addRange(ex->getSourceRange());
90    R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
91  }
92  C.EmitReport(R);
93}
94
95