clang: lib/Analysis/RetainSummaryManager.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
22#include
23
24using namespace clang;
25using namespace ento;
26
27template
29 return false;
30}
31
32
33
34template <class T, class P, class... ToCompare>
36 return std::is_same_v<T, P> || isOneOf<T, ToCompare...>();
37}
38
39namespace {
40
41
42struct GeneralizedReturnsRetainedAttr {
43 static bool classof(const Attr *A) {
44 if (auto AA = dyn_cast(A))
45 return AA->getAnnotation() == "rc_ownership_returns_retained";
46 return false;
47 }
48};
49
50struct GeneralizedReturnsNotRetainedAttr {
51 static bool classof(const Attr *A) {
52 if (auto AA = dyn_cast(A))
53 return AA->getAnnotation() == "rc_ownership_returns_not_retained";
54 return false;
55 }
56};
57
58struct GeneralizedConsumedAttr {
59 static bool classof(const Attr *A) {
60 if (auto AA = dyn_cast(A))
61 return AA->getAnnotation() == "rc_ownership_consumed";
62 return false;
63 }
64};
65
66}
67
68template
69std::optional RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D,
72 if (isOneOf<T, CFConsumedAttr, CFReturnsRetainedAttr,
73 CFReturnsNotRetainedAttr>()) {
74 if (!TrackObjCAndCFObjects)
75 return std::nullopt;
76
78 } else if (isOneOf<T, NSConsumedAttr, NSConsumesSelfAttr,
79 NSReturnsAutoreleasedAttr, NSReturnsRetainedAttr,
80 NSReturnsNotRetainedAttr, NSConsumesSelfAttr>()) {
81
82 if (!TrackObjCAndCFObjects)
83 return std::nullopt;
84
85 if (isOneOf<T, NSReturnsRetainedAttr, NSReturnsAutoreleasedAttr,
86 NSReturnsNotRetainedAttr>() &&
88 return std::nullopt;
90 } else if (isOneOf<T, OSConsumedAttr, OSConsumesThisAttr,
91 OSReturnsNotRetainedAttr, OSReturnsRetainedAttr,
92 OSReturnsRetainedOnZeroAttr,
93 OSReturnsRetainedOnNonZeroAttr>()) {
94 if (!TrackOSObjects)
95 return std::nullopt;
97 } else if (isOneOf<T, GeneralizedReturnsNotRetainedAttr,
98 GeneralizedReturnsRetainedAttr,
99 GeneralizedConsumedAttr>()) {
101 } else {
102 llvm_unreachable("Unexpected attribute");
103 }
105 return K;
106 return std::nullopt;
107}
108
109template <class T1, class T2, class... Others>
110std::optional RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D,
112 if (auto Out = hasAnyEnabledAttrOf(D, QT))
113 return Out;
114 return hasAnyEnabledAttrOf<T2, Others...>(D, QT);
115}
116
118RetainSummaryManager::getPersistentSummary(const RetainSummary &OldSumm) {
119
121 ::llvm::FoldingSetNodeID ID;
123
124 void *Pos;
125 CachedSummaryNode *N = SimpleSummaries.FindNodeOrInsertPos(ID, Pos);
126
127 if (!N) {
128 N = (CachedSummaryNode *) BPAlloc.Allocate();
129 new (N) CachedSummaryNode(OldSumm);
130 SimpleSummaries.InsertNode(N, Pos);
131 }
132
133 return &N->getValue();
134 }
135
138 return Summ;
139}
140
142 StringRef ClassName) {
143 using namespace ast_matchers;
145 cxxRecordDecl(isSameOrDerivedFrom(std::string(ClassName)));
147}
148
150 using namespace ast_matchers;
154}
155
157 return D && isSubclass(D, "OSMetaClassBase") &&
159}
160
162
164 return S == "requiredMetaCast";
165}
166
168 return S == "metaCast";
169}
170
171
174}
175
177 return StringRef(Ty.getAsString()).starts_with("isl_");
178}
179
182}
183
185 for (const auto *Ann : D->specific_attrs()) {
186 if (Ann->getAnnotation() == rcAnnotation)
187 return true;
188 }
189 return false;
190}
191
193 return FName.starts_with_insensitive("retain") ||
194 FName.ends_with_insensitive("retain");
195}
196
198 return FName.starts_with_insensitive("release") ||
199 FName.ends_with_insensitive("release");
200}
201
203 return FName.starts_with_insensitive("autorelease") ||
204 FName.ends_with_insensitive("autorelease");
205}
206
208 return FName.contains_insensitive("MakeCollectable");
209}
210
211
212
215 return true;
216
222 return true;
223 }
224
225 return false;
226}
227
228bool
232 if (!RD)
233 return false;
235 if (II && II->getName() == "smart_ptr")
236 if (const auto *ND = dyn_cast(RD->getDeclContext()))
237 if (ND->getNameAsString() == "os")
238 return true;
239 return false;
240}
241
243RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD,
244 StringRef FName, QualType RetTy) {
245 assert(TrackOSObjects &&
246 "Requesting a summary for an OSObject but OSObjects are not tracked");
247
253 return getDefaultSummary();
254
255
256
257
258 if (FName.ends_with("Matching")) {
259 return getPersistentStopSummary();
260 }
261
262
263
264 if ((!FName.starts_with("get") && !FName.starts_with("Get")) ||
266 return getOSSummaryCreateRule(FD);
267 } else {
268 return getOSSummaryGetRule(FD);
269 }
270 }
271 }
272
273 if (const auto *MD = dyn_cast(FD)) {
276 if (FName == "release" || FName == "taggedRelease")
277 return getOSSummaryReleaseRule(FD);
278
279 if (FName == "retain" || FName == "taggedRetain")
280 return getOSSummaryRetainRule(FD);
281
282 if (FName == "free")
283 return getOSSummaryFreeRule(FD);
284
285 if (MD->getOverloadedOperator() == OO_New)
286 return getOSSummaryCreateRule(MD);
287 }
288 }
289
290 return nullptr;
291}
292
293const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
295 StringRef FName,
298 bool &AllowAnnotations) {
299
300 ArgEffects ScratchArgs(AF.getEmptyMap());
301
302 std::string RetTyName = RetTy.getAsString();
303 if (FName == "pthread_create" || FName == "pthread_setspecific") {
304
305
306
307 return getPersistentStopSummary();
308 } else if(FName == "NSMakeCollectable") {
309
310 AllowAnnotations = false;
312 : getPersistentStopSummary();
313 } else if (FName == "CMBufferQueueDequeueAndRetain" ||
314 FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
315
316
318 ScratchArgs,
321 } else if (FName == "CFPlugInInstanceCreate") {
323 } else if (FName == "IORegistryEntrySearchCFProperty" ||
324 (RetTyName == "CFMutableDictionaryRef" &&
325 (FName == "IOBSDNameMatching" || FName == "IOServiceMatching" ||
326 FName == "IOServiceNameMatching" ||
327 FName == "IORegistryEntryIDMatching" ||
328 FName == "IOOpenFirmwarePathMatching"))) {
329
330
333 } else if (FName == "IOServiceGetMatchingService" ||
334 FName == "IOServiceGetMatchingServices") {
335
336
339 ScratchArgs,
341 } else if (FName == "IOServiceAddNotification" ||
342 FName == "IOServiceAddMatchingNotification") {
343
344
347 ScratchArgs,
349 } else if (FName == "CVPixelBufferCreateWithBytes") {
350
351
352
353
354
355
358 ScratchArgs,
360 } else if (FName == "CGBitmapContextCreateWithData") {
361
362
363
364
368 } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {
369
372 ScratchArgs,
374 } else if (FName == "VTCompressionSessionEncodeFrame" ||
375 FName == "VTCompressionSessionEncodeMultiImageFrame") {
376
377
378
379
380
383 ScratchArgs,
385 } else if (FName == "dispatch_set_context" ||
386 FName == "xpc_connection_set_context") {
387
388
389
390
393 ScratchArgs,
395 } else if (FName.starts_with("NSLog")) {
396 return getDoNothingSummary();
397 } else if (FName.starts_with("NS") && FName.contains("Insert")) {
398
399
405 }
406
408
409
412
413
414
415
416 AllowAnnotations = false;
417
418 return getUnarySummary(FT, IncRef);
420
421
422 AllowAnnotations = false;
423
426 AllowAnnotations = false;
427 return getUnarySummary(FT, DoNothing);
428 } else {
429 return getCFCreateGetRuleSummary(FD);
430 }
431 }
432
433
437 return getUnarySummary(FT, IncRef);
438 else
439 return getCFCreateGetRuleSummary(FD);
440 }
441
442
443
444
446 return getCFCreateGetRuleSummary(FD);
447 }
448
449 if (FD->hasAttr()) {
450 return getCFCreateGetRuleSummary(FD);
451 }
452 }
453
454
455
456 if (FName.starts_with("CG") || FName.starts_with("CF")) {
457
458 FName = FName.substr(FName.starts_with("CGCF") ? 4 : 2);
459
461 return getUnarySummary(FT, DecRef);
462 else {
463 assert(ScratchArgs.isEmpty());
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
480 (StrInStrNoCase(FName, "InsertValue") != StringRef::npos ||
481 StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
482 StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
483 StrInStrNoCase(FName, "AppendValue") != StringRef::npos ||
484 StrInStrNoCase(FName, "SetAttribute") != StringRef::npos)
487
490 }
491 }
492
493 return nullptr;
494}
495
497RetainSummaryManager::generateSummary(const FunctionDecl *FD,
498 bool &AllowAnnotations) {
499
501 return getPersistentStopSummary();
502
504
505 StringRef FName = II ? II->getName() : "";
506
507
508
509 FName = FName.substr(FName.find_first_not_of('_'));
510
511
514
515 if (TrackOSObjects)
516 if (const RetainSummary *S = getSummaryForOSObject(FD, FName, RetTy))
517 return S;
518
519 if (const auto *MD = dyn_cast(FD))
526
527 if (TrackObjCAndCFObjects)
529 getSummaryForObjCOrCFObject(FD, FName, RetTy, FT, AllowAnnotations))
530 return S;
531
532 return getDefaultSummary();
533}
534
536RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {
537
538 if (!FD)
539 return getDefaultSummary();
540
541
542 FuncSummariesTy::iterator I = FuncSummaries.find(FD);
543 if (I != FuncSummaries.end())
544 return I->second;
545
546
547 bool AllowAnnotations = true;
548 const RetainSummary *S = generateSummary(FD, AllowAnnotations);
549
550
551 if (AllowAnnotations)
552 updateSummaryFromAnnotations(S, FD);
553
554 FuncSummaries[FD] = S;
555 return S;
556}
557
558
559
560
561
563 switch (E.getKind()) {
581 }
582
583 llvm_unreachable("Unknown ArgEffect kind");
584}
585
587RetainSummaryManager::updateSummaryForNonZeroCallbackArg(const RetainSummary *S,
591
592 ArgEffects ScratchArgs(AF.getEmptyMap());
593 ArgEffects CustomArgEffects = S->getArgEffects();
594 for (ArgEffects::iterator I = CustomArgEffects.begin(),
595 E = CustomArgEffects.end();
596 I != E; ++I) {
599 ScratchArgs = AF.add(ScratchArgs, I->first, Translated);
600 }
601
603
604
605
606
608
609
610
611
612 if (Name->isStr("CGBitmapContextCreateWithData") ||
613 Name->isStr("dispatch_data_create"))
614 RE = S->getRetEffect();
615 }
616
617 return getPersistentSummary(RE, ScratchArgs, RecEffect, DefEffect);
618}
619
620void RetainSummaryManager::updateSummaryForReceiverUnconsumedSelf(
622
624
627}
628
629
630void RetainSummaryManager::updateSummaryForArgumentTypes(
633
634 unsigned parm_idx = 0;
635 for (auto pi = C.param_begin(), pe = C.param_end(); pi != pe;
636 ++pi, ++parm_idx) {
637 QualType QT = (*pi)->getType();
638
639
641 continue;
642
644
653 }
654
656 Template->addArg(AF, parm_idx,
658 }
659}
660
663 bool HasNonZeroCallbackArg,
664 bool IsReceiverUnconsumedSelf,
667 switch (C.getKind()) {
673 Summ = getFunctionSummary(cast_or_null(C.getDecl()));
674 break;
677
678 return getPersistentStopSummary();
680 const auto *ME = cast_or_null(C.getExpr());
681 if (!ME) {
682 Summ = getMethodSummary(cast(C.getDecl()));
683 } else if (ME->isInstanceMessage()) {
684 Summ = getInstanceMethodSummary(ME, ReceiverType);
685 } else {
686 Summ = getClassMethodSummary(ME);
687 }
688 break;
689 }
690 }
691
692 if (HasNonZeroCallbackArg)
693 Summ = updateSummaryForNonZeroCallbackArg(Summ, C);
694
695 if (IsReceiverUnconsumedSelf)
696 updateSummaryForReceiverUnconsumedSelf(Summ);
697
698 updateSummaryForArgumentTypes(C, Summ);
699
700 assert(Summ && "Unknown call type?");
701 return Summ;
702}
703
704
706RetainSummaryManager::getCFCreateGetRuleSummary(const FunctionDecl *FD) {
708 return getCFSummaryCreateRule(FD);
709
710 return getCFSummaryGetRule(FD);
711}
712
714 const Decl *FD) {
715 return hasRCAnnotation(FD, "rc_ownership_trusted_implementation");
716}
717
718std::optionalRetainSummaryManager::BehaviorSummary
720 bool &hasTrustedImplementationAnnotation) {
721
723 if (!II)
724 return std::nullopt;
725
726 StringRef FName = II->getName();
727 FName = FName.substr(FName.find_first_not_of('_'));
728
731 if (II->isStr("NSMakeCollectable"))
734
735
736
737 if (FName == "CMBufferQueueDequeueAndRetain" ||
738 FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
739
740
741 return std::nullopt;
742 }
750
751
752
753
754
755
756 if (TrackOSObjects) {
762 !cast(FD)->isStatic()) {
764 }
765 }
766
769 hasTrustedImplementationAnnotation = true;
771 }
772 }
773
774 if (const auto *MD = dyn_cast(FD)) {
777 if (FName == "release" || FName == "retain")
779 }
780
781 return std::nullopt;
782}
783
785RetainSummaryManager::getUnarySummary(const FunctionType* FT,
787
788
789 ArgEffects ScratchArgs(AF.getEmptyMap());
790
791
792
795 return getPersistentStopSummary();
796
798
799 ScratchArgs = AF.add(ScratchArgs, 0, Effect);
801 ScratchArgs,
803}
804
806RetainSummaryManager::getOSSummaryRetainRule(const FunctionDecl *FD) {
808 AF.getEmptyMap(),
812}
813
815RetainSummaryManager::getOSSummaryReleaseRule(const FunctionDecl *FD) {
817 AF.getEmptyMap(),
821}
822
824RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) {
826 AF.getEmptyMap(),
830}
831
833RetainSummaryManager::getOSSummaryCreateRule(const FunctionDecl *FD) {
835 AF.getEmptyMap());
836}
837
839RetainSummaryManager::getOSSummaryGetRule(const FunctionDecl *FD) {
841 AF.getEmptyMap());
842}
843
845RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl *FD) {
848}
849
851RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
855}
856
857
858
859
860
861
862
863
864std::optional
865RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
867 if (hasAnyEnabledAttrOf(D, RetTy))
868 return ObjCAllocRetE;
869
870 if (auto K = hasAnyEnabledAttrOf<CFReturnsRetainedAttr, OSReturnsRetainedAttr,
871 GeneralizedReturnsRetainedAttr>(D, RetTy))
873
874 if (auto K = hasAnyEnabledAttrOf<
875 CFReturnsNotRetainedAttr, OSReturnsNotRetainedAttr,
876 GeneralizedReturnsNotRetainedAttr, NSReturnsNotRetainedAttr,
877 NSReturnsAutoreleasedAttr>(D, RetTy))
879
880 if (const auto *MD = dyn_cast(D))
881 for (const auto *PD : MD->overridden_methods())
882 if (auto RE = getRetEffectFromAnnotations(RetTy, PD))
883 return RE;
884
885 return std::nullopt;
886}
887
888
889
891 StringRef Name) {
893 const auto &Context = T->getDecl()->getASTContext();
894 if (T->getDecl()->getIdentifier() == &Context.Idents.get(Name))
895 return true;
896 QT = T->getDecl()->getUnderlyingType();
897 }
898 return false;
899}
900
902 if (const auto *FD = dyn_cast(ND)) {
904 } else if (const auto *MD = dyn_cast(ND)) {
905 return MD->getReturnType();
906 } else {
907 llvm_unreachable("Unexpected decl");
908 }
909}
910
911bool RetainSummaryManager::applyParamAnnotationEffect(
915 if (auto K =
916 hasAnyEnabledAttrOf<NSConsumedAttr, CFConsumedAttr, OSConsumedAttr,
917 GeneralizedConsumedAttr>(pd, QT)) {
919 return true;
920 } else if (auto K = hasAnyEnabledAttrOf<
921 CFReturnsRetainedAttr, OSReturnsRetainedAttr,
922 OSReturnsRetainedOnNonZeroAttr, OSReturnsRetainedOnZeroAttr,
923 GeneralizedReturnsRetainedAttr>(pd, QT)) {
924
925
926
929
930 bool HasRetainedOnZero = pd->hasAttr();
931 bool HasRetainedOnNonZero = pd->hasAttr();
932
933
934
935
936
937 bool SuccessOnZero =
938 HasRetainedOnZero ||
939 (hasTypedefNamed(QT, "kern_return_t") && !HasRetainedOnNonZero);
942 if (ShouldSplit && SuccessOnZero) {
944 } else if (ShouldSplit && (!SuccessOnZero || HasRetainedOnNonZero)) {
946 }
948 }
949
950
951
952
953
954 return true;
955 } else if (auto K = hasAnyEnabledAttrOf<CFReturnsNotRetainedAttr,
956 OSReturnsNotRetainedAttr,
957 GeneralizedReturnsNotRetainedAttr>(
958 pd, QT)) {
960 return true;
961 }
962
963 if (const auto *MD = dyn_cast(FD)) {
964 for (const auto *OD : MD->overridden_methods()) {
965 const ParmVarDecl *OP = OD->parameters()[parm_idx];
966 if (applyParamAnnotationEffect(OP, parm_idx, OD, Template))
967 return true;
968 }
969 }
970
971 return false;
972}
973
974void
975RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
977 if (!FD)
978 return;
979
980 assert(Summ && "Must have a summary to add annotations to.");
982
983
984 unsigned parm_idx = 0;
986 pe = FD->param_end(); pi != pe; ++pi, ++parm_idx)
987 applyParamAnnotationEffect(*pi, parm_idx, FD, Template);
988
990 if (std::optional RetE = getRetEffectFromAnnotations(RetTy, FD))
992
993 if (hasAnyEnabledAttrOf(FD, RetTy))
995}
996
997void
998RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
1000 if (!MD)
1001 return;
1002
1003 assert(Summ && "Must have a valid summary to add annotations to");
1005
1006
1007 if (hasAnyEnabledAttrOf(MD, MD->getReturnType()))
1009
1010
1011 unsigned parm_idx = 0;
1013 ++pi, ++parm_idx)
1014 applyParamAnnotationEffect(*pi, parm_idx, MD, Template);
1015
1017 if (std::optional RetE = getRetEffectFromAnnotations(RetTy, MD))
1019}
1020
1022RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
1024
1027
1028
1029 switch (MD ? MD->getMethodFamily() : S.getMethodFamily()) {
1033
1034
1035
1039
1040
1041
1042
1043 if (MD) {
1044 switch (S.getMethodFamily()) {
1050 break;
1051 default:
1053 break;
1054 }
1055 } else {
1057 }
1058 }
1059 break;
1061 ResultEff = ObjCInitRetE;
1063 break;
1069 ResultEff = ObjCAllocRetE;
1072 break;
1075 break;
1078 break;
1081 break;
1084 break;
1086
1087 break;
1090
1091 break;
1092 }
1093
1094
1095
1096
1097
1098 if (S.isKeywordSelector()) {
1099 for (unsigned i = 0, e = S.getNumArgs(); i != e; ++i) {
1100 StringRef Slot = S.getNameForSlot(i);
1101 if (Slot.ends_with_insensitive("delegate")) {
1102 if (ResultEff == ObjCInitRetE)
1104 else
1106 }
1107 }
1108 }
1109
1112 return getDefaultSummary();
1113
1114 return getPersistentSummary(ResultEff, ArgEffects(AF.getEmptyMap()),
1116}
1117
1119RetainSummaryManager::getClassMethodSummary(const ObjCMessageExpr *ME) {
1122
1124 ME->getType(), ObjCClassMethodSummaries);
1125}
1126
1127const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(
1131
1132
1133
1134 if (!ReceiverType.isNull())
1136 ReceiverClass = PT->getInterfaceDecl();
1137
1138
1139 if (!ReceiverClass)
1141
1142
1143
1144
1145
1148 if (!Method && ReceiverClass)
1150
1151 return getMethodSummary(S, ReceiverClass, Method, ME->getType(),
1152 ObjCMethodSummaries);
1153}
1154
1156RetainSummaryManager::getMethodSummary(Selector S,
1159 ObjCMethodSummariesTy &CachedSummaries) {
1160
1161
1162 if (!TrackObjCAndCFObjects)
1163 return getDefaultSummary();
1164
1165
1166 const RetainSummary *Summ = CachedSummaries.find(ID, S);
1167
1168 if (!Summ) {
1169 Summ = getStandardMethodSummary(MD, S, RetTy);
1170
1171
1172 updateSummaryFromAnnotations(Summ, MD);
1173
1174
1176 }
1177
1178 return Summ;
1179}
1180
1181void RetainSummaryManager::InitializeClassMethodSummaries() {
1182 ArgEffects ScratchArgs = AF.getEmptyMap();
1183
1184
1185 addClassMethSummary("NSAssertionHandler", "currentHandler",
1187 ScratchArgs));
1188
1189
1191 addClassMethSummary("NSAutoreleasePool", "addObject",
1195}
1196
1197void RetainSummaryManager::InitializeMethodSummaries() {
1198
1199 ArgEffects ScratchArgs = AF.getEmptyMap();
1200
1201
1202 const RetainSummary *InitSumm = getPersistentSummary(
1205
1206
1207
1208 addNSObjectMethSummary(GetUnarySelector("awakeAfterUsingCoder", Ctx),
1209 InitSumm);
1210
1211
1212 const RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE,
1213 ScratchArgs);
1216
1217
1219 const RetainSummary *Summ = getPersistentSummary(
1222
1223
1224 Summ = getPersistentSummary(NoRet, ScratchArgs,
1227
1228
1229 Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Dealloc,
1232
1233
1236 addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
1237
1238
1239
1240
1241
1245
1246 addClassMethSummary("NSWindow", "alloc", NoTrackYet);
1247
1248
1249
1250
1251
1252 addClassMethSummary("NSPanel", "alloc", NoTrackYet);
1253
1254
1255
1256 addClassMethSummary("NSNull", "null", NoTrackYet);
1257
1258
1259
1260 addClassMethSummary("NSAutoreleasePool", "alloc", NoTrackYet);
1261 addClassMethSummary("NSAutoreleasePool", "allocWithZone", NoTrackYet, false);
1262 addClassMethSummary("NSAutoreleasePool", "new", NoTrackYet);
1263
1264
1265 addInstMethSummary("QCRenderer", AllocSumm, "createSnapshotImageOfType");
1266 addInstMethSummary("QCView", AllocSumm, "createSnapshotImageOfType");
1267
1268
1269
1270
1271 addInstMethSummary("CIContext", CFAllocSumm, "createCGImage", "fromRect");
1272 addInstMethSummary("CIContext", CFAllocSumm, "createCGImage", "fromRect",
1273 "format", "colorSpace");
1274 addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", "info");
1275}
1276
1278RetainSummaryManager::getMethodSummary(const ObjCMethodDecl *MD) {
1282
1283 ObjCMethodSummariesTy *CachedSummaries;
1285 CachedSummaries = &ObjCMethodSummaries;
1286 else
1287 CachedSummaries = &ObjCClassMethodSummaries;
1288
1289 return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);
1290}
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static bool isSubclass(const ObjCInterfaceDecl *Class, const IdentifierInfo *II)
static bool isOSObjectRelated(const CXXMethodDecl *MD)
A function is OSObject related if it is declared on a subclass of OSObject, or any of the parameters ...
static bool isISLObjectRef(QualType Ty)
static bool isRelease(const FunctionDecl *FD, StringRef FName)
static bool hasTypedefNamed(QualType QT, StringRef Name)
static bool isOSObjectRequiredCast(StringRef S)
static ArgEffect getStopTrackingHardEquivalent(ArgEffect E)
static constexpr bool isOneOf()
static bool isOSIteratorSubclass(const Decl *D)
static QualType getCallableReturnType(const NamedDecl *ND)
static bool isAutorelease(const FunctionDecl *FD, StringRef FName)
static bool isExactClass(const Decl *D, StringRef ClassName)
static bool isOSObjectPtr(QualType QT)
static bool hasRCAnnotation(const Decl *D, StringRef rcAnnotation)
static bool isOSObjectSubclass(const Decl *D)
static bool isOSObjectThisCast(StringRef S)
static bool isMakeCollectable(StringRef FName)
static bool isOSObjectDynamicCast(StringRef S)
static bool isRetain(const FunctionDecl *FD, StringRef FName)
An instance of this class corresponds to a call.
@ Destructor
An implicit C++ destructor call (called implicitly or by operator 'delete')
@ ObjCMethod
A call to an Objective-C method.
@ Deallocator
A C++ deallocation function call (operator delete), via C++ delete-expression.
@ Function
A function, function pointer, or a C++ method call.
@ Allocator
A C++ allocation function call (operator new), via C++ new-expression.
@ Constructor
An implicit or explicit C++ constructor call.
@ InheritedConstructor
A C++ inherited constructor produced by a "using T::T" directive.
@ Block
A call to an Objective-C block.
Attr - This represents one attribute.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a C++ struct/union/class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Represents a function declaration or definition.
param_iterator param_end()
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
FunctionDecl * getDefinition()
Get the definition for this declaration.
size_t param_size() const
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
Represents an ObjC class declaration.
An expression that sends a message to the given Objective-C object or class.
Selector getSelector() const
bool isInstanceMessage() const
Determine whether this is an instance message to either a computed object or to super.
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
const ObjCMethodDecl * getMethodDecl() const
ObjCMethodDecl - Represents an instance or class method declaration.
param_const_iterator param_end() const
param_const_iterator param_begin() const
Selector getSelector() const
bool isInstanceMethod() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
QualType getReturnType() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
Represents a parameter to a function.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Smart pointer class that efficiently represents Objective-C method names.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
const T * castAs() const
Member-template castAs.
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjCIdType() const
const T * getAs() const
Member-template getAs'.
An ArgEffect summarizes the retain count behavior on an argument or receiver to a function or method.
ArgEffectKind getKind() const
A key identifying a summary.
RetEffect summarizes a call's retain/release behavior with respect to its return value.
static RetEffect MakeNotOwned(ObjKind o)
static RetEffect MakeOwned(ObjKind o)
@ NoRet
Indicates that no retain count information is tracked for the return value.
static RetEffect MakeNoRet()
static RetEffect MakeNoRetHard()
bool isTrustedReferenceCountImplementation(const Decl *FD)
std::optional< BehaviorSummary > canEval(const CallExpr *CE, const FunctionDecl *FD, bool &hasTrustedImplementationAnnotation)
static bool isKnownSmartPointer(QualType QT)
const RetainSummary * getSummary(AnyCall C, bool HasNonZeroCallbackArg=false, bool IsReceiverUnconsumedSelf=false, QualType ReceiverType={})
Summary for a function with respect to ownership changes.
void setRetEffect(RetEffect E)
setRetEffect - Set the effect of the return value of the call.
void addArg(ArgEffects::Factory &af, unsigned idx, ArgEffect e)
bool isSimple() const
A retain summary is simple if it has no ArgEffects other than the default.
ArgEffects getArgEffects() const
void setThisEffect(ArgEffect e)
Set the effect of the method on "this".
void setReceiverEffect(ArgEffect e)
Sets the effect on the receiver of the message.
void Profile(llvm::FoldingSetNodeID &ID) const
Profile this summary for inclusion in a FoldingSet.
internal::Matcher< Decl > DeclarationMatcher
Types of matchers for the top-level classes in the AST class hierarchy.
internal::Matcher< NamedDecl > hasName(StringRef Name)
Matches NamedDecl nodes that have the specified name.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl > cxxRecordDecl
Matches C++ class declarations.
bool isCocoaObjectRef(QualType T)
bool isRefType(QualType RetTy, StringRef Prefix, StringRef Name=StringRef())
bool followsCreateRule(const FunctionDecl *FD)
bool isCFObjectRef(QualType T)
llvm::ImmutableMap< unsigned, ArgEffect > ArgEffects
ArgEffects summarizes the effects of a function/method call on all of its arguments.
ObjKind
Determines the object kind of a tracked object.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ Generalized
Indicates that the tracked object is a generalized object.
@ CF
Indicates that the tracked object is a CF object.
@ AnyObj
Indicates that the tracked object could be a CF or Objective-C object.
@ ObjC
Indicates that the tracked object is an Objective-C object.
@ IncRef
The argument has its reference count increased by 1.
@ UnretainedOutParameter
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +0 v...
@ DoNothing
There is no effect.
@ RetainedOutParameter
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
@ RetainedOutParameterOnZero
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
@ MayEscape
The argument is treated as potentially escaping, meaning that even when its reference count hits 0 it...
@ StopTracking
All typestate tracking of the object ceases.
@ Dealloc
The argument is treated as if the referenced object was deallocated.
@ Autorelease
The argument is treated as if an -autorelease message had been sent to the referenced object.
@ RetainedOutParameterOnNonZero
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
@ DecRef
The argument has its reference count decreased by 1.
@ StopTrackingHard
All typestate tracking of the object ceases.
@ DecRefAndStopTrackingHard
Performs the combined functionality of DecRef and StopTrackingHard.
@ DecRefBridgedTransferred
The argument has its reference count decreased by 1 to model a transferred bridge cast under ARC.
bool NoRet(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ OMF_None
No particular method family.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
const FunctionProtoType * T
@ Class
The "class" keyword introduces the elaborated-type-specifier.