20 using namespace clang;
25 class BuiltinFunctionChecker :
public Checker<eval::Call> {
27 bool evalCall(
const CallEvent &Call, CheckerContext &C)
const;
32 bool BuiltinFunctionChecker::evalCall(
const CallEvent &Call,
33 CheckerContext &C)
const {
35 const auto *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
40 const Expr *CE = Call.getOriginExpr();
42 switch (FD->getBuiltinID()) {
46 case Builtin::BI__builtin_assume: {
47 assert (Call.getNumArgs() > 0);
48 SVal Arg = Call.getArgSVal(0);
52 state = state->assume(Arg.castAs<DefinedOrUnknownSVal>(),
true);
56 C.generateSink(C.getState(), C.getPredecessor());
60 C.addTransition(state);
64 case Builtin::BI__builtin_unpredictable:
65 case Builtin::BI__builtin_expect:
66 case Builtin::BI__builtin_assume_aligned:
67 case Builtin::BI__builtin_addressof: {
72 assert (Call.getNumArgs() > 0);
73 SVal Arg = Call.getArgSVal(0);
74 C.addTransition(state->BindExpr(CE, LCtx, Arg));
78 case Builtin::BI__builtin_alloca_with_align:
79 case Builtin::BI__builtin_alloca: {
81 MemRegionManager& RM = C.getStoreManager().getRegionManager();
82 const AllocaRegion* R =
83 RM.getAllocaRegion(CE, C.blockCount(), C.getLocationContext());
88 auto Size = Call.getArgSVal(0);
92 SValBuilder& svalBuilder = C.getSValBuilder();
93 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
94 DefinedOrUnknownSVal extentMatchesSizeArg =
95 svalBuilder.evalEQ(state, Extent, Size.castAs<DefinedOrUnknownSVal>());
96 state = state->assume(extentMatchesSizeArg,
true);
97 assert(state &&
"The region should not have any previous constraints");
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 LangOptions &LO) {
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
Strictly evaluate the expression.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
APValue Val
Val - This is the value the expression can be folded to.
This represents one expression.
Dataflow Directional Tag Classes.
EvalResult is a struct with detailed info about an evaluated expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
Defines enum values for all the target-independent builtin functions.