blob: 6761a7a567afa30a9038545e886624daedcd8148 [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();
Jordy Rose32f26562010-07-04 00:00:41 +000060 const AllocaRegion* R =
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000061 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.
Jordy Rose32f26562010-07-04 00:00:41 +000067 DefinedOrUnknownSVal Size =
68 cast<DefinedOrUnknownSVal>(state->getSVal(*(CE->arg_begin())));
69
70 ValueManager& ValMgr = C.getValueManager();
71 DefinedOrUnknownSVal Extent = R->getExtent(ValMgr);
72
Ted Kremenek846eabd2010-12-01 21:28:31 +000073 SValBuilder& svalBuilder = ValMgr.getSValBuilder();
Jordy Rose32f26562010-07-04 00:00:41 +000074 DefinedOrUnknownSVal ExtentMatchesSizeArg =
Ted Kremenek846eabd2010-12-01 21:28:31 +000075 svalBuilder.EvalEQ(state, Extent, Size);
Jordy Rose32f26562010-07-04 00:00:41 +000076 state = state->Assume(ExtentMatchesSizeArg, true);
77
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000078 C.GenerateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
79 return true;
80 }
81 }
82
83 return false;
84}