blob: 840ae3d2ad50ad200d523c8d86476bb5ae5217a2 [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> {
Dylan Noblesmith6f42b622012-02-05 02:12:40 +000027 mutable OwningPtr<BugType> BT;
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000028
Zhongxing Xuc3372e02009-11-22 12:29:52 +000029public:
Anna Zaks390909c2011-10-06 00:43:15 +000030 void checkBind(SVal location, SVal val, const Stmt *S,
31 CheckerContext &C) const;
Zhongxing Xuc3372e02009-11-22 12:29:52 +000032};
33}
34
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000035void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
Anna Zaks390909c2011-10-06 00:43:15 +000036 const Stmt *StoreE,
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000037 CheckerContext &C) const {
Ted Kremenekb107c4b2009-11-04 04:24:16 +000038 if (!val.isUndef())
39 return;
40
Ted Kremenekd048c6e2010-12-20 21:19:09 +000041 ExplodedNode *N = C.generateSink();
Ted Kremenekb107c4b2009-11-04 04:24:16 +000042
43 if (!N)
44 return;
45
Ted Kremenek12182a02010-03-22 22:16:26 +000046 const char *str = "Assigned value is garbage or undefined";
47
Ted Kremenekb107c4b2009-11-04 04:24:16 +000048 if (!BT)
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000049 BT.reset(new BuiltinBug(str));
Ted Kremenekb107c4b2009-11-04 04:24:16 +000050
51 // Generate a report for this bug.
Ted Kremenek12182a02010-03-22 22:16:26 +000052 const Expr *ex = 0;
Ted Kremenekb107c4b2009-11-04 04:24:16 +000053
Ted Kremenek79d73042010-09-02 00:56:20 +000054 while (StoreE) {
55 if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) {
Ted Kremenek12182a02010-03-22 22:16:26 +000056 if (B->isCompoundAssignmentOp()) {
Ted Kremenek8bef8232012-01-26 21:29:00 +000057 ProgramStateRef state = C.getState();
Ted Kremenek5eca4822012-01-06 22:09:28 +000058 if (state->getSVal(B->getLHS(), C.getLocationContext()).isUndef()) {
Ted Kremenek12182a02010-03-22 22:16:26 +000059 str = "The left expression of the compound assignment is an "
60 "uninitialized value. The computed value will also be garbage";
61 ex = B->getLHS();
62 break;
63 }
64 }
Ted Kremenekb107c4b2009-11-04 04:24:16 +000065
Ted Kremenek50ecd152009-11-05 00:42:23 +000066 ex = B->getRHS();
Ted Kremenek12182a02010-03-22 22:16:26 +000067 break;
68 }
69
Ted Kremenek79d73042010-09-02 00:56:20 +000070 if (const DeclStmt *DS = dyn_cast<DeclStmt>(StoreE)) {
Ted Kremenek9c378f72011-08-12 23:37:29 +000071 const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
Ted Kremenek50ecd152009-11-05 00:42:23 +000072 ex = VD->getInit();
73 }
Ted Kremenek12182a02010-03-22 22:16:26 +000074
75 break;
Ted Kremenekb107c4b2009-11-04 04:24:16 +000076 }
77
Anna Zakse172e8b2011-08-17 23:00:25 +000078 BugReport *R = new BugReport(*BT, str, N);
Ted Kremenek12182a02010-03-22 22:16:26 +000079 if (ex) {
80 R->addRange(ex->getSourceRange());
Anna Zaks50bbc162011-08-19 22:33:38 +000081 R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, ex));
Ted Kremenek12182a02010-03-22 22:16:26 +000082 }
Ted Kremenekb107c4b2009-11-04 04:24:16 +000083 C.EmitReport(R);
Ted Kremenek12182a02010-03-22 22:16:26 +000084}
Ted Kremenekb107c4b2009-11-04 04:24:16 +000085
Argyrios Kyrtzidis267aa5c2011-02-28 01:27:37 +000086void ento::registerUndefinedAssignmentChecker(CheckerManager &mgr) {
87 mgr.registerChecker<UndefinedAssignmentChecker>();
88}