21 using namespace clang;
26 class BuiltinFunctionChecker :
public Checker<eval::Call> {
28 bool evalCall(
const CallEvent &Call, CheckerContext &C)
const;
33 bool BuiltinFunctionChecker::evalCall(
const CallEvent &Call,
34 CheckerContext &C)
const {
36 const auto *FD = dyn_cast_or_null<FunctionDecl>(
Call.getDecl());
41 const Expr *CE =
Call.getOriginExpr();
43 switch (FD->getBuiltinID()) {
47 case Builtin::BI__builtin_assume: {
48 assert (
Call.getNumArgs() > 0);
49 SVal Arg =
Call.getArgSVal(0);
53 state =
state->assume(Arg.castAs<DefinedOrUnknownSVal>(),
true);
57 C.generateSink(
C.getState(),
C.getPredecessor());
65 case Builtin::BI__builtin_unpredictable:
66 case Builtin::BI__builtin_expect:
67 case Builtin::BI__builtin_expect_with_probability:
68 case Builtin::BI__builtin_assume_aligned:
69 case Builtin::BI__builtin_addressof:
70 case Builtin::BI__builtin_function_start: {
76 assert (
Call.getNumArgs() > 0);
77 SVal Arg =
Call.getArgSVal(0);
78 C.addTransition(
state->BindExpr(CE, LCtx, Arg));
82 case Builtin::BI__builtin_alloca_with_align:
83 case Builtin::BI__builtin_alloca: {
85 MemRegionManager& RM =
C.getStoreManager().getRegionManager();
86 const AllocaRegion* R =
87 RM.getAllocaRegion(CE,
C.blockCount(),
C.getLocationContext());
99 C.addTransition(
state->BindExpr(CE, LCtx, loc::MemRegionVal(R)));
103 case Builtin::BI__builtin_dynamic_object_size:
104 case Builtin::BI__builtin_object_size:
105 case Builtin::BI__builtin_constant_p: {
108 SValBuilder &SVB =
C.getSValBuilder();
109 SVal
V = UnknownVal();
114 BasicValueFactory &BVF = SVB.getBasicValueFactory();
115 BVF.getAPSIntType(CE->
getType()).apply(Result);
116 V = SVB.makeIntVal(Result);
119 if (FD->getBuiltinID() == Builtin::BI__builtin_constant_p) {
124 V = SVB.makeIntVal(0, CE->
getType());
127 C.addTransition(
state->BindExpr(CE, LCtx,
V));
133 void ento::registerBuiltinFunctionChecker(CheckerManager &mgr) {
134 mgr.registerChecker<BuiltinFunctionChecker>();
137 bool ento::shouldRegisterBuiltinFunctionChecker(
const CheckerManager &mgr) {