blob: b1eb38704bcda9562bba2a98854b4f37eba057bb [file] [log] [blame]
Ted Kremenekb107c4b2009-11-04 04:24:16 +00001//===--- 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
Zhongxing Xuc3372e02009-11-22 12:29:52 +000015#include "GRExprEngineInternalChecks.h"
Argyrios Kyrtzidis98cabba2010-12-22 18:51:49 +000016#include "clang/GR/BugReporter/BugType.h"
17#include "clang/GR/PathSensitive/CheckerVisitor.h"
Ted Kremenekb107c4b2009-11-04 04:24:16 +000018
19using namespace clang;
Argyrios Kyrtzidis5a4f98f2010-12-22 18:53:20 +000020using namespace GR;
Ted Kremenekb107c4b2009-11-04 04:24:16 +000021
Zhongxing Xuc3372e02009-11-22 12:29:52 +000022namespace {
Kovarththanan Rajaratnamba5fb5a2009-11-28 06:07:30 +000023class UndefinedAssignmentChecker
Zhongxing Xuc3372e02009-11-22 12:29:52 +000024 : public CheckerVisitor<UndefinedAssignmentChecker> {
25 BugType *BT;
26public:
27 UndefinedAssignmentChecker() : BT(0) {}
28 static void *getTag();
Ted Kremenek79d73042010-09-02 00:56:20 +000029 virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
30 SVal location, SVal val);
Zhongxing Xuc3372e02009-11-22 12:29:52 +000031};
32}
33
Argyrios Kyrtzidis5a4f98f2010-12-22 18:53:20 +000034void GR::RegisterUndefinedAssignmentChecker(GRExprEngine &Eng){
Zhongxing Xuc3372e02009-11-22 12:29:52 +000035 Eng.registerCheck(new UndefinedAssignmentChecker());
36}
37
Ted Kremenekb107c4b2009-11-04 04:24:16 +000038void *UndefinedAssignmentChecker::getTag() {
39 static int x = 0;
40 return &x;
41}
42
Ted Kremenek50ecd152009-11-05 00:42:23 +000043void UndefinedAssignmentChecker::PreVisitBind(CheckerContext &C,
Ted Kremenek50ecd152009-11-05 00:42:23 +000044 const Stmt *StoreE,
Ted Kremenekb107c4b2009-11-04 04:24:16 +000045 SVal location,
46 SVal val) {
47 if (!val.isUndef())
48 return;
49
Ted Kremenekd048c6e2010-12-20 21:19:09 +000050 ExplodedNode *N = C.generateSink();
Ted Kremenekb107c4b2009-11-04 04:24:16 +000051
52 if (!N)
53 return;
54
Ted Kremenek12182a02010-03-22 22:16:26 +000055 const char *str = "Assigned value is garbage or undefined";
56
Ted Kremenekb107c4b2009-11-04 04:24:16 +000057 if (!BT)
Ted Kremenek12182a02010-03-22 22:16:26 +000058 BT = new BuiltinBug(str);
Ted Kremenekb107c4b2009-11-04 04:24:16 +000059
60 // Generate a report for this bug.
Ted Kremenek12182a02010-03-22 22:16:26 +000061 const Expr *ex = 0;
Ted Kremenekb107c4b2009-11-04 04:24:16 +000062
Ted Kremenek79d73042010-09-02 00:56:20 +000063 while (StoreE) {
64 if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) {
Ted Kremenek12182a02010-03-22 22:16:26 +000065 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 }
Ted Kremenekb107c4b2009-11-04 04:24:16 +000074
Ted Kremenek50ecd152009-11-05 00:42:23 +000075 ex = B->getRHS();
Ted Kremenek12182a02010-03-22 22:16:26 +000076 break;
77 }
78
Ted Kremenek79d73042010-09-02 00:56:20 +000079 if (const DeclStmt *DS = dyn_cast<DeclStmt>(StoreE)) {
Ted Kremenek50ecd152009-11-05 00:42:23 +000080 const VarDecl* VD = dyn_cast<VarDecl>(DS->getSingleDecl());
81 ex = VD->getInit();
82 }
Ted Kremenek12182a02010-03-22 22:16:26 +000083
84 break;
Ted Kremenekb107c4b2009-11-04 04:24:16 +000085 }
86
Ted Kremenek12182a02010-03-22 22:16:26 +000087 EnhancedBugReport *R = new EnhancedBugReport(*BT, str, N);
88 if (ex) {
89 R->addRange(ex->getSourceRange());
90 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
91 }
Ted Kremenekb107c4b2009-11-04 04:24:16 +000092 C.EmitReport(R);
Ted Kremenek12182a02010-03-22 22:16:26 +000093}
Ted Kremenekb107c4b2009-11-04 04:24:16 +000094