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 (isSafePtrType(call->getType()))
108 return callback(E,
true);
110 if (
auto *memberCall = dyn_cast<CXXMemberCallExpr>(call)) {
111 if (
auto *
decl = memberCall->getMethodDecl()) {
113 if (IsGetterOfRefCt && *IsGetterOfRefCt) {
115 if (
auto *DRE = dyn_cast<DeclRefExpr>(E)) {
116 if (
auto *
Decl = dyn_cast_or_null<VarDecl>(DRE->getDecl())) {
117 if (
Decl->isLocalVarDeclOrParm()) {
118 if (StopAtFirstRefCountedObj)
119 return callback(E,
true);
128 if (
auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(E)) {
129 if (
auto *Callee = operatorCall->getDirectCallee()) {
133 ClsName ==
"UniqueRef" || ClsName ==
"WeakPtr" ||
134 ClsName ==
"WeakRef") {
135 if (operatorCall->getNumArgs() == 1) {
136 E = operatorCall->getArg(0);
143 if (
auto *callee = call->getDirectCallee()) {
145 if (StopAtFirstRefCountedObj)
146 return callback(E,
true);
157 if (isSafePtrType(callee->getReturnType()))
158 return callback(E,
true);
161 return callback(E,
true);
163 if (callee->isInStdNamespace() &&
safeGetName(callee) ==
"forward") {
174 if (Name ==
"__builtin___CFStringMakeConstantString" ||
175 Name ==
"NSStringFromSelector" || Name ==
"NSSelectorFromString" ||
176 Name ==
"NSStringFromClass" || Name ==
"NSClassFromString" ||
177 Name ==
"NSStringFromProtocol" || Name ==
"NSProtocolFromString")
178 return callback(E,
true);
179 }
else if (
auto *CalleeE = call->getCallee()) {
180 if (
auto *E = dyn_cast<DeclRefExpr>(CalleeE->IgnoreParenCasts())) {
182 return callback(E,
true);
185 if (
auto *
MemberExpr = dyn_cast<CXXDependentScopeMemberExpr>(CalleeE)) {
187 auto MemberName =
MemberExpr->getMember().getAsString();
188 bool IsGetter = MemberName ==
"get" || MemberName ==
"ptr";
189 if (
Base && isSafePtrType(
Base->getType()) && IsGetter)
190 return callback(E,
true);
197 if (
auto *CalleeDecl = call->getCalleeDecl()) {
198 if (
auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) {
199 auto RetType = FD->getReturnType();
200 if (
auto *Subst = dyn_cast<SubstTemplateTypeParmType>(RetType)) {
201 if (
auto *SubstType = Subst->desugar().getTypePtr()) {
202 if (
auto *RD = dyn_cast<RecordType>(SubstType)) {
203 if (
auto *
CXX = dyn_cast<CXXRecordDecl>(RD->getDecl()))
205 return callback(E,
true);
212 if (
auto *ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(E)) {
213 if (
auto *
Method = ObjCMsgExpr->getMethodDecl()) {
214 if (isSafePtrType(
Method->getReturnType()))
215 return callback(E,
true);
217 if (ObjCMsgExpr->isClassMessage())
218 return callback(E,
true);
219 auto Selector = ObjCMsgExpr->getSelector();
221 if ((NameForFirstSlot ==
"class" || NameForFirstSlot ==
"superclass") &&
223 return callback(E,
true);
225 if (
auto *ObjCProtocol = dyn_cast<ObjCProtocolExpr>(E))
226 return callback(ObjCProtocol,
true);
227 if (
auto *ObjCDict = dyn_cast<ObjCDictionaryLiteral>(E))
228 return callback(ObjCDict,
true);
229 if (
auto *ObjCArray = dyn_cast<ObjCArrayLiteral>(E))
230 return callback(ObjCArray,
true);
231 if (
auto *ObjCStr = dyn_cast<ObjCStringLiteral>(E))
232 return callback(ObjCStr,
true);
233 if (
auto *unaryOp = dyn_cast<UnaryOperator>(E)) {
235 E = unaryOp->getSubExpr();
238 if (
auto *BoxedExpr = dyn_cast<ObjCBoxedExpr>(E)) {
239 if (StopAtFirstRefCountedObj)
240 return callback(BoxedExpr,
true);
241 E = BoxedExpr->getSubExpr();
247 return callback(E,
false);
345 auto *ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(E);
346 if (
auto *POE = dyn_cast<PseudoObjectExpr>(E)) {
347 if (
unsigned ExprCount = POE->getNumSemanticExprs()) {
349 ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(
Expr);
351 *InnerExpr = ObjCMsgExpr;
356 auto Selector = ObjCMsgExpr->getSelector();
358 if (NameForFirstSlot.starts_with(
"alloc") ||
359 NameForFirstSlot.starts_with(
"copy") ||
360 NameForFirstSlot.starts_with(
"mutableCopy")) {
361 if (
auto *MD = ObjCMsgExpr->getMethodDecl()) {
362 if (MD->getReturnType()->isVoidType())
367 if (!NameForFirstSlot.starts_with(
"init") &&
368 !NameForFirstSlot.starts_with(
"_init"))
370 if (!ObjCMsgExpr->isInstanceMessage())
372 auto *Receiver = ObjCMsgExpr->getInstanceReceiver();
375 Receiver = Receiver->IgnoreParenCasts();
376 if (
auto *Inner = dyn_cast<ObjCMessageExpr>(Receiver)) {
379 auto InnerSelector = Inner->getSelector();
380 return InnerSelector.getNameForSlot(0).starts_with(
"alloc");
381 }
else if (
auto *CE = dyn_cast<CallExpr>(Receiver)) {
384 if (
auto *Callee = CE->getDirectCallee()) {
385 if (Callee->getDeclName().isIdentifier()) {
386 auto CalleeName = Callee->getName();
387 return CalleeName.starts_with(
"alloc");