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