1 //== ReturnUndefChecker.cpp -------------------------------------*- 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 file defines ReturnUndefChecker, which is a path-sensitive 11 // check which looks for undefined or garbage values being returned to the 12 // caller. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "ExprEngineInternalChecks.h" 17 #include "clang/StaticAnalyzer/BugReporter/BugType.h" 18 #include "clang/StaticAnalyzer/PathSensitive/CheckerVisitor.h" 19 #include "clang/StaticAnalyzer/PathSensitive/ExprEngine.h" 20 21 using namespace clang; 22 using namespace ento; 23 24 namespace { 25 class ReturnUndefChecker : 26 public CheckerVisitor<ReturnUndefChecker> { 27 BuiltinBug *BT; 28 public: 29 ReturnUndefChecker() : BT(0) {} 30 static void *getTag(); 31 void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *RS); 32 }; 33 } 34 35 void ento::RegisterReturnUndefChecker(ExprEngine &Eng) { 36 Eng.registerCheck(new ReturnUndefChecker()); 37 } 38 39 void *ReturnUndefChecker::getTag() { 40 static int x = 0; return &x; 41 } 42 43 void ReturnUndefChecker::PreVisitReturnStmt(CheckerContext &C, 44 const ReturnStmt *RS) { 45 46 const Expr *RetE = RS->getRetValue(); 47 if (!RetE) 48 return; 49 50 if (!C.getState()->getSVal(RetE).isUndef()) 51 return; 52 53 ExplodedNode *N = C.generateSink(); 54 55 if (!N) 56 return; 57 58 if (!BT) 59 BT = new BuiltinBug("Garbage return value", 60 "Undefined or garbage value returned to caller"); 61 62 EnhancedBugReport *report = 63 new EnhancedBugReport(*BT, BT->getDescription(), N); 64 65 report->addRange(RetE->getSourceRange()); 66 report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, RetE); 67 68 C.EmitReport(report); 69 } 70