blob: 757f158e232e335c2d1e8a50a830108116f2886a [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; }
Ted Kremenek9c149532010-12-01 21:57:22 +000025 virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000026};
27
28}
29
30void clang::RegisterBuiltinFunctionChecker(GRExprEngine &Eng) {
31 Eng.registerCheck(new BuiltinFunctionChecker());
32}
33
Ted Kremenek9c149532010-12-01 21:57:22 +000034bool BuiltinFunctionChecker::evalCallExpr(CheckerContext &C,const CallExpr *CE){
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000035 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()));
Ted Kremenekd048c6e2010-12-20 21:19:09 +000053 C.generateNode(state->BindExpr(CE, X));
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000054 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
Ted Kremenekc8413fd2010-12-02 07:49:45 +000070 SValBuilder& svalBuilder = C.getSValBuilder();
71 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
72 DefinedOrUnknownSVal extentMatchesSizeArg =
Ted Kremenek9c149532010-12-01 21:57:22 +000073 svalBuilder.evalEQ(state, Extent, Size);
Ted Kremenekc8413fd2010-12-02 07:49:45 +000074 state = state->assume(extentMatchesSizeArg, true);
Jordy Rose32f26562010-07-04 00:00:41 +000075
Ted Kremenekd048c6e2010-12-20 21:19:09 +000076 C.generateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000077 return true;
78 }
79 }
80
81 return false;
82}