[analyzer] Refactoring: include/clang/Checker -> include/clang/GR
[clang.git] / lib / Checker / BuiltinFunctionChecker.cpp
blob08fcbd6f4ef4f0169f7e62761758f019408acb8b
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;
20 namespace {
22 class BuiltinFunctionChecker : public Checker {
23 public:
24 static void *getTag() { static int tag = 0; return &tag; }
25 virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
30 void clang::RegisterBuiltinFunctionChecker(GRExprEngine &Eng) {
31 Eng.registerCheck(new BuiltinFunctionChecker());
34 bool BuiltinFunctionChecker::evalCallExpr(CheckerContext &C,const CallExpr *CE){
35 const GRState *state = C.getState();
36 const Expr *Callee = CE->getCallee();
37 SVal L = state->getSVal(Callee);
38 const FunctionDecl *FD = L.getAsFunctionDecl();
40 if (!FD)
41 return false;
43 unsigned id = FD->getBuiltinID();
45 if (!id)
46 return false;
48 switch (id) {
49 case Builtin::BI__builtin_expect: {
50 // For __builtin_expect, just return the value of the subexpression.
51 assert (CE->arg_begin() != CE->arg_end());
52 SVal X = state->getSVal(*(CE->arg_begin()));
53 C.generateNode(state->BindExpr(CE, X));
54 return true;
57 case Builtin::BI__builtin_alloca: {
58 // FIXME: Refactor into StoreManager itself?
59 MemRegionManager& RM = C.getStoreManager().getRegionManager();
60 const AllocaRegion* R =
61 RM.getAllocaRegion(CE, C.getNodeBuilder().getCurrentBlockCount(),
62 C.getPredecessor()->getLocationContext());
64 // Set the extent of the region in bytes. This enables us to use the
65 // SVal of the argument directly. If we save the extent in bits, we
66 // cannot represent values like symbol*8.
67 DefinedOrUnknownSVal Size =
68 cast<DefinedOrUnknownSVal>(state->getSVal(*(CE->arg_begin())));
70 SValBuilder& svalBuilder = C.getSValBuilder();
71 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
72 DefinedOrUnknownSVal extentMatchesSizeArg =
73 svalBuilder.evalEQ(state, Extent, Size);
74 state = state->assume(extentMatchesSizeArg, true);
76 C.generateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
77 return true;
81 return false;