[analyzer] Refactoring: Move stuff into namespace 'GR'.
[clang.git] / lib / GR / Checkers / BuiltinFunctionChecker.cpp
blobdc55a65ff5a4fee4a2bf968a906fbc3de294cb68
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.
12 //===----------------------------------------------------------------------===//
14 #include "GRExprEngineInternalChecks.h"
15 #include "clang/GR/PathSensitive/Checker.h"
16 #include "clang/Basic/Builtins.h"
18 using namespace clang;
19 using namespace GR;
21 namespace {
23 class BuiltinFunctionChecker : public Checker {
24 public:
25 static void *getTag() { static int tag = 0; return &tag; }
26 virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
31 void GR::RegisterBuiltinFunctionChecker(GRExprEngine &Eng) {
32 Eng.registerCheck(new BuiltinFunctionChecker());
35 bool 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();
41 if (!FD)
42 return false;
44 unsigned id = FD->getBuiltinID();
46 if (!id)
47 return false;
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;
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());
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())));
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);
77 C.generateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
78 return true;
82 return false;