blob: 27162e40af9ddd88858e4a398a5a616d2f7d432b [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
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000014#include "ExprEngineInternalChecks.h"
Argyrios Kyrtzidis98cabba2010-12-22 18:51:49 +000015#include "clang/GR/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;
Argyrios Kyrtzidis5a4f98f2010-12-22 18:53:20 +000019using namespace GR;
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000020
21namespace {
22
23class BuiltinFunctionChecker : public Checker {
24public:
25 static void *getTag() { static int tag = 0; return &tag; }
Ted Kremenek9c149532010-12-01 21:57:22 +000026 virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000027};
28
29}
30
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000031void GR::RegisterBuiltinFunctionChecker(ExprEngine &Eng) {
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000032 Eng.registerCheck(new BuiltinFunctionChecker());
33}
34
Ted Kremenek9c149532010-12-01 21:57:22 +000035bool BuiltinFunctionChecker::evalCallExpr(CheckerContext &C,const CallExpr *CE){
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000036 const GRState *state = C.getState();
37 const Expr *Callee = CE->getCallee();
Ted Kremenek13976632010-02-08 16:18:51 +000038 SVal L = state->getSVal(Callee);
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000039 const FunctionDecl *FD = L.getAsFunctionDecl();
40
41 if (!FD)
42 return false;
43
44 unsigned id = FD->getBuiltinID();
45
46 if (!id)
47 return false;
48
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());
Ted Kremenek13976632010-02-08 16:18:51 +000053 SVal X = state->getSVal(*(CE->arg_begin()));
Ted Kremenekd048c6e2010-12-20 21:19:09 +000054 C.generateNode(state->BindExpr(CE, X));
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000055 return true;
56 }
57
58 case Builtin::BI__builtin_alloca: {
59 // FIXME: Refactor into StoreManager itself?
60 MemRegionManager& RM = C.getStoreManager().getRegionManager();
Jordy Rose32f26562010-07-04 00:00:41 +000061 const AllocaRegion* R =
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000062 RM.getAllocaRegion(CE, C.getNodeBuilder().getCurrentBlockCount(),
63 C.getPredecessor()->getLocationContext());
64
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.
Jordy Rose32f26562010-07-04 00:00:41 +000068 DefinedOrUnknownSVal Size =
69 cast<DefinedOrUnknownSVal>(state->getSVal(*(CE->arg_begin())));
70
Ted Kremenekc8413fd2010-12-02 07:49:45 +000071 SValBuilder& svalBuilder = C.getSValBuilder();
72 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
73 DefinedOrUnknownSVal extentMatchesSizeArg =
Ted Kremenek9c149532010-12-01 21:57:22 +000074 svalBuilder.evalEQ(state, Extent, Size);
Ted Kremenekc8413fd2010-12-02 07:49:45 +000075 state = state->assume(extentMatchesSizeArg, true);
Jordy Rose32f26562010-07-04 00:00:41 +000076
Ted Kremenekd048c6e2010-12-20 21:19:09 +000077 C.generateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
Zhongxing Xu7c9624b2009-12-08 09:07:59 +000078 return true;
79 }
80 }
81
82 return false;
83}