blob: 6cef60eaee298dcac8f982c8528b41c76f8273db [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"
Benjamin Kramer5e2d2c22010-03-27 21:19:47 +000016#include "clang/Checker/BugReporter/BugType.h"
Ted Kremenek1309f9a2010-01-25 04:41:41 +000017#include "clang/Checker/PathSensitive/CheckerVisitor.h"
Ted Kremenekb107c4b2009-11-04 04:24:16 +000018
19using namespace clang;
20
Zhongxing Xuc3372e02009-11-22 12:29:52 +000021namespace {
Kovarththanan Rajaratnamba5fb5a2009-11-28 06:07:30 +000022class UndefinedAssignmentChecker
Zhongxing Xuc3372e02009-11-22 12:29:52 +000023 : 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
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,
44 const Stmt *AssignE,
45 const Stmt *StoreE,
Ted Kremenekb107c4b2009-11-04 04:24:16 +000046 SVal location,
47 SVal val) {
48 if (!val.isUndef())
49 return;
50
Ted Kremenek19d67b52009-11-23 22:22:01 +000051 ExplodedNode *N = C.GenerateSink();
Ted Kremenekb107c4b2009-11-04 04:24:16 +000052
53 if (!N)
54 return;
55
Ted Kremenek12182a02010-03-22 22:16:26 +000056 const char *str = "Assigned value is garbage or undefined";
57
Ted Kremenekb107c4b2009-11-04 04:24:16 +000058 if (!BT)
Ted Kremenek12182a02010-03-22 22:16:26 +000059 BT = new BuiltinBug(str);
Ted Kremenekb107c4b2009-11-04 04:24:16 +000060
61 // Generate a report for this bug.
Ted Kremenek12182a02010-03-22 22:16:26 +000062 const Expr *ex = 0;
Ted Kremenekb107c4b2009-11-04 04:24:16 +000063
Ted Kremenek12182a02010-03-22 22:16:26 +000064 while (AssignE) {
65 if (const BinaryOperator *B = dyn_cast<BinaryOperator>(AssignE)) {
66 if (B->isCompoundAssignmentOp()) {
67 const GRState *state = C.getState();
68 if (state->getSVal(B->getLHS()).isUndef()) {
69 str = "The left expression of the compound assignment is an "
70 "uninitialized value. The computed value will also be garbage";
71 ex = B->getLHS();
72 break;
73 }
74 }
Ted Kremenekb107c4b2009-11-04 04:24:16 +000075
Ted Kremenek50ecd152009-11-05 00:42:23 +000076 ex = B->getRHS();
Ted Kremenek12182a02010-03-22 22:16:26 +000077 break;
78 }
79
80 if (const DeclStmt *DS = dyn_cast<DeclStmt>(AssignE)) {
Ted Kremenek50ecd152009-11-05 00:42:23 +000081 const VarDecl* VD = dyn_cast<VarDecl>(DS->getSingleDecl());
82 ex = VD->getInit();
83 }
Ted Kremenek12182a02010-03-22 22:16:26 +000084
85 break;
Ted Kremenekb107c4b2009-11-04 04:24:16 +000086 }
87
Ted Kremenek12182a02010-03-22 22:16:26 +000088 EnhancedBugReport *R = new EnhancedBugReport(*BT, str, N);
89 if (ex) {
90 R->addRange(ex->getSourceRange());
91 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
92 }
Ted Kremenekb107c4b2009-11-04 04:24:16 +000093 C.EmitReport(R);
Ted Kremenek12182a02010-03-22 22:16:26 +000094}
Ted Kremenekb107c4b2009-11-04 04:24:16 +000095