26 const Expr *E,
bool StopAtFirstRefCountedObj,
32 if (
auto *DRE = dyn_cast<DeclRefExpr>(E)) {
33 if (
auto *VD = dyn_cast_or_null<VarDecl>(DRE->getDecl())) {
34 auto QT = VD->getType();
36 if (VD->hasGlobalStorage() && (IsImmortal || QT.isConstQualified()))
37 return callback(E,
true);
38 if (VD->hasGlobalStorage() && isSafeGlobalDecl(VD))
39 return callback(E,
true);
42 if (
auto *tempExpr = dyn_cast<MaterializeTemporaryExpr>(E)) {
43 E = tempExpr->getSubExpr();
46 if (
auto *tempExpr = dyn_cast<CXXBindTemporaryExpr>(E)) {
47 E = tempExpr->getSubExpr();
50 if (
auto *tempExpr = dyn_cast<CXXConstructExpr>(E)) {
51 if (
auto *
C = tempExpr->getConstructor()) {
53 return callback(E,
true);
57 if (
auto *TempExpr = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
58 if (isSafePtrType(TempExpr->getTypeAsWritten()))
59 return callback(TempExpr,
true);
61 if (
auto *POE = dyn_cast<PseudoObjectExpr>(E)) {
62 if (
auto *RF = POE->getResultExpr()) {
67 if (
auto *tempExpr = dyn_cast<ParenExpr>(E)) {
68 E = tempExpr->getSubExpr();
71 if (
auto *OpaqueValue = dyn_cast<OpaqueValueExpr>(E)) {
72 E = OpaqueValue->getSourceExpr();
75 if (
auto *
Expr = dyn_cast<ConditionalOperator>(E)) {
77 isSafePtr, isSafePtrType, isSafeGlobalDecl,
80 isSafePtr, isSafePtrType, isSafeGlobalDecl,
83 if (
auto *
cast = dyn_cast<CastExpr>(E)) {
84 if (StopAtFirstRefCountedObj) {
85 if (
auto *ConversionFunc =
86 dyn_cast_or_null<FunctionDecl>(
cast->getConversionFunction())) {
88 return callback(E,
true);
91 return callback(E,
true);
95 E =
cast->getSubExpr();
98 if (
auto *call = dyn_cast<CallExpr>(E)) {
99 if (
auto *Callee = call->getCalleeDecl()) {
100 if (Callee->hasAttr<CFReturnsRetainedAttr>() ||
101 Callee->hasAttr<NSReturnsRetainedAttr>() ||
102 Callee->hasAttr<NSReturnsAutoreleasedAttr>()) {
103 return callback(E,
true);
107 if (
auto *memberCall = dyn_cast<CXXMemberCallExpr>(call)) {
108 if (
auto *
decl = memberCall->getMethodDecl()) {
110 if (IsGetterOfRefCt && *IsGetterOfRefCt) {
112 if (
auto *DRE = dyn_cast<DeclRefExpr>(E)) {
113 if (
auto *
Decl = dyn_cast_or_null<VarDecl>(DRE->getDecl())) {
114 if (
Decl->isLocalVarDeclOrParm()) {
115 if (StopAtFirstRefCountedObj)
116 return callback(E,
true);
125 if (
auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(E)) {
126 if (
auto *Callee = operatorCall->getDirectCallee()) {
130 ClsName ==
"UniqueRef" || ClsName ==
"WeakPtr" ||
131 ClsName ==
"WeakRef") {
132 if (operatorCall->getNumArgs() == 1) {
133 E = operatorCall->getArg(0);
140 if (
auto *callee = call->getDirectCallee()) {
142 if (StopAtFirstRefCountedObj)
143 return callback(E,
true);
154 if (isSafePtrType(callee->getReturnType()))
155 return callback(E,
true);
158 return callback(E,
true);
160 if (callee->isInStdNamespace() &&
safeGetName(callee) ==
"forward") {
171 if (Name ==
"__builtin___CFStringMakeConstantString" ||
172 Name ==
"NSStringFromSelector" || Name ==
"NSSelectorFromString" ||
173 Name ==
"NSStringFromClass" || Name ==
"NSClassFromString" ||
174 Name ==
"NSStringFromProtocol" || Name ==
"NSProtocolFromString")
175 return callback(E,
true);
176 }
else if (
auto *CalleeE = call->getCallee()) {
177 if (
auto *E = dyn_cast<DeclRefExpr>(CalleeE->IgnoreParenCasts())) {
179 return callback(E,
true);
182 if (
auto *
MemberExpr = dyn_cast<CXXDependentScopeMemberExpr>(CalleeE)) {
184 auto MemberName =
MemberExpr->getMember().getAsString();
185 bool IsGetter = MemberName ==
"get" || MemberName ==
"ptr";
186 if (
Base && isSafePtrType(
Base->getType()) && IsGetter)
187 return callback(E,
true);
194 if (
auto *CalleeDecl = call->getCalleeDecl()) {
195 if (
auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) {
196 auto RetType = FD->getReturnType();
197 if (
auto *Subst = dyn_cast<SubstTemplateTypeParmType>(RetType)) {
198 if (
auto *SubstType = Subst->desugar().getTypePtr()) {
199 if (
auto *RD = dyn_cast<RecordType>(SubstType)) {
200 if (
auto *
CXX = dyn_cast<CXXRecordDecl>(RD->getDecl()))
202 return callback(E,
true);
209 if (
auto *ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(E)) {
210 if (
auto *
Method = ObjCMsgExpr->getMethodDecl()) {
211 if (isSafePtrType(
Method->getReturnType()))
212 return callback(E,
true);
214 if (ObjCMsgExpr->isClassMessage())
215 return callback(E,
true);
216 auto Selector = ObjCMsgExpr->getSelector();
218 if ((NameForFirstSlot ==
"class" || NameForFirstSlot ==
"superclass") &&
220 return callback(E,
true);
222 if (
auto *ObjCProtocol = dyn_cast<ObjCProtocolExpr>(E))
223 return callback(ObjCProtocol,
true);
224 if (
auto *ObjCDict = dyn_cast<ObjCDictionaryLiteral>(E))
225 return callback(ObjCDict,
true);
226 if (
auto *ObjCArray = dyn_cast<ObjCArrayLiteral>(E))
227 return callback(ObjCArray,
true);
228 if (
auto *ObjCStr = dyn_cast<ObjCStringLiteral>(E))
229 return callback(ObjCStr,
true);
230 if (
auto *unaryOp = dyn_cast<UnaryOperator>(E)) {
232 E = unaryOp->getSubExpr();
235 if (
auto *BoxedExpr = dyn_cast<ObjCBoxedExpr>(E)) {
236 if (StopAtFirstRefCountedObj)
237 return callback(BoxedExpr,
true);
238 E = BoxedExpr->getSubExpr();
244 return callback(E,
false);
342 auto *ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(E);
343 if (
auto *POE = dyn_cast<PseudoObjectExpr>(E)) {
344 if (
unsigned ExprCount = POE->getNumSemanticExprs()) {
346 ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(
Expr);
348 *InnerExpr = ObjCMsgExpr;
353 auto Selector = ObjCMsgExpr->getSelector();
355 if (NameForFirstSlot.starts_with(
"alloc") ||
356 NameForFirstSlot.starts_with(
"copy") ||
357 NameForFirstSlot.starts_with(
"mutableCopy")) {
358 if (
auto *MD = ObjCMsgExpr->getMethodDecl()) {
359 if (MD->getReturnType()->isVoidType())
364 if (!NameForFirstSlot.starts_with(
"init") &&
365 !NameForFirstSlot.starts_with(
"_init"))
367 if (!ObjCMsgExpr->isInstanceMessage())
369 auto *Receiver = ObjCMsgExpr->getInstanceReceiver();
372 Receiver = Receiver->IgnoreParenCasts();
373 if (
auto *Inner = dyn_cast<ObjCMessageExpr>(Receiver)) {
376 auto InnerSelector = Inner->getSelector();
377 return InnerSelector.getNameForSlot(0).starts_with(
"alloc");
378 }
else if (
auto *CE = dyn_cast<CallExpr>(Receiver)) {
381 if (
auto *Callee = CE->getDirectCallee()) {
382 if (Callee->getDeclName().isIdentifier()) {
383 auto CalleeName = Callee->getName();
384 return CalleeName.starts_with(
"alloc");