1 //=== BuiltinFunctionChecker.cpp --------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
;
23 class BuiltinFunctionChecker
: public Checker
{
25 static void *getTag() { static int tag
= 0; return &tag
; }
26 virtual bool evalCallExpr(CheckerContext
&C
, const CallExpr
*CE
);
31 void GR::RegisterBuiltinFunctionChecker(GRExprEngine
&Eng
) {
32 Eng
.registerCheck(new BuiltinFunctionChecker());
35 bool BuiltinFunctionChecker::evalCallExpr(CheckerContext
&C
,const CallExpr
*CE
){
36 const GRState
*state
= C
.getState();
37 const Expr
*Callee
= CE
->getCallee();
38 SVal L
= state
->getSVal(Callee
);
39 const FunctionDecl
*FD
= L
.getAsFunctionDecl();
44 unsigned id
= FD
->getBuiltinID();
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());
53 SVal X
= state
->getSVal(*(CE
->arg_begin()));
54 C
.generateNode(state
->BindExpr(CE
, X
));
58 case Builtin::BI__builtin_alloca
: {
59 // FIXME: Refactor into StoreManager itself?
60 MemRegionManager
& RM
= C
.getStoreManager().getRegionManager();
61 const AllocaRegion
* R
=
62 RM
.getAllocaRegion(CE
, C
.getNodeBuilder().getCurrentBlockCount(),
63 C
.getPredecessor()->getLocationContext());
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.
68 DefinedOrUnknownSVal Size
=
69 cast
<DefinedOrUnknownSVal
>(state
->getSVal(*(CE
->arg_begin())));
71 SValBuilder
& svalBuilder
= C
.getSValBuilder();
72 DefinedOrUnknownSVal Extent
= R
->getExtent(svalBuilder
);
73 DefinedOrUnknownSVal extentMatchesSizeArg
=
74 svalBuilder
.evalEQ(state
, Extent
, Size
);
75 state
= state
->assume(extentMatchesSizeArg
, true);
77 C
.generateNode(state
->BindExpr(CE
, loc::MemRegionVal(R
)));