From 8222d5fa1faa34a7d61b9d181f2b85655ff214fa Mon Sep 17 00:00:00 2001 From: Sungkeun Cho Date: Mon, 21 Sep 2020 07:55:50 -0700 Subject: [PATCH] [cost] Ignore tagged pointers in autoreleasepool size Summary: This diff ignores tagged pointers in the autoreleasepool size, since they are not added to the autorelease pool. https://opensource.apple.com/source/objc4/objc4-781/runtime/objc-internal.h.auto.html Reviewed By: ezgicicek Differential Revision: D23626339 fbshipit-source-id: ba9ef4106 --- infer/src/IR/QualifiedCppName.ml | 6 +++++ infer/src/IR/QualifiedCppName.mli | 2 ++ infer/src/IR/Typ.ml | 26 ++++++++++++++++++- infer/src/IR/Typ.mli | 2 +- infer/src/cost/cost.ml | 2 +- .../objc/autoreleasepool/arc_callee.h | 10 +++++++ .../objc/autoreleasepool/arc_callee.m | 20 ++++++++++++++ .../objc/autoreleasepool/cost-issues.exp | 10 +++++++ .../objc/autoreleasepool/no_arc_caller.m | 20 ++++++++++++++ 9 files changed, 95 insertions(+), 3 deletions(-) diff --git a/infer/src/IR/QualifiedCppName.ml b/infer/src/IR/QualifiedCppName.ml index 95967b781..ebbb2a989 100644 --- a/infer/src/IR/QualifiedCppName.ml +++ b/infer/src/IR/QualifiedCppName.ml @@ -110,3 +110,9 @@ module Match = struct let normalized_qualifiers = strip_template_args quals in Str.string_match matcher (to_separated_string ~sep:matching_separator normalized_qualifiers) 0 end + +module Set = PrettyPrintable.MakePPSet (struct + type nonrec t = t [@@deriving compare] + + let pp = pp +end) diff --git a/infer/src/IR/QualifiedCppName.mli b/infer/src/IR/QualifiedCppName.mli index f213b1d5f..138b93358 100644 --- a/infer/src/IR/QualifiedCppName.mli +++ b/infer/src/IR/QualifiedCppName.mli @@ -88,3 +88,5 @@ module Match : sig val match_qualifiers : quals_matcher -> t -> bool end + +module Set : PrettyPrintable.PPSet with type elt = t diff --git a/infer/src/IR/Typ.ml b/infer/src/IR/Typ.ml index 034c19308..479136178 100644 --- a/infer/src/IR/Typ.ml +++ b/infer/src/IR/Typ.ml @@ -506,6 +506,26 @@ module Name = struct let protocol_from_qual_name qual_name = ObjcProtocol qual_name let is_class = function ObjcClass _ -> true | _ -> false + + let is_non_tagged_class = + (* The list of tagged classes are from: + https://opensource.apple.com/source/objc4/objc4-781/runtime/objc-internal.h *) + let tagged_classes = + [ "CGColor" + ; "NSAtom" + ; "NSColor" + ; "NSDate" + ; "NSIndexPath" + ; "NSIndexSet" + ; "NSManagedObjectID" + ; "NSNumber" + ; "NSString" + ; "Photos" + ; "UIColor" ] + |> List.map ~f:QualifiedCppName.of_qual_string + |> QualifiedCppName.Set.of_list + in + function ObjcClass name -> not (QualifiedCppName.Set.mem name tagged_classes) | _ -> false end module Set = PrettyPrintable.MakePPSet (struct @@ -559,6 +579,8 @@ let is_class_of_kind check_fun typ = let is_objc_class = is_class_of_kind Name.Objc.is_class +let is_objc_non_tagged_class = is_class_of_kind Name.Objc.is_non_tagged_class + let is_cpp_class = is_class_of_kind Name.Cpp.is_class let is_pointer typ = match typ.desc with Tptr _ -> true | _ -> false @@ -569,7 +591,9 @@ let is_struct typ = match typ.desc with Tstruct _ -> true | _ -> false let is_pointer_to_cpp_class typ = match typ.desc with Tptr (t, _) -> is_cpp_class t | _ -> false -let is_pointer_to_objc_class typ = match typ.desc with Tptr (t, _) -> is_objc_class t | _ -> false +let is_pointer_to_objc_non_tagged_class typ = + match typ.desc with Tptr (t, _) -> is_objc_non_tagged_class t | _ -> false + let is_pointer_to_void typ = match typ.desc with Tptr ({desc= Tvoid}, _) -> true | _ -> false diff --git a/infer/src/IR/Typ.mli b/infer/src/IR/Typ.mli index 5c527d22f..4a26db00c 100644 --- a/infer/src/IR/Typ.mli +++ b/infer/src/IR/Typ.mli @@ -324,7 +324,7 @@ val is_cpp_class : t -> bool val is_pointer_to_cpp_class : t -> bool -val is_pointer_to_objc_class : t -> bool +val is_pointer_to_objc_non_tagged_class : t -> bool val is_pointer_to_void : t -> bool diff --git a/infer/src/cost/cost.ml b/infer/src/cost/cost.ml index 3199e90d4..e3ee8366e 100644 --- a/infer/src/cost/cost.ml +++ b/infer/src/cost/cost.ml @@ -133,7 +133,7 @@ module InstrBasicCostWithReason = struct | _, _ -> if is_objc_call_from_no_arc_to_arc extras cfg callee_pname - && Typ.is_pointer_to_objc_class ret_typ + && Typ.is_pointer_to_objc_non_tagged_class ret_typ && not (return_object_owned_by_caller callee_pname) then let autoreleasepool_trace = diff --git a/infer/tests/codetoanalyze/objc/autoreleasepool/arc_callee.h b/infer/tests/codetoanalyze/objc/autoreleasepool/arc_callee.h index c12542868..342d9c876 100644 --- a/infer/tests/codetoanalyze/objc/autoreleasepool/arc_callee.h +++ b/infer/tests/codetoanalyze/objc/autoreleasepool/arc_callee.h @@ -20,4 +20,14 @@ + (int)giveMeInt; ++ (NSString*)giveTaggedPointerString; + ++ (NSNumber*)giveTaggedPointerNumber; + ++ (NSIndexPath*)giveTaggedPointerIndexPath; + ++ (NSIndexSet*)giveTaggedPointerIndexSet; + ++ (NSDate*)giveTaggedPointerDate; + @end diff --git a/infer/tests/codetoanalyze/objc/autoreleasepool/arc_callee.m b/infer/tests/codetoanalyze/objc/autoreleasepool/arc_callee.m index 35de0efa1..a555286f4 100644 --- a/infer/tests/codetoanalyze/objc/autoreleasepool/arc_callee.m +++ b/infer/tests/codetoanalyze/objc/autoreleasepool/arc_callee.m @@ -36,4 +36,24 @@ return 100; } ++ (NSString*)giveTaggedPointerString { + return [NSString new]; +} + ++ (NSNumber*)giveTaggedPointerNumber { + return [NSNumber new]; +} + ++ (NSIndexPath*)giveTaggedPointerIndexPath { + return [NSIndexPath new]; +} + ++ (NSIndexSet*)giveTaggedPointerIndexSet { + return [NSIndexSet new]; +} + ++ (NSDate*)giveTaggedPointerDate { + return [NSDate new]; +} + @end diff --git a/infer/tests/codetoanalyze/objc/autoreleasepool/cost-issues.exp b/infer/tests/codetoanalyze/objc/autoreleasepool/cost-issues.exp index ed4a071fe..858d8dca2 100644 --- a/infer/tests/codetoanalyze/objc/autoreleasepool/cost-issues.exp +++ b/infer/tests/codetoanalyze/objc/autoreleasepool/cost-issues.exp @@ -7,6 +7,11 @@ codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.copyObject:, 0, OnUI codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.dealloc, 0, OnUIThread:false, [] codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.giveMeInt, 0, OnUIThread:false, [] codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.giveMeObject, 0, OnUIThread:false, [] +codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.giveTaggedPointerDate, 0, OnUIThread:false, [] +codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.giveTaggedPointerIndexPath, 0, OnUIThread:false, [] +codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.giveTaggedPointerIndexSet, 0, OnUIThread:false, [] +codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.giveTaggedPointerNumber, 0, OnUIThread:false, [] +codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.giveTaggedPointerString, 0, OnUIThread:false, [] codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.mutableCopyObject:, 0, OnUIThread:false, [] codetoanalyze/objc/autoreleasepool/arc_callee.m, ArcCallee.newObject, 0, OnUIThread:false, [] codetoanalyze/objc/autoreleasepool/arc_caller.m, ArcCaller.callAllocObject_zero:, 0, OnUIThread:false, [] @@ -45,6 +50,11 @@ codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callCopyObject_z codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callGiveMeInt_zero, 0, OnUIThread:false, [] codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callGiveMeObject_autoreleasepool_zero:, 0, OnUIThread:false, [] codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callGiveMeObject_linear:, n, OnUIThread:false, [{n},Loop,autorelease,ARC function call to ArcCallee.giveMeObject from non-ARC caller] +codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callGiveTaggedPointerDate_zero, 0, OnUIThread:false, [] +codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callGiveTaggedPointerIndexPath_zero, 0, OnUIThread:false, [] +codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callGiveTaggedPointerIndexSet_zero, 0, OnUIThread:false, [] +codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callGiveTaggedPointerNumber_zero, 0, OnUIThread:false, [] +codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callGiveTaggedPointerString_zero, 0, OnUIThread:false, [] codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callMutableCopyObject_zero:x:, 0, OnUIThread:false, [] codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.callNewObject_zero:, 0, OnUIThread:false, [] codetoanalyze/objc/autoreleasepool/no_arc_caller.m, NoArcCaller.dealloc, 0, OnUIThread:false, [] diff --git a/infer/tests/codetoanalyze/objc/autoreleasepool/no_arc_caller.m b/infer/tests/codetoanalyze/objc/autoreleasepool/no_arc_caller.m index dbf2fabb1..f94de5adc 100644 --- a/infer/tests/codetoanalyze/objc/autoreleasepool/no_arc_caller.m +++ b/infer/tests/codetoanalyze/objc/autoreleasepool/no_arc_caller.m @@ -54,4 +54,24 @@ int i = [ArcCallee giveMeInt]; } +- (void)callGiveTaggedPointerString_zero { + NSString* x = [ArcCallee giveTaggedPointerString]; +} + +- (void)callGiveTaggedPointerNumber_zero { + NSNumber* x = [ArcCallee giveTaggedPointerNumber]; +} + +- (void)callGiveTaggedPointerIndexPath_zero { + NSIndexPath* x = [ArcCallee giveTaggedPointerIndexPath]; +} + +- (void)callGiveTaggedPointerIndexSet_zero { + NSIndexSet* x = [ArcCallee giveTaggedPointerIndexSet]; +} + +- (void)callGiveTaggedPointerDate_zero { + NSDate* x = [ArcCallee giveTaggedPointerDate]; +} + @end