26 const Expr *
E,
bool StopAtFirstRefCountedObj,
27 std::function<
bool(
const clang::Expr *,
bool)> callback) {
29 if (
auto *tempExpr = dyn_cast<MaterializeTemporaryExpr>(
E)) {
30 E = tempExpr->getSubExpr();
33 if (
auto *tempExpr = dyn_cast<CXXBindTemporaryExpr>(
E)) {
34 E = tempExpr->getSubExpr();
37 if (
auto *tempExpr = dyn_cast<CXXConstructExpr>(
E)) {
38 if (
auto *
C = tempExpr->getConstructor()) {
40 return callback(
E,
true);
44 if (
auto *POE = dyn_cast<PseudoObjectExpr>(
E)) {
45 if (
auto *RF = POE->getResultExpr()) {
50 if (
auto *tempExpr = dyn_cast<ParenExpr>(
E)) {
51 E = tempExpr->getSubExpr();
54 if (
auto *
Expr = dyn_cast<ConditionalOperator>(
E)) {
60 if (
auto *
cast = dyn_cast<CastExpr>(
E)) {
61 if (StopAtFirstRefCountedObj) {
62 if (
auto *ConversionFunc =
63 dyn_cast_or_null<FunctionDecl>(
cast->getConversionFunction())) {
65 return callback(
E,
true);
70 E =
cast->getSubExpr();
73 if (
auto *call = dyn_cast<CallExpr>(
E)) {
74 if (
auto *memberCall = dyn_cast<CXXMemberCallExpr>(call)) {
75 if (
auto *
decl = memberCall->getMethodDecl()) {
77 if (IsGetterOfRefCt && *IsGetterOfRefCt) {
78 E = memberCall->getImplicitObjectArgument();
79 if (StopAtFirstRefCountedObj) {
80 return callback(
E,
true);
87 if (
auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(
E)) {
88 if (operatorCall->getNumArgs() == 1) {
89 E = operatorCall->getArg(0);
94 if (
auto *callee = call->getDirectCallee()) {
96 if (StopAtFirstRefCountedObj)
97 return callback(
E,
true);
104 return callback(
E,
true);
107 return callback(
E,
true);
109 if (callee->isInStdNamespace() &&
safeGetName(callee) ==
"forward") {
120 if (
auto *ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(
E)) {
121 if (
auto *Method = ObjCMsgExpr->getMethodDecl()) {
123 return callback(
E,
true);
126 if (
auto *unaryOp = dyn_cast<UnaryOperator>(
E)) {
128 E = unaryOp->getSubExpr();
135 return callback(
E,
false);
140 if (
auto *Ref = dyn_cast<DeclRefExpr>(
E)) {
141 if (
auto *
D = dyn_cast_or_null<VarDecl>(Ref->getFoundDecl())) {
142 if (isa<ParmVarDecl>(
D) ||
D->isLocalVarDecl())
150 return isa<CXXThisExpr>(
E);
154 if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(
E)) {
155 if (
auto *Callee = MCE->getDirectCallee()) {
157 if (Name ==
"get" || Name ==
"ptr") {
158 auto *ThisArg = MCE->getImplicitObjectArgument();
162 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E)) {
163 if (OCE->getOperator() == OO_Star && OCE->getNumArgs() == 1)
166 auto *ME = dyn_cast<MemberExpr>(
E);
169 auto *
D = ME->getMemberDecl();
172 auto T =
D->getType();
180 for (
const Stmt *Child : S->children()) {
181 if (Child && !
Visit(Child))
189 RV = RV->IgnoreParenCasts();
190 if (isa<CXXNullPtrLiteralExpr>(RV))
199 auto *MCE = dyn_cast<CXXMemberCallExpr>(
E);
202 auto *Callee = MCE->getDirectCallee();
205 auto *Body = Callee->getBody();
208 auto [CacheIt, IsNew] =
Cache.insert(std::make_pair(Callee,
false));
211 return CacheIt->second;
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Represents a C++ struct/union/class.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Decl - This represents one declaration (or definition), e.g.
bool isACallToEnsureFn(const Expr *E) const
bool VisitReturnStmt(const ReturnStmt *RS)
bool VisitStmt(const Stmt *S)
This represents one expression.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Stmt - This represents one statement.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isCtorOfSafePtr(const clang::FunctionDecl *F)
bool isPtrConversion(const FunctionDecl *F)
bool isCtorOfRefCounted(const clang::FunctionDecl *F)
bool isASafeCallArg(const Expr *E)
For E referring to a ref-countable/-counted pointer/reference we return whether it's a safe call argu...
bool isSingleton(const FunctionDecl *F)
bool isRefCounted(const CXXRecordDecl *R)
bool isOwnerPtrType(const clang::QualType T)
bool isSafePtrType(const clang::QualType T)
std::optional< bool > isGetterOfSafePtr(const CXXMethodDecl *M)
const FunctionProtoType * T
bool isSafePtr(clang::CXXRecordDecl *Decl)
bool tryToFindPtrOrigin(const Expr *E, bool StopAtFirstRefCountedObj, std::function< bool(const clang::Expr *, bool)> callback)
This function de-facto defines a set of transformations that we consider safe (in heuristical sense).
std::string safeGetName(const T *ASTNode)
bool isCtorOfCheckedPtr(const clang::FunctionDecl *F)
bool isCheckedPtr(const std::string &Name)
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
bool isConstOwnerPtrMemberExpr(const clang::Expr *E)