clang 22.0.0git
AssumeModeling.cpp
Go to the documentation of this file.
1//=== AssumeModeling.cpp --------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This checker evaluates the builting assume functions.
10// This checker also sinks execution paths leaving [[assume]] attributes with
11// false assumptions.
12//
13//===----------------------------------------------------------------------===//
14
21#include "llvm/ADT/STLExtras.h"
22
23using namespace clang;
24using namespace ento;
25
26namespace {
27class AssumeModelingChecker
28 : public Checker<eval::Call, check::PostStmt<AttributedStmt>> {
29public:
30 void checkPostStmt(const AttributedStmt *A, CheckerContext &C) const;
31 bool evalCall(const CallEvent &Call, CheckerContext &C) const;
32};
33} // namespace
34
35void AssumeModelingChecker::checkPostStmt(const AttributedStmt *A,
36 CheckerContext &C) const {
38 return;
39
40 for (const auto *Attr : getSpecificAttrs<CXXAssumeAttr>(A->getAttrs())) {
41 SVal AssumptionVal = C.getSVal(Attr->getAssumption());
42
43 // The assumption is not evaluated at all if it had sideffects; skip them.
44 if (AssumptionVal.isUnknown())
45 continue;
46
47 const auto *Assumption = AssumptionVal.getAsInteger();
48 if (Assumption && Assumption->isZero()) {
49 C.addSink();
50 }
51 }
52}
53
54bool AssumeModelingChecker::evalCall(const CallEvent &Call,
55 CheckerContext &C) const {
56 ProgramStateRef State = C.getState();
57 const auto *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
58 if (!FD)
59 return false;
60
61 if (!llvm::is_contained({Builtin::BI__builtin_assume, Builtin::BI__assume},
62 FD->getBuiltinID())) {
63 return false;
64 }
65
66 assert(Call.getNumArgs() > 0);
67 SVal Arg = Call.getArgSVal(0);
68 if (Arg.isUndef())
69 return true; // Return true to model purity.
70
71 State = State->assume(Arg.castAs<DefinedOrUnknownSVal>(), true);
72 if (!State) {
73 C.addSink();
74 return true;
75 }
76
77 C.addTransition(State);
78 return true;
79}
80
81void ento::registerAssumeModeling(CheckerManager &Mgr) {
82 Mgr.registerChecker<AssumeModelingChecker>();
83}
84
85bool ento::shouldRegisterAssumeModeling(const CheckerManager &) { return true; }
Defines enum values for all the target-independent builtin functions.
Represents an attribute applied to a statement.
Definition Stmt.h:2203
ArrayRef< const Attr * > getAttrs() const
Definition Stmt.h:2235
CHECKER * registerChecker(AT &&...Args)
Register a single-part checker (derived from Checker): construct its singleton instance,...
Simple checker classes that implement one frontend (i.e.
Definition Checker.h:553
bool isUndef() const
Definition SVals.h:107
const llvm::APSInt * getAsInteger() const
If this SVal is loc::ConcreteInt or nonloc::ConcreteInt, return a pointer to APSInt which is held in ...
Definition SVals.cpp:111
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition SVals.h:83
bool isUnknown() const
Definition SVals.h:105
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The JSON file list parser is used to communicate input to InstallAPI.
bool hasSpecificAttr(const Container &container)
auto getSpecificAttrs(const Container &container)