BuiltinFunctionChecker.cpp revision 9b663716449b618ba0390b1dbebc54fa8e971124
1//=== BuiltinFunctionChecker.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 checker evaluates clang builtin functions. 11// 12//===----------------------------------------------------------------------===// 13 14#include "InternalChecks.h" 15#include "clang/StaticAnalyzer/Core/PathSensitive/Checker.h" 16#include "clang/Basic/Builtins.h" 17 18using namespace clang; 19using namespace ento; 20 21namespace { 22 23class BuiltinFunctionChecker : public Checker { 24public: 25 static void *getTag() { static int tag = 0; return &tag; } 26 virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE); 27}; 28 29} 30 31void ento::RegisterBuiltinFunctionChecker(ExprEngine &Eng) { 32 Eng.registerCheck(new BuiltinFunctionChecker()); 33} 34 35bool BuiltinFunctionChecker::evalCallExpr(CheckerContext &C,const CallExpr *CE){ 36 const GRState *state = C.getState(); 37 const Expr *Callee = CE->getCallee(); 38 SVal L = state->getSVal(Callee); 39 const FunctionDecl *FD = L.getAsFunctionDecl(); 40 41 if (!FD) 42 return false; 43 44 unsigned id = FD->getBuiltinID(); 45 46 if (!id) 47 return false; 48 49 switch (id) { 50 case Builtin::BI__builtin_expect: { 51 // For __builtin_expect, just return the value of the subexpression. 52 assert (CE->arg_begin() != CE->arg_end()); 53 SVal X = state->getSVal(*(CE->arg_begin())); 54 C.generateNode(state->BindExpr(CE, X)); 55 return true; 56 } 57 58 case Builtin::BI__builtin_alloca: { 59 // FIXME: Refactor into StoreManager itself? 60 MemRegionManager& RM = C.getStoreManager().getRegionManager(); 61 const AllocaRegion* R = 62 RM.getAllocaRegion(CE, C.getNodeBuilder().getCurrentBlockCount(), 63 C.getPredecessor()->getLocationContext()); 64 65 // Set the extent of the region in bytes. This enables us to use the 66 // SVal of the argument directly. If we save the extent in bits, we 67 // cannot represent values like symbol*8. 68 DefinedOrUnknownSVal Size = 69 cast<DefinedOrUnknownSVal>(state->getSVal(*(CE->arg_begin()))); 70 71 SValBuilder& svalBuilder = C.getSValBuilder(); 72 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder); 73 DefinedOrUnknownSVal extentMatchesSizeArg = 74 svalBuilder.evalEQ(state, Extent, Size); 75 state = state->assume(extentMatchesSizeArg, true); 76 77 C.generateNode(state->BindExpr(CE, loc::MemRegionVal(R))); 78 return true; 79 } 80 } 81 82 return false; 83} 84