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) {
111 E = memberCall->getImplicitObjectArgument();
112 if (StopAtFirstRefCountedObj) {
113 return callback(E,
true);
120 if (
auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(E)) {
121 if (
auto *Callee = operatorCall->getDirectCallee()) {
125 ClsName ==
"UniqueRef" || ClsName ==
"WeakPtr" ||
126 ClsName ==
"WeakRef") {
127 if (operatorCall->getNumArgs() == 1) {
128 E = operatorCall->getArg(0);
135 if (call->isCallToStdMove() && call->getNumArgs() == 1) {
140 if (
auto *callee = call->getDirectCallee()) {
142 if (StopAtFirstRefCountedObj)
143 return callback(E,
true);
149 if (isSafePtrType(callee->getReturnType()))
150 return callback(E,
true);
153 return callback(E,
true);
155 if (callee->isInStdNamespace() &&
safeGetName(callee) ==
"forward") {
166 if (Name ==
"__builtin___CFStringMakeConstantString" ||
167 Name ==
"NSStringFromSelector" || Name ==
"NSSelectorFromString" ||
168 Name ==
"NSStringFromClass" || Name ==
"NSClassFromString" ||
169 Name ==
"NSStringFromProtocol" || Name ==
"NSProtocolFromString")
170 return callback(E,
true);
171 }
else if (
auto *CalleeE = call->getCallee()) {
172 if (
auto *E = dyn_cast<DeclRefExpr>(CalleeE->IgnoreParenCasts())) {
174 return callback(E,
true);
177 if (
auto *
MemberExpr = dyn_cast<CXXDependentScopeMemberExpr>(CalleeE)) {
179 auto MemberName =
MemberExpr->getMember().getAsString();
180 bool IsGetter = MemberName ==
"get" || MemberName ==
"ptr";
181 if (
Base && isSafePtrType(
Base->getType()) && IsGetter)
182 return callback(E,
true);
189 if (
auto *CalleeDecl = call->getCalleeDecl()) {
190 if (
auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) {
191 auto RetType = FD->getReturnType();
192 if (
auto *Subst = dyn_cast<SubstTemplateTypeParmType>(RetType)) {
193 if (
auto *SubstType = Subst->desugar().getTypePtr()) {
194 if (
auto *RD = dyn_cast<RecordType>(SubstType)) {
195 if (
auto *
CXX = dyn_cast<CXXRecordDecl>(RD->getDecl()))
197 return callback(E,
true);
204 if (
auto *ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(E)) {
205 if (
auto *
Method = ObjCMsgExpr->getMethodDecl()) {
206 if (isSafePtrType(
Method->getReturnType()))
207 return callback(E,
true);
209 auto Selector = ObjCMsgExpr->getSelector();
211 if ((NameForFirstSlot ==
"class" || NameForFirstSlot ==
"superclass") &&
213 return callback(E,
true);
215 if (
auto *ObjCProtocol = dyn_cast<ObjCProtocolExpr>(E))
216 return callback(ObjCProtocol,
true);
217 if (
auto *ObjCDict = dyn_cast<ObjCDictionaryLiteral>(E))
218 return callback(ObjCDict,
true);
219 if (
auto *ObjCArray = dyn_cast<ObjCArrayLiteral>(E))
220 return callback(ObjCArray,
true);
221 if (
auto *ObjCStr = dyn_cast<ObjCStringLiteral>(E))
222 return callback(ObjCStr,
true);
223 if (
auto *unaryOp = dyn_cast<UnaryOperator>(E)) {
225 E = unaryOp->getSubExpr();
228 if (
auto *BoxedExpr = dyn_cast<ObjCBoxedExpr>(E)) {
229 if (StopAtFirstRefCountedObj)
230 return callback(BoxedExpr,
true);
231 E = BoxedExpr->getSubExpr();
237 return callback(E,
false);