33#include "llvm/ADT/StringMap.h"
38using ::clang::ast_matchers::MatchFinder;
45 while (!NamespaceNames.empty() && NS) {
46 if (NS->
getName() != NamespaceNames.consume_back())
48 NS = dyn_cast_or_null<NamespaceDecl>(NS->
getParent());
50 return NamespaceNames.empty() && !NS;
59 if (RD->getName() == Name)
60 if (
const auto *N = dyn_cast_or_null<NamespaceDecl>(RD->getDeclContext()))
66 return isTypeNamed(
Type, {
"absl",
"internal_statusor"},
"OperatorBase");
75 return OkVal !=
nullptr && Env.
proves(OkVal->formula());
88 if (!RD->hasDefinition())
90 for (
const auto &
Base : RD->bases())
102 return ofClass(
hasName(
"::absl::Status"));
157 "::absl::AbortedError",
"::absl::AlreadyExistsError",
158 "::absl::CancelledError",
"::absl::DataLossError",
159 "::absl::DeadlineExceededError",
"::absl::FailedPreconditionError",
160 "::absl::InternalError",
"::absl::InvalidArgumentError",
161 "::absl::NotFoundError",
"::absl::OutOfRangeError",
162 "::absl::PermissionDeniedError",
"::absl::ResourceExhaustedError",
163 "::absl::UnauthenticatedError",
"::absl::UnavailableError",
164 "::absl::UnimplementedError",
"::absl::UnknownError"))));
185 hasArgument(1,
anyOf(hasType(hasUnqualifiedDesugaredType(
186 type(equalsBoundNode(
"T")))),
187 nullPointerConstant())));
195 anyOf(hasType(hasCanonicalType(
type(equalsBoundNode(
"T")))),
196 nullPointerConstant(),
198 "std::in_place_t"))))));
244 parameterCountIs(0), isConst(),
251 parameterCountIs(0), isConst(),
281 hasName(
"::testing::internal::MakePredicateFormatterFromMatcher"))),
284 "::testing::status::internal_status::IsOkMatcher",
285 "::absl_testing::status_internal::IsOkMatcher",
286 "::testing::status::internal_status::IsOkAndHoldsMatcher",
287 "::absl_testing::status_internal::IsOkAndHoldsMatcher")))));
293 "::testing::status::StatusIs",
"absl_testing::StatusIs",
294 "::testing::status::CanonicalStatusIs",
295 "::absl_testing::CanonicalStatusIs"))),
297 "::absl::StatusCode::kOk",
"OK"))))));
304 hasName(
"::testing::internal::MakePredicateFormatterFromMatcher"))),
306 "::testing::status::internal_status::StatusIsMatcher",
307 "::testing::status::internal_status::"
308 "CanonicalStatusIsMatcher",
309 "::absl_testing::status_internal::StatusIsMatcher",
310 "::absl_testing::status_internal::"
311 "CanonicalStatusIsMatcher")))));
319 hasName(
"testing::internal::PredicateFormatterFromMatcher")))),
328 hasName(
"testing::internal::PredicateFormatterFromMatcher")))),
337 ofClass(
hasName(
"testing::AssertionResult")))));
344 hasArgument(0, hasType(booleanType())));
369 hasName(
"::absl::status_macro_internal::ReturnIfErrorAdaptor"));
375 hasName(
"::absl::status_macro_internal::ReturnIfErrorAdaptor"));
380 return hasUnqualifiedDesugaredType(
404 .CaseOfCFGStmt<CXXMemberCallExpr>(
415 .CaseOfCFGStmt<CXXOperatorCallExpr>(
437 return DiagnoseMatchSwitch(Elt, Ctx, State.Env);
456 hasTemplateArgument(0, refersToType(
type().bind(
"T"))));
467 hasName(
"absl::internal_statusor::OperatorBase"));
490 "PredicateFormatterFromMatcher");
499 "StatusIsMatcher") ||
501 "CanonicalStatusIsMatcher") ||
503 "StatusIsMatcher") ||
505 "CanonicalStatusIsMatcher");
510 "ReturnIfErrorAdaptor");
527 return {{
"status", StatusType}};
557 if (StatusOrLoc ==
nullptr)
561 State.Env.setValue(*
Expr, OkVal);
569 if (StatusOrLoc ==
nullptr)
574 if (State.Env.getValue(
locForOk(StatusLoc)) ==
nullptr)
578 copyRecord(StatusLoc, State.Env.getResultObjectLocation(*
Expr), State.Env);
580 State.Env.setStorageLocation(*
Expr, StatusLoc);
588 if (StatusLoc ==
nullptr)
592 State.Env.setValue(*
Expr, *Val);
600 assert(
Expr->getNumArgs() == 1);
601 auto *Arg =
Expr->getArg(0);
603 Arg->isPRValue() ? &State.Env.getResultObjectLocation(*Arg)
606 if (ThisLoc ==
nullptr || ArgRecord ==
nullptr)
609 auto &ThisOkVal =
valForOk(*ThisLoc, State.Env);
610 auto &ArgOkVal =
valForOk(*ArgRecord, State.Env);
611 auto &A = State.Env.arena();
612 auto &NewVal = State.Env.makeAtomicBoolValue();
613 State.Env.assume(A.makeImplies(A.makeNot(ThisOkVal.formula()),
614 A.makeNot(NewVal.formula())));
615 State.Env.assume(A.makeImplies(NewVal.formula(), ArgOkVal.formula()));
616 State.Env.setValue(
locForOk(*ThisLoc), NewVal);
622 auto &A = Env.
arena();
632 auto &LhsOkVal =
valForOk(LhsStatusLoc, Env);
633 auto &RhsOkVal =
valForOk(RhsStatusLoc, Env);
638 Env.
assume(A.makeImplies(A.makeAnd(LhsOkVal.formula(), RhsOkVal.formula()),
642 Res.formula(), A.makeEquals(LhsOkVal.formula(), RhsOkVal.formula())));
651 auto &A = Env.
arena();
667 res.formula(), A.makeEquals(LhsOkVal.formula(), RhsOkVal.formula())));
678 if (LhsStatusOrLoc ==
nullptr)
681 if (RhsStatusOrLoc ==
nullptr)
688 if (LhsStatusLoc ==
nullptr)
692 if (RhsStatusLoc ==
nullptr)
705 if (LhsAndRhsVal ==
nullptr)
709 State.Env.setValue(*
Expr, State.Env.makeNot(*LhsAndRhsVal));
711 State.Env.setValue(*
Expr, *LhsAndRhsVal);
717 return dyn_cast<RecordStorageLocation>(&PointerVal->getPointeeLoc());
732 if (LhsStatusOrLoc ==
nullptr || RhsStatusOrLoc ==
nullptr)
741 if (LhsStatusLoc ==
nullptr || RhsStatusLoc ==
nullptr)
743 auto &LhsOkVal =
valForOk(*LhsStatusLoc, Env);
744 auto &RhsOkVal =
valForOk(*RhsStatusLoc, Env);
746 auto &A = Env.
arena();
748 Res.formula(), A.makeEquals(LhsOkVal.formula(), RhsOkVal.formula())));
757 if (LhsAndRhsVal ==
nullptr)
761 State.Env.setValue(*
Expr, State.Env.makeNot(*LhsAndRhsVal));
763 State.Env.setValue(*
Expr, *LhsAndRhsVal);
771 State.Env.assume(OkVal.formula());
779 auto &A = State.Env.arena();
780 State.Env.assume(A.makeNot(OkVal.formula()));
788 if (StatusOrLoc ==
nullptr)
792 State.Env.assume(OkVal.formula());
798 assert(
Expr->getNumArgs() > 1);
801 if (StatusOrLoc ==
nullptr)
805 State.Env.assume(OkVal.formula());
813 State.Env.assume(OkVal.formula());
822 if (State.Env.getValue(
locForOk(StatusLoc)) ==
nullptr)
831 if (State.Env.getValue(
locForOk(StatusLoc)) ==
nullptr)
838 assert(
Expr->getNumArgs() == 1);
841 auto *ArgLoc = State.Env.getStorageLocation(*
Expr->getArg(0));
842 if (ArgLoc ==
nullptr)
845 State.Env.setStorageLocation(*
Expr, *ArgLoc);
851 assert(
Expr->getNumArgs() > 2);
854 if (EqVal ==
nullptr)
860 State.Env.setValue(*
Expr, State.Env.makeNot(*EqVal));
866 assert(
Expr->getNumArgs() == 1);
869 if (ArgLoc ==
nullptr)
872 if (State.Env.getValue(
locForOk(*ArgLoc)) ==
nullptr)
875 auto &ExprVal = State.Env.create<
PointerValue>(*ArgLoc);
876 State.Env.setValue(*
Expr, ExprVal);
882 assert(
Expr->getNumArgs() == 1);
885 if (ArgLoc ==
nullptr)
890 if (State.Env.getValue(
locForOk(StatusLoc)) ==
nullptr)
893 auto &ExprVal = State.Env.create<
PointerValue>(StatusLoc);
894 State.Env.setValue(*
Expr, ExprVal);
900 if (
auto *SubExprVal =
901 dyn_cast_or_null<BoolValue>(State.Env.getValue(*
Expr->getSubExpr())))
902 State.Env.setValue(*
Expr, *SubExprVal);
910 if (StatusOrLoc !=
nullptr &&
921 if (DirectCallee ==
nullptr)
924 State.Lattice.getOrCreateConstMethodReturnStorageLocation(
926 if (isStatusOrType(Expr->getType()))
927 initializeStatusOr(cast<RecordStorageLocation>(Loc), State.Env);
930 auto &ResultLoc = State.Env.getResultObjectLocation(*
Expr);
933 State.Env.setStorageLocation(*
Expr, Loc);
950 auto *Val = State.Lattice.getOrCreateConstMethodReturnValue(*
RecordLoc,
Expr,
952 State.Env.setValue(*
Expr, *Val);
973 auto *
RecordLoc = cast_or_null<RecordStorageLocation>(
974 State.Env.getStorageLocation(*
Expr->getArg(0)));
989 auto *
RecordLoc = cast_or_null<RecordStorageLocation>(
990 State.Env.getStorageLocation(*
Expr->getArg(0)));
999 State.Lattice.clearConstMethodReturnValues(*
RecordLoc);
1000 State.Lattice.clearConstMethodReturnStorageLocations(*
RecordLoc);
1017 auto *
RecordLoc = cast_or_null<RecordStorageLocation>(
1018 State.Env.getStorageLocation(*
Expr->getArg(0)));
1027 State.Env.getBoolLiteralValue(
true));
1033 BoolValue &OkMatcherVal = State.Env.getBoolLiteralValue(
true);
1042 auto &Loc = State.Env.getResultObjectLocation(*
Expr->getArg(0));
1045 if (OkMatcherVal ==
nullptr)
1061 if (ObjectLoc ==
nullptr)
1066 if (OkPredicateVal ==
nullptr)
1071 auto &StatusOk =
valForOk(*ObjectLoc, State.Env);
1073 auto &A = State.Env.arena();
1074 auto &Res = State.Env.makeAtomicBoolValue();
1076 A.makeImplies(OkPredicateVal->
formula(),
1077 A.makeEquals(StatusOk.formula(), Res.formula())));
1078 State.Env.setValue(
locForOk(State.Env.getResultObjectLocation(*
Expr)), Res);
1085 assert(
Expr->getNumArgs() > 0);
1088 if (StatusAdaptorLoc ==
nullptr)
1091 if (OkVal ==
nullptr)
1093 State.Env.setValue(
locForOk(State.Env.getResultObjectLocation(*
Expr)),
1105 if (OkVal ==
nullptr)
1107 auto &A = State.Env.arena();
1108 auto &Res = State.Env.makeAtomicBoolValue();
1109 State.Env.assume(A.makeEquals(OkVal->
formula(), Res.formula()));
1110 State.Env.setValue(*
Expr, Res);
1118 if (StatusOrLoc && State.Env.getStorageLocation(*
Expr) ==
nullptr)
1119 State.Env.setStorageLocation(*
Expr,
1120 StatusOrLoc->getSyntheticField(
"value"));
1130 StatusOrLoc->getSyntheticField(
"value")));
1138 if (StatusOrLoc && State.Env.getStorageLocation(*
Expr) ==
nullptr)
1139 State.Env.setStorageLocation(*
Expr,
1140 StatusOrLoc->getSyntheticField(
"value"));
1147 dyn_cast_or_null<PointerValue>(State.Env.getValue(*
Expr));
1150 State.Env.setValue(*
Expr, *PointerVal);
1154 dyn_cast_or_null<RecordStorageLocation>(&PointerVal->
getPointeeLoc());
1164 dyn_cast_or_null<PointerValue>(State.Env.getValue(*
Expr));
1167 State.Env.setValue(*
Expr, *PointerVal);
1171 dyn_cast_or_null<RecordStorageLocation>(&PointerVal->
getPointeeLoc());
1181 if (
auto *PointerVal = dyn_cast_or_null<PointerValue>(Env.
getValue(E)))
1182 return dyn_cast_or_null<RecordStorageLocation>(
1183 &PointerVal->getPointeeLoc());
1189 assert(
Expr->getNumArgs() > 0);
1191 auto *StatusAdaptorLoc =
1193 if (StatusAdaptorLoc ==
nullptr)
1205 if (StatusAdaptorLoc ==
nullptr)
1209 State.Env.setValue(*
Expr, OkVal);
1216 return std::move(Builder)
1225 .CaseOfCFGStmt<CXXOperatorCallExpr>(
1232 .CaseOfCFGStmt<CXXOperatorCallExpr>(
1239 .CaseOfCFGStmt<CXXConstructExpr>(
1252 .CaseOfCFGStmt<CXXOperatorCallExpr>(
1259 .CaseOfCFGStmt<CXXOperatorCallExpr>(
1266 .CaseOfCFGStmt<BinaryOperator>(
1273 .CaseOfCFGStmt<BinaryOperator>(
1305 .CaseOfCFGStmt<CXXOperatorCallExpr>(
1314 .CaseOfCFGStmt<CXXOperatorCallExpr>(
1323 .CaseOfCFGStmt<CXXMemberCallExpr>(
1331 .CaseOfCFGStmt<CXXMemberCallExpr>(
1377 .CaseOfCFGStmt<ImplicitCastExpr>(
1402 Env.getDataflowAnalysisContext().setSyntheticFieldCallback(
1403 [StatusType](
QualType Ty) -> llvm::StringMap<QualType> {
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
llvm::MachO::RecordLoc RecordLoc
Defines the clang::SourceLocation class and associated facilities.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const SmallVectorImpl< Type * > & getTypes() const
A builtin binary operation expression such as "x + y" or "x <= y".
Represents a top-level expression in a basic block.
Represents a call to a C++ constructor.
Represents a call to a member function that may be written either with member call syntax (e....
SourceLocation getExprLoc() const LLVM_READONLY
A call to an overloaded operator written using operator syntax.
Represents a C++ struct/union/class.
bool hasDefinition() const
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Represents a class template specialization, which refers to a class template with a given set of temp...
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
ASTContext & getASTContext() const LLVM_READONLY
This represents one expression.
Represents a function declaration or definition.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represent a C++ namespace.
A (possibly-)qualified type.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
QualType getAsType() const
Retrieve the type for a type template argument.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isRecordType() const
const Formula & formula() const
Collects cases of a "match switch": a collection of matchers paired with callbacks,...
ASTContext & getASTContext() final
DataflowAnalysis(ASTContext &Context)
CachedConstAccessorsLattice< NoopLattice > Lattice
Holds the state of the program (store and heap) at a given program point.
StorageLocation * getStorageLocation(const ValueDecl &D) const
Returns the storage location assigned to D in the environment, or null if D isn't assigned a storage ...
BoolValue & makeAtomicBoolValue() const
Returns an atomic boolean value.
bool proves(const Formula &) const
Returns true if the formula is always true when this point is reached.
Value * getValue(const StorageLocation &Loc) const
Returns the value assigned to Loc in the environment or null if Loc isn't assigned a value in the env...
void assume(const Formula &)
Record a fact that must be true if this point in the program is reached.
void setValue(const StorageLocation &Loc, Value &Val)
Assigns Val as the value of Loc in the environment.
std::enable_if_t< std::is_base_of_v< StorageLocation, T >, T * > get(const ValueDecl &D) const
Returns the result of casting getStorageLocation(...) to a subclass of StorageLocation (using cast_or...
Models a symbolic pointer. Specifically, any value of type T*.
StorageLocation & getPointeeLoc() const
A storage location for a record (struct, class, or union).
StorageLocation & getSyntheticField(llvm::StringRef Name) const
Returns the storage location for the synthetic field Name.
Base class for elements of the local variable store and of the heap.
Base class for all values computed by abstract interpretation.
UncheckedStatusOrAccessDiagnoser(UncheckedStatusOrAccessModelOptions Options={})
llvm::SmallVector< SourceLocation > operator()(const CFGElement &Elt, ASTContext &Ctx, const TransferStateForDiagnostics< UncheckedStatusOrAccessModel::Lattice > &State)
UncheckedStatusOrAccessModel(ASTContext &Ctx, Environment &Env)
void transfer(const CFGElement &Elt, Lattice &L, Environment &Env)
internal::Matcher< QualType > TypeMatcher
const internal::VariadicDynCastAllOfMatcher< Stmt, DeclRefExpr > declRefExpr
Matches expressions that refer to declarations.
const internal::VariadicOperatorMatcherFunc< 1, 1 > unless
Matches if the provided matcher does not match.
internal::Matcher< Decl > DeclarationMatcher
Types of matchers for the top-level classes in the AST class hierarchy.
const internal::VariadicDynCastAllOfMatcher< Stmt, ImplicitCastExpr > implicitCastExpr
Matches the implicit cast nodes of Clang's AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
const internal::VariadicDynCastAllOfMatcher< Decl, NamedDecl > namedDecl
Matches a declaration of anything that could have a name.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicFunction< internal::Matcher< NamedDecl >, StringRef, internal::hasAnyNameFunc > hasAnyName
Matches NamedDecl nodes that have any of the specified names.
internal::Matcher< Stmt > StatementMatcher
const internal::VariadicDynCastAllOfMatcher< Decl, EnumConstantDecl > enumConstantDecl
Matches enum constants.
const internal::VariadicDynCastAllOfMatcher< Stmt, BinaryOperator > binaryOperator
Matches binary operator expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXConstructExpr > cxxConstructExpr
Matches constructor call expressions (including implicit ones).
const internal::VariadicDynCastAllOfMatcher< Decl, ClassTemplateSpecializationDecl > classTemplateSpecializationDecl
Matches C++ class template specializations.
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
const AstTypeMatcher< RecordType > recordType
const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl > cxxRecordDecl
Matches C++ class declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, RecordDecl > recordDecl
Matches class, struct, and union declarations.
internal::PolymorphicMatcher< internal::HasDeclarationMatcher, void(internal::HasDeclarationSupportedTypes), internal::Matcher< Decl > > hasDeclaration(const internal::Matcher< Decl > &InnerMatcher)
Matches a node if the declaration associated with that node matches the given matcher.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits< unsigned >::max()> anyOf
Matches if any of the given matchers matches.
const internal::VariadicAllOfMatcher< QualType > qualType
Matches QualTypes in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXThisExpr > cxxThisExpr
Matches implicit and explicit this expressions.
static void transferLoggingCheckEqImpl(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static void transferStatusOrReturningCall(const CallExpr *Expr, LatticeTransferState &State)
static bool doHandleConstAccessorMemberCall(const CallExpr *Expr, RecordStorageLocation *RecordLoc, const MatchFinder::MatchResult &Result, LatticeTransferState &State)
static void transferValueAssignmentCall(const CXXOperatorCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
TransferState< UncheckedStatusOrAccessModel::Lattice > LatticeTransferState
static ClassTemplateSpecializationDecl * getStatusOrBaseClass(const QualType &Ty)
static bool isStatusOrOperatorBaseType(QualType Type)
static void transferValueCall(const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static StorageLocation & locForOkMatcher(RecordStorageLocation &StatusLoc)
static void handleConstAccessorMemberCall(const CallExpr *Expr, RecordStorageLocation *RecordLoc, const MatchFinder::MatchResult &Result, LatticeTransferState &State)
static auto isStatusMemberCallWithName(llvm::StringRef member_name)
static auto buildDiagnoseMatchSwitch(const UncheckedStatusOrAccessModelOptions &Options)
static auto isStatusOrValueConstructor()
static auto isComparisonOperatorCall(llvm::StringRef operator_name)
static void transferAssertionResultConstructFromBoolCall(const CXXConstructExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static void transferMacroAdaptorCall(const clang::CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
RecordStorageLocation & locForStatus(RecordStorageLocation &StatusOrLoc)
static auto isLoggingCheckEqImpl()
static void transferNotOkStatusCall(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static BoolValue * evaluateStatusEquality(RecordStorageLocation &LhsStatusLoc, RecordStorageLocation &RhsStatusLoc, Environment &Env)
static void transferStatusConstructor(const CXXConstructExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static BoolValue * evaluateStatusOrEquality(RecordStorageLocation &LhsStatusOrLoc, RecordStorageLocation &RhsStatusOrLoc, Environment &Env)
static void transferMakePredicateFormatterFromIsOkMatcherCall(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static auto isNonConstMemberOperatorCall()
static bool isPredicateFormatterFromMatcherType(QualType Type)
static auto isStatusOrOperatorCallWithName(llvm::StringRef operator_name)
clang::ast_matchers::TypeMatcher statusType()
static void transferNonConstMemberOperatorCall(const CXXOperatorCallExpr *Expr, const MatchFinder::MatchResult &Result, LatticeTransferState &State)
static auto isAssertionResultOperatorBoolCall()
static void transferValueConstructor(const CXXConstructExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static auto isOkStatusCall()
static auto isStatusOrPtrReturningCall()
static void transferComparisonOperator(const CXXOperatorCallExpr *Expr, LatticeTransferState &State, bool IsNegative)
static auto isMacroAdaptorCall()
clang::ast_matchers::DeclarationMatcher statusOrClass()
static void transferOkStatusCall(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static auto isPointerComparisonOperatorCall(std::string operator_name)
clang::ast_matchers::TypeMatcher statusOrType()
static auto isStatusConstructor()
static bool isSafeUnwrap(RecordStorageLocation *StatusOrLoc, const Environment &Env)
static void transferPointerComparisonOperator(const BinaryOperator *Expr, LatticeTransferState &State, bool IsNegative)
static auto returnIfErrorAdaptorType()
static void transferNonConstMemberCall(const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &Result, LatticeTransferState &State)
static void transferStatusOrOkCall(const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static bool namespaceEquals(const NamespaceDecl *NS, clang::ArrayRef< clang::StringRef > NamespaceNames)
static auto isReturnIfErrorAdaptorOperatorBoolCall()
static bool isTypeNamed(QualType Type, clang::ArrayRef< clang::StringRef > NS, StringRef Name)
static void transferConstAccessorMemberCall(const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &Result, LatticeTransferState &State)
static void transferStatusOrConstructor(const CXXConstructExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static void transferLoggingGetReferenceableValueCall(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static auto valueOperatorCall()
clang::ast_matchers::DeclarationMatcher statusClass()
static auto ofClassStatus()
static RecordStorageLocation * getSmartPtrLikeStorageLocation(const Expr &E, const Environment &Env)
static bool isStatusIsMatcherType(QualType Type)
static void handleNonConstMemberCall(const CallExpr *Expr, RecordStorageLocation *RecordLoc, const MatchFinder::MatchResult &Result, LatticeTransferState &State)
BoolValue & initializeStatusOr(RecordStorageLocation &StatusOrLoc, Environment &Env)
static void transferAsStatusCallWithStatusOr(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static auto possiblyReferencedStatusOrType()
static auto isLoggingGetReferenceableValueCall()
QualType findStatusType(const ASTContext &Ctx)
static auto returnIfErrorAdaptorClass()
BoolValue & initializeStatus(RecordStorageLocation &StatusLoc, Environment &Env)
static void transferDerefCall(const CXXOperatorCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static void transferPointerToBoolean(const ImplicitCastExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
llvm::StringMap< QualType > getSyntheticFields(QualType Ty, QualType StatusType, const CXXRecordDecl &RD)
StorageLocation & locForOk(RecordStorageLocation &StatusLoc)
static void transferStatusIsOkMatcherCall(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static auto isAsStatusCallWithStatusOr()
static auto isMakePredicateFormatterFromIsOkMatcherCall()
static auto isNonConstMemberCall()
static auto isAssertionResultConstructFromBoolCall()
static auto isConstPointerAccessorMemberOperatorCall()
static auto isStatusOrMemberCallWithName(llvm::StringRef member_name)
static BoolValue * evaluateEquality(const Expr *LhsExpr, const Expr *RhsExpr, Environment &Env)
static void transferStatusCall(const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static void transferConstPointerAccessorMemberCall(const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &Result, LatticeTransferState &State)
static void transferStatusOkCall(const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static void transferPredicateFormatterMatcherCall(const CXXOperatorCallExpr *Expr, LatticeTransferState &State, bool IsStatusOr)
static void transferAssertionResultOperatorBoolCall(const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static StorageLocation & locForOkPredicate(RecordStorageLocation &StatusLoc)
static void transferMakePredicateFormatterFromStatusIsMatcherCall(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static void transferEmplaceCall(const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static auto isPredicateFormatterFromStatusMatcherCall()
static auto isStatusOrValueAssignmentCall()
static void transferAsStatusCallWithStatus(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static void transferStatusOrPtrReturningCall(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static auto isStatusOrConstructor()
static BoolValue * evaluatePointerEquality(const Expr *LhsExpr, const Expr *RhsExpr, Environment &Env)
static QualType getStatusOrValueType(ClassTemplateSpecializationDecl *TRD)
static RecordStorageLocation * getPointeeLocation(const Expr &Expr, Environment &Env)
static void transferArrowCall(const CXXOperatorCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static void transferStatusPtrReturningCall(const CallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static bool isAssertionResultType(QualType Type)
static auto isConstAccessorMemberCall()
static auto isAsStatusCallWithStatus()
BoolValue & valForOk(RecordStorageLocation &StatusLoc, Environment &Env)
bool isStatusOrType(QualType Type)
static auto isNotOkStatusCall()
static auto isStatusPtrReturningCall()
static void transferConstPointerAccessorMemberOperatorCall(const CXXOperatorCallExpr *Expr, const MatchFinder::MatchResult &Result, LatticeTransferState &State)
static auto isStatusIsOkMatcherCall()
static auto isPredicateFormatterFromStatusOrMatcherCall()
static void transferStatusUpdateCall(const CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
static void handleConstPointerAccessorMemberCall(const CallExpr *Expr, RecordStorageLocation *RecordLoc, const MatchFinder::MatchResult &Result, LatticeTransferState &State)
static auto isStatusOrReturningCall()
static bool IsMacroAdaptorType(clang::QualType type)
static auto isMakePredicateFormatterFromStatusIsMatcherCall()
static void transferConstAccessorMemberOperatorCall(const CXXOperatorCallExpr *Expr, const MatchFinder::MatchResult &Result, LatticeTransferState &State)
static auto isConstPointerAccessorMemberCall()
CFGMatchSwitch< LatticeTransferState > buildTransferMatchSwitch(ASTContext &Ctx, CFGMatchSwitchBuilder< LatticeTransferState > Builder)
static auto ofClassReturnIfErrorAdaptor()
static auto isConstAccessorMemberOperatorCall()
bool isStatusType(QualType Type)
static void transferReturnIfErrorAdaptorOperatorBoolCall(const clang::CXXMemberCallExpr *Expr, const MatchFinder::MatchResult &, LatticeTransferState &State)
clang::ast_matchers::DeclarationMatcher statusOrOperatorBaseClass()
ast_matchers::StatementMatcher isSmartPointerLikeValueMethodCall(clang::StringRef MethodName="value")
void transferSmartPointerLikeCachedDeref(const CallExpr *DerefExpr, RecordStorageLocation *SmartPointerLoc, TransferState< LatticeT > &State, llvm::function_ref< void(StorageLocation &)> InitializeLoc)
A transfer function for operator* (and value) calls that can be cached.
ast_matchers::StatementMatcher isPointerLikeOperatorStar()
Matchers: For now, these match on any class with an operator* or operator-> where the return types ha...
void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, Environment &Env, QualType TypeToCopy=QualType())
Copies a record (struct, class, or union) from Src to Dst.
void transferSmartPointerLikeCachedGet(const CallExpr *GetExpr, RecordStorageLocation *SmartPointerLoc, TransferState< LatticeT > &State, llvm::function_ref< void(StorageLocation &)> InitializeLoc)
A transfer function for operator-> (and get) calls that can be cached.
internal::Matcher< NamedDecl > hasName(StringRef Name)
Matches NamedDecl nodes that have the specified name.
std::function< Result(const CFGElement &, ASTContext &, State &)> CFGMatchSwitch
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXMemberCallExpr > cxxMemberCallExpr
Matches member call expressions.
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXOperatorCallExpr > cxxOperatorCallExpr
Matches overloaded operator calls.
const AstTypeMatcher< PointerType > pointerType
internal::PolymorphicMatcher< internal::HasOverloadedOperatorNameMatcher, AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl), std::vector< std::string > > hasOverloadedOperatorName(StringRef Name)
Matches overloaded operator names.
RecordStorageLocation * getImplicitObjectLocation(const CXXMemberCallExpr &MCE, const Environment &Env)
Returns the storage location for the implicit object of a CXXMemberCallExpr, or null if none is defin...
const internal::VariadicDynCastAllOfMatcher< Decl, CXXMethodDecl > cxxMethodDecl
Matches method declarations.
ast_matchers::StatementMatcher isSmartPointerLikeGetMethodCall(clang::StringRef MethodName="get")
ast_matchers::StatementMatcher isPointerLikeOperatorArrow()
const AstTypeMatcher< ReferenceType > referenceType
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)
Contains all information for a given match.
A read-only version of TransferState.
Contains all information for a given match.