blob: 9c8b51657b26a32ed5805d7c612b7d072da6b4fc [file] [log] [blame]
Zhongxing Xu7c9624b2009-12-08 09:07:59 +00001//=== 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 "GRExprEngineInternalChecks.h"
Ted Kremenek1309f9a2010-01-25 04:41:41 +000015#include "clang/Checker/PathSensitive/Checker.h"
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000016#include "clang/Basic/Builtins.h"
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000017
18using namespace clang;
19
20namespace {
21
22class BuiltinFunctionChecker : public Checker {
23public:
24 static void *getTag() { static int tag = 0; return &tag; }
25 virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
26};
27
28}
29
30void clang::RegisterBuiltinFunctionChecker(GRExprEngine &Eng) {
31 Eng.registerCheck(new BuiltinFunctionChecker());
32}
33
34bool BuiltinFunctionChecker::EvalCallExpr(CheckerContext &C,const CallExpr *CE){
35 const GRState *state = C.getState();
36 const Expr *Callee = CE->getCallee();
Ted Kremenek13976632010-02-08 16:18:51 +000037 SVal L = state->getSVal(Callee);
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000038 const FunctionDecl *FD = L.getAsFunctionDecl();
39
40 if (!FD)
41 return false;
42
43 unsigned id = FD->getBuiltinID();
44
45 if (!id)
46 return false;
47
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());
Ted Kremenek13976632010-02-08 16:18:51 +000052 SVal X = state->getSVal(*(CE->arg_begin()));
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000053 C.GenerateNode(state->BindExpr(CE, X));
54 return true;
55 }
56
57 case Builtin::BI__builtin_alloca: {
58 // FIXME: Refactor into StoreManager itself?
59 MemRegionManager& RM = C.getStoreManager().getRegionManager();
60 const MemRegion* R =
61 RM.getAllocaRegion(CE, C.getNodeBuilder().getCurrentBlockCount(),
62 C.getPredecessor()->getLocationContext());
63
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.
Ted Kremenek13976632010-02-08 16:18:51 +000067 SVal Extent = state->getSVal(*(CE->arg_begin()));
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000068 state = C.getStoreManager().setExtent(state, R, Extent);
69 C.GenerateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
70 return true;
71 }
72 }
73
74 return false;
75}