diff --git a/infer/src/pulse/PulseAbductiveDomain.ml b/infer/src/pulse/PulseAbductiveDomain.ml index 644cc285a..fcef3e661 100644 --- a/infer/src/pulse/PulseAbductiveDomain.ml +++ b/infer/src/pulse/PulseAbductiveDomain.ml @@ -569,8 +569,11 @@ let mk_initial tenv proc_desc = in let locals = Procdesc.get_locals proc_desc in let post = - List.fold locals ~init:post ~f:(fun (acc : PostDomain.t) {ProcAttributes.name; typ} -> - set_uninitialized_post tenv (`LocalDecl (Pvar.mk name proc_name, None)) typ location acc ) + List.fold locals ~init:post + ~f:(fun (acc : PostDomain.t) {ProcAttributes.name; typ; modify_in_block; is_constexpr} -> + if modify_in_block || is_constexpr then acc + else + set_uninitialized_post tenv (`LocalDecl (Pvar.mk name proc_name, None)) typ location acc ) in { pre ; post diff --git a/infer/tests/codetoanalyze/objc/pulse/issues.exp b/infer/tests/codetoanalyze/objc/pulse/issues.exp index bcd1b9fd7..113b6b3e7 100644 --- a/infer/tests/codetoanalyze/objc/pulse/issues.exp +++ b/infer/tests/codetoanalyze/objc/pulse/issues.exp @@ -9,8 +9,5 @@ codetoanalyze/objc/pulse/MemoryLeaks.m, call_cfrelease_interproc_leak_ok_FP, 2, codetoanalyze/objc/pulse/MemoryLeaksInBlocks.m, block_captured_var_leak_bad, 6, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `malloc_no_fail` (modelled),allocation part of the trace ends here,memory becomes unreachable here] codetoanalyze/objc/pulse/NPEBlocks.m, Singleton.dispatch_once_no_npe_good_FP, 6, NULLPTR_DEREFERENCE, no_bucket, ERROR, [source of the null value part of the trace starts here,assigned,is the null pointer,null pointer dereference part of the trace starts here,assigned,invalid access occurs here] codetoanalyze/objc/pulse/NPEBlocks.m, captured_npe_bad, 5, NULLPTR_DEREFERENCE, no_bucket, ERROR, [source of the null value part of the trace starts here,assigned,is the null pointer,null pointer dereference part of the trace starts here,assigned,when calling `objc_blockcaptured_npe_bad_3` here,parameter `x` of objc_blockcaptured_npe_bad_3,invalid access occurs here] -codetoanalyze/objc/pulse/uninit.m, Uninit.capture_in_closure_bad, 7, PULSE_UNINITIALIZED_VALUE, no_bucket, ERROR, [variable `x` declared here,read to uninitialized value occurs here] -codetoanalyze/objc/pulse/uninit.m, Uninit.not_set_in_closure_bad, 7, PULSE_UNINITIALIZED_VALUE, no_bucket, ERROR, [variable `x` declared here,read to uninitialized value occurs here] -codetoanalyze/objc/pulse/uninit.m, Uninit.use_in_closure_bad, 7, PULSE_UNINITIALIZED_VALUE, no_bucket, ERROR, [variable `x` declared here,when calling `objc_blockUninit.use_in_closure_bad_5` here,parameter `x` of objc_blockUninit.use_in_closure_bad_5,read to uninitialized value occurs 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] diff --git a/infer/tests/codetoanalyze/objc/pulse/uninit.m b/infer/tests/codetoanalyze/objc/pulse/uninit.m index ed5251a39..ab5dbe252 100644 --- a/infer/tests/codetoanalyze/objc/pulse/uninit.m +++ b/infer/tests/codetoanalyze/objc/pulse/uninit.m @@ -7,6 +7,9 @@ #import @interface Uninit : NSObject + +@property(nonatomic, assign) int obj_field; + @end struct my_struct { @@ -24,7 +27,7 @@ struct my_struct { }; } -- (BOOL)capture_in_closure_bad { +- (BOOL)capture_in_closure_bad_FN { __block BOOL x; void (^block)() = ^() { @@ -45,7 +48,7 @@ struct my_struct { return x; } -- (BOOL)not_set_in_closure_bad { +- (BOOL)not_set_in_closure_bad_FN { __block BOOL x; void (^block)() = ^() { @@ -55,7 +58,7 @@ struct my_struct { return x; } -- (BOOL)use_in_closure_bad { +- (BOOL)use_in_closure_bad_FN { __block BOOL x; void (^block)() = ^() { @@ -96,4 +99,20 @@ struct my_struct { return [o return_my_struct].x; } +dispatch_queue_t queue; + +- (void)dispatch_sync_block:(dispatch_block_t)block { + dispatch_sync(queue, ^{ + block(); + }); +} + +- (int)init_x_in_block_ok { + __block int x; + [self dispatch_sync_block:^{ + x = self->_obj_field; + }]; + return x; +} + @end