ExprInspectionChecker.cpp revision 93a9d828378b5c969344f27aeb275b8c2a19d918
1//==- ExprInspectionChecker.cpp - Used for regression tests ------*- 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#include "ClangSACheckers.h" 11#include "clang/StaticAnalyzer/Core/Checker.h" 12#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 13#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 14 15using namespace clang; 16using namespace ento; 17 18namespace { 19class ExprInspectionChecker : public Checker< eval::Call > { 20 mutable OwningPtr<BugType> BT; 21public: 22 bool evalCall(const CallExpr *CE, CheckerContext &C) const; 23}; 24} 25 26bool ExprInspectionChecker::evalCall(const CallExpr *CE, 27 CheckerContext &C) const { 28 // These checks should have no effect on the surrounding environment 29 // (globals should not be evaluated, etc), hence the use of evalCall. 30 ExplodedNode *N = C.getPredecessor(); 31 const LocationContext *LC = N->getLocationContext(); 32 33 if (!C.getCalleeName(CE).equals("clang_analyzer_eval")) 34 return false; 35 36 // A specific instantiation of an inlined function may have more constrained 37 // values than can generally be assumed. Skip the check. 38 if (LC->getParent() != 0) 39 return true; 40 41 const char *Msg = 0; 42 43 if (CE->getNumArgs() == 0) 44 Msg = "Missing assertion argument"; 45 else { 46 ProgramStateRef State = N->getState(); 47 const Expr *Assertion = CE->getArg(0); 48 SVal AssertionVal = State->getSVal(Assertion, LC); 49 50 if (AssertionVal.isUndef()) 51 Msg = "UNDEFINED"; 52 else { 53 ProgramStateRef StTrue, StFalse; 54 llvm::tie(StTrue, StFalse) = 55 State->assume(cast<DefinedOrUnknownSVal>(AssertionVal)); 56 57 if (StTrue) { 58 if (StFalse) 59 Msg = "UNKNOWN"; 60 else 61 Msg = "TRUE"; 62 } else { 63 if (StFalse) 64 Msg = "FALSE"; 65 else 66 llvm_unreachable("Invalid constraint; neither true or false."); 67 } 68 } 69 } 70 71 assert(Msg); 72 73 if (!BT) 74 BT.reset(new BugType("Checking analyzer assumptions", "debug")); 75 76 BugReport *R = new BugReport(*BT, Msg, N); 77 C.EmitReport(R); 78 79 return true; 80} 81 82void ento::registerExprInspectionChecker(CheckerManager &Mgr) { 83 Mgr.registerChecker<ExprInspectionChecker>(); 84} 85 86