blob: 28806e3db917f65e833892be24b330fb6aa3097d [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//
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000010// This defines UndefinedAssignmentChecker, a builtin check in ExprEngine that
Ted Kremenekb107c4b2009-11-04 04:24:16 +000011// checks for assigning undefined values.
12//
13//===----------------------------------------------------------------------===//
14
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000015#include "ClangSACheckers.h"
Argyrios Kyrtzidisec8605f2011-03-01 01:16:21 +000016#include "clang/StaticAnalyzer/Core/Checker.h"
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000017#include "clang/StaticAnalyzer/Core/CheckerManager.h"
18#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
Ted Kremenek9b663712011-02-10 01:03:03 +000019#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
Ted Kremenekb107c4b2009-11-04 04:24:16 +000020
21using namespace clang;
Ted Kremenek9ef65372010-12-23 07:20:52 +000022using namespace ento;
Ted Kremenekb107c4b2009-11-04 04:24:16 +000023
Zhongxing Xuc3372e02009-11-22 12:29:52 +000024namespace {
Kovarththanan Rajaratnamba5fb5a2009-11-28 06:07:30 +000025class UndefinedAssignmentChecker
Argyrios Kyrtzidisec8605f2011-03-01 01:16:21 +000026 : public Checker<check::Bind> {
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000027 mutable llvm::OwningPtr<BugType> BT;
28
Zhongxing Xuc3372e02009-11-22 12:29:52 +000029public:
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000030 void checkBind(SVal location, SVal val, CheckerContext &C) const;
Zhongxing Xuc3372e02009-11-22 12:29:52 +000031};
32}
33
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000034void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
35 CheckerContext &C) const {
Ted Kremenekb107c4b2009-11-04 04:24:16 +000036 if (!val.isUndef())
37 return;
38
Ted Kremenekd048c6e2010-12-20 21:19:09 +000039 ExplodedNode *N = C.generateSink();
Ted Kremenekb107c4b2009-11-04 04:24:16 +000040
41 if (!N)
42 return;
43
Ted Kremenek12182a02010-03-22 22:16:26 +000044 const char *str = "Assigned value is garbage or undefined";
45
Ted Kremenekb107c4b2009-11-04 04:24:16 +000046 if (!BT)
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000047 BT.reset(new BuiltinBug(str));
Ted Kremenekb107c4b2009-11-04 04:24:16 +000048
49 // Generate a report for this bug.
Ted Kremenek12182a02010-03-22 22:16:26 +000050 const Expr *ex = 0;
Ted Kremenekb107c4b2009-11-04 04:24:16 +000051
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000052 const Stmt *StoreE = C.getStmt();
Ted Kremenek79d73042010-09-02 00:56:20 +000053 while (StoreE) {
54 if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) {
Ted Kremenek12182a02010-03-22 22:16:26 +000055 if (B->isCompoundAssignmentOp()) {
56 const GRState *state = C.getState();
57 if (state->getSVal(B->getLHS()).isUndef()) {
58 str = "The left expression of the compound assignment is an "
59 "uninitialized value. The computed value will also be garbage";
60 ex = B->getLHS();
61 break;
62 }
63 }
Ted Kremenekb107c4b2009-11-04 04:24:16 +000064
Ted Kremenek50ecd152009-11-05 00:42:23 +000065 ex = B->getRHS();
Ted Kremenek12182a02010-03-22 22:16:26 +000066 break;
67 }
68
Ted Kremenek79d73042010-09-02 00:56:20 +000069 if (const DeclStmt *DS = dyn_cast<DeclStmt>(StoreE)) {
Ted Kremenek50ecd152009-11-05 00:42:23 +000070 const VarDecl* VD = dyn_cast<VarDecl>(DS->getSingleDecl());
71 ex = VD->getInit();
72 }
Ted Kremenek12182a02010-03-22 22:16:26 +000073
74 break;
Ted Kremenekb107c4b2009-11-04 04:24:16 +000075 }
76
Ted Kremenek12182a02010-03-22 22:16:26 +000077 EnhancedBugReport *R = new EnhancedBugReport(*BT, str, N);
78 if (ex) {
79 R->addRange(ex->getSourceRange());
80 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
81 }
Ted Kremenekb107c4b2009-11-04 04:24:16 +000082 C.EmitReport(R);
Ted Kremenek12182a02010-03-22 22:16:26 +000083}
Ted Kremenekb107c4b2009-11-04 04:24:16 +000084
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000085void ento::registerUndefinedAssignmentChecker(CheckerManager &mgr) {
86 mgr.registerChecker<UndefinedAssignmentChecker>();
87}