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
;
22 class BuiltinFunctionChecker
: public Checker
{
24 static void *getTag() { static int tag
= 0; return &tag
; }
25 virtual bool evalCallExpr(CheckerContext
&C
, const CallExpr
*CE
);
30 void clang::RegisterBuiltinFunctionChecker(GRExprEngine
&Eng
) {
31 Eng
.registerCheck(new BuiltinFunctionChecker());
34 bool BuiltinFunctionChecker::evalCallExpr(CheckerContext
&C
,const CallExpr
*CE
){
35 const GRState
*state
= C
.getState();
36 const Expr
*Callee
= CE
->getCallee();
37 SVal L
= state
->getSVal(Callee
);
38 const FunctionDecl
*FD
= L
.getAsFunctionDecl();
43 unsigned id
= FD
->getBuiltinID();
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());
52 SVal X
= state
->getSVal(*(CE
->arg_begin()));
53 C
.generateNode(state
->BindExpr(CE
, X
));
57 case Builtin::BI__builtin_alloca
: {
58 // FIXME: Refactor into StoreManager itself?
59 MemRegionManager
& RM
= C
.getStoreManager().getRegionManager();
60 const AllocaRegion
* R
=
61 RM
.getAllocaRegion(CE
, C
.getNodeBuilder().getCurrentBlockCount(),
62 C
.getPredecessor()->getLocationContext());
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.
67 DefinedOrUnknownSVal Size
=
68 cast
<DefinedOrUnknownSVal
>(state
->getSVal(*(CE
->arg_begin())));
70 SValBuilder
& svalBuilder
= C
.getSValBuilder();
71 DefinedOrUnknownSVal Extent
= R
->getExtent(svalBuilder
);
72 DefinedOrUnknownSVal extentMatchesSizeArg
=
73 svalBuilder
.evalEQ(state
, Extent
, Size
);
74 state
= state
->assume(extentMatchesSizeArg
, true);
76 C
.generateNode(state
->BindExpr(CE
, loc::MemRegionVal(R
)));