[uninit/pulse] Do not track captured variables of block

Summary:
When a block value is passed via more than one-depth of function calls, it is not analyzed correctly
because current inlining mechanism (specializing objc block parameters) of the frontend works for
only one-depth of block passing.  This diff gives up analyzing initialized-ness of captured
variables in ObjC to avoid FPs.

Reviewed By: da319

Differential Revision: D27885395

fbshipit-source-id: fc6b4663c
master
Sungkeun Cho 4 years ago committed by Facebook GitHub Bot
parent df9bb5dc37
commit fa10bb225a

@ -569,7 +569,10 @@ let mk_initial tenv proc_desc =
in in
let locals = Procdesc.get_locals proc_desc in let locals = Procdesc.get_locals proc_desc in
let post = let post =
List.fold locals ~init:post ~f:(fun (acc : PostDomain.t) {ProcAttributes.name; typ} -> 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 ) set_uninitialized_post tenv (`LocalDecl (Pvar.mk name proc_name, None)) typ location acc )
in in
{ pre { pre

@ -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/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, 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/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, 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] 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]

@ -7,6 +7,9 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface Uninit : NSObject @interface Uninit : NSObject
@property(nonatomic, assign) int obj_field;
@end @end
struct my_struct { struct my_struct {
@ -24,7 +27,7 @@ struct my_struct {
}; };
} }
- (BOOL)capture_in_closure_bad { - (BOOL)capture_in_closure_bad_FN {
__block BOOL x; __block BOOL x;
void (^block)() = ^() { void (^block)() = ^() {
@ -45,7 +48,7 @@ struct my_struct {
return x; return x;
} }
- (BOOL)not_set_in_closure_bad { - (BOOL)not_set_in_closure_bad_FN {
__block BOOL x; __block BOOL x;
void (^block)() = ^() { void (^block)() = ^() {
@ -55,7 +58,7 @@ struct my_struct {
return x; return x;
} }
- (BOOL)use_in_closure_bad { - (BOOL)use_in_closure_bad_FN {
__block BOOL x; __block BOOL x;
void (^block)() = ^() { void (^block)() = ^() {
@ -96,4 +99,20 @@ struct my_struct {
return [o return_my_struct].x; 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 @end

Loading…
Cancel
Save