diff --git a/infer/src/absint/PatternMatch.ml b/infer/src/absint/PatternMatch.ml index 4c4c93c24..266f86569 100644 --- a/infer/src/absint/PatternMatch.ml +++ b/infer/src/absint/PatternMatch.ml @@ -479,4 +479,8 @@ module ObjectiveC = struct String.is_prefix ~prefix:"CG" procname && ( String.is_substring ~substring:"Create" procname || String.is_substring ~substring:"Copy" procname ) + + + let is_core_graphics_release _ procname = + String.is_prefix ~prefix:"CG" procname && String.is_suffix ~suffix:"Release" procname end diff --git a/infer/src/absint/PatternMatch.mli b/infer/src/absint/PatternMatch.mli index faa4e8cf3..08018cc07 100644 --- a/infer/src/absint/PatternMatch.mli +++ b/infer/src/absint/PatternMatch.mli @@ -163,4 +163,6 @@ val is_override_of_java_lang_object_equals : Procname.t -> bool module ObjectiveC : sig val is_core_graphics_create_or_copy : Tenv.t -> string -> bool + + val is_core_graphics_release : Tenv.t -> string -> bool end diff --git a/infer/src/pulse/PulseModels.ml b/infer/src/pulse/PulseModels.ml index 49774de3b..2019fa076 100644 --- a/infer/src/pulse/PulseModels.ml +++ b/infer/src/pulse/PulseModels.ml @@ -525,7 +525,10 @@ module ProcNameDispatcher = struct &:: "nextElement" <>$ capt_arg_payload $!--> fun x -> StdVector.at ~desc:"Enumeration.nextElement" x (AbstractValue.mk_fresh (), []) ) - ; +PatternMatch.ObjectiveC.is_core_graphics_create_or_copy &++> ObjectiveC.alloc ] + ; +PatternMatch.ObjectiveC.is_core_graphics_create_or_copy &++> ObjectiveC.alloc + ; +PatternMatch.ObjectiveC.is_core_graphics_release <>$ capt_arg_payload $--> C.free + ; -"CFRelease" <>$ capt_arg_payload $--> C.free + ; -"CFAutoRelease" <>$ capt_arg_payload $--> C.free ] end let dispatch tenv proc_name args = ProcNameDispatcher.dispatch tenv proc_name args diff --git a/infer/tests/codetoanalyze/objc/pulse/MemoryLeaks.m b/infer/tests/codetoanalyze/objc/pulse/MemoryLeaks.m index cf41af741..45c893a43 100644 --- a/infer/tests/codetoanalyze/objc/pulse/MemoryLeaks.m +++ b/infer/tests/codetoanalyze/objc/pulse/MemoryLeaks.m @@ -16,7 +16,7 @@ @implementation MemoryLeaks -- (void)cg_path_create_with_rect_no_leak_good_FP { +- (void)cg_path_create_with_rect_no_leak_good { UIView* attachmentContainerView = [UIView alloc]; CGPathRef shadowPath = CGPathCreateWithRect(attachmentContainerView.bounds, NULL); @@ -34,16 +34,21 @@ CGPathCreateMutable(); } -+ (void)cg_path_create_mutable_no_leak_good_FP:(CGRect)rect { ++ (void)cg_path_create_mutable_no_leak_good:(CGRect)rect { CGFloat lineThickness = 0.20f * CGRectGetHeight(rect); // One rectangle CGMutablePathRef path1 = CGPathCreateMutable(); CFRelease(path1); } -+ (void)cg_bitmap_context_create_image_no_leak_good_FP { ++ (void)cg_bitmap_context_create_image_no_leak_good { CGImageRef newImage = CGBitmapContextCreateImage(nil); CGImageRelease(newImage); } ++ (void)cg_bitmap_context_create_image1_no_leak_good { + CGImageRef newImage = CGBitmapContextCreateImage(nil); + CFAutoRelease(newImage); +} + @end diff --git a/infer/tests/codetoanalyze/objc/pulse/issues.exp b/infer/tests/codetoanalyze/objc/pulse/issues.exp index 7b7cf2b98..314aa2bd3 100644 --- a/infer/tests/codetoanalyze/objc/pulse/issues.exp +++ b/infer/tests/codetoanalyze/objc/pulse/issues.exp @@ -1,7 +1,4 @@ -codetoanalyze/objc/pulse/MemoryLeaks.m, MemoryLeaks::cg_bitmap_context_create_image_no_leak_good_FP, 2, PULSE_MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocation occurs here,memory becomes unreachable here] codetoanalyze/objc/pulse/MemoryLeaks.m, MemoryLeaks::cg_path_create_mutable_leak_bad:, 2, PULSE_MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocation occurs here,memory becomes unreachable here] -codetoanalyze/objc/pulse/MemoryLeaks.m, MemoryLeaks::cg_path_create_mutable_no_leak_good_FP:, 4, PULSE_MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocation occurs here,memory becomes unreachable here] codetoanalyze/objc/pulse/MemoryLeaks.m, MemoryLeaks::cg_path_create_with_rect_leak_bad, 3, PULSE_MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocation occurs here,memory becomes unreachable here] -codetoanalyze/objc/pulse/MemoryLeaks.m, MemoryLeaks::cg_path_create_with_rect_no_leak_good_FP, 4, PULSE_MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocation occurs here,memory becomes unreachable here] codetoanalyze/objc/pulse/use_after_free.m, PulseTest::use_after_free_simple_in_objc_method_bad:, 2, USE_AFTER_FREE, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `x` of PulseTest::use_after_free_simple_in_objc_method_bad:,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `x` of PulseTest::use_after_free_simple_in_objc_method_bad:,invalid access occurs here] codetoanalyze/objc/pulse/use_after_free.m, use_after_free_simple_bad, 2, USE_AFTER_FREE, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `x` of use_after_free_simple_bad,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `x` of use_after_free_simple_bad,invalid access occurs here]