diff --git a/infer/src/IR/ProcAttributes.ml b/infer/src/IR/ProcAttributes.ml index 10b35a5db..dcc29f38d 100644 --- a/infer/src/IR/ProcAttributes.ml +++ b/infer/src/IR/ProcAttributes.ml @@ -56,6 +56,10 @@ type objc_accessor_type = | Objc_setter of Typ.Struct.field [@@deriving compare] +let kind_of_objc_accessor_type accessor = + match accessor with Objc_getter _ -> "getter" | Objc_setter _ -> "setter" + + type var_attribute = Modify_in_block [@@deriving compare] let var_attribute_equal = [%compare.equal : var_attribute] diff --git a/infer/src/IR/ProcAttributes.mli b/infer/src/IR/ProcAttributes.mli index 1d9b73b75..1591d0736 100644 --- a/infer/src/IR/ProcAttributes.mli +++ b/infer/src/IR/ProcAttributes.mli @@ -32,6 +32,8 @@ type objc_accessor_type = | Objc_setter of Typ.Struct.field [@@deriving compare] +val kind_of_objc_accessor_type : objc_accessor_type -> string + type var_attribute = | Modify_in_block (* __block attribute of Objective-C variables, means that it will be modified inside a block *) diff --git a/infer/src/biabduction/SymExec.ml b/infer/src/biabduction/SymExec.ml index 8b98fc85b..ac13e26da 100644 --- a/infer/src/biabduction/SymExec.ml +++ b/infer/src/biabduction/SymExec.ml @@ -1271,7 +1271,7 @@ let rec sym_exec exe_env tenv current_pdesc instr_ (prop_: Prop.normal Prop.t) p (* If it's an ObjC getter or setter, call the builtin rather than skipping *) handle_objc_instance_method_call n_actual_params n_actual_params prop tenv ret_id current_pdesc callee_pname loc path - (sym_exec_objc_accessor objc_accessor ret_type) + (sym_exec_objc_accessor callee_pname objc_accessor ret_type) | None, true -> (* If it's an alloc model, call alloc rather than skipping *) sym_exec_alloc_model exe_env callee_pname ret_type tenv ret_id @@ -1661,8 +1661,8 @@ and sym_exec_objc_setter field _ tenv _ pdesc pname loc args prop = raise (Exceptions.Wrong_argument_number __POS__) -and sym_exec_objc_accessor property_accesor ret_typ tenv ret_id pdesc _ loc args prop path - : Builtin.ret_typ = +and sym_exec_objc_accessor callee_pname property_accesor ret_typ tenv ret_id pdesc _ loc args prop + path : Builtin.ret_typ = let f_accessor = match property_accesor with | ProcAttributes.Objc_getter field -> @@ -1673,6 +1673,12 @@ and sym_exec_objc_accessor property_accesor ret_typ tenv ret_id pdesc _ loc args (* we want to execute in the context of the current procedure, not in the context of callee_pname, since this is the procname of the setter/getter method *) let cur_pname = Procdesc.get_proc_name pdesc in + let path_description = + F.sprintf "Executing synthesized %s %s" + (ProcAttributes.kind_of_objc_accessor_type property_accesor) + (Typ.Procname.to_simplified_string callee_pname) + in + let path = Paths.Path.add_description path path_description in f_accessor ret_typ tenv ret_id pdesc cur_pname loc args prop |> List.map ~f:(fun p -> (p, path)) diff --git a/infer/tests/build_systems/objc_getters_setters/issues.exp b/infer/tests/build_systems/objc_getters_setters/issues.exp index d6855c10a..30c307493 100644 --- a/infer/tests/build_systems/objc_getters_setters/issues.exp +++ b/infer/tests/build_systems/objc_getters_setters/issues.exp @@ -1,5 +1,5 @@ build_systems/codetoanalyze/objc_getters_setters/B.m, B_calling_c_function_with_block_parameters_sets_fields_correctly, 5, NULL_DEREFERENCE, ERROR, [start of procedure calling_c_function_with_block_parameters_sets_fields_correctly,start of procedure calling_c_function_with_block_parameters,start of procedure c_function(),start of procedure block,return from a call to objc_blockB_calling_c_function_with_block_parameters_3,start of procedure block,return from a call to objc_blockB_calling_c_function_with_block_parameters_4,return from a call to c_function_objc_blockB_calling_c_function_with_block_parameters_3_objc_blockB_calling_c_function_with_block_parameters_4,return from a call to B_calling_c_function_with_block_parameters,Condition is true] build_systems/codetoanalyze/objc_getters_setters/B.m, B_calling_method_with_block_parameters_sets_fields_correctly, 5, NULL_DEREFERENCE, ERROR, [start of procedure calling_method_with_block_parameters_sets_fields_correctly,start of procedure calling_method_with_block_parameters,start of procedure foo:and:and_also:and:,start of procedure block,return from a call to objc_blockB_calling_method_with_block_parameters_1,start of procedure block,return from a call to objc_blockB_calling_method_with_block_parameters_2,return from a call to A_foo:and:and_also:and:_objc_blockB_calling_method_with_block_parameters_1_objc_blockB_calling_method_with_block_parameters_2,return from a call to B_calling_method_with_block_parameters,Condition is true] -build_systems/codetoanalyze/objc_getters_setters/B.m, B_npe_no_bad_footprint_in_getter:, 3, NULL_DEREFERENCE, ERROR, [start of procedure npe_no_bad_footprint_in_getter:] -build_systems/codetoanalyze/objc_getters_setters/B.m, B_npe_no_bad_footprint_in_setter:andMetadata:, 3, NULL_DEREFERENCE, ERROR, [start of procedure npe_no_bad_footprint_in_setter:andMetadata:] +build_systems/codetoanalyze/objc_getters_setters/B.m, B_npe_no_bad_footprint_in_getter:, 3, NULL_DEREFERENCE, ERROR, [start of procedure npe_no_bad_footprint_in_getter:,Executing synthesized getter metadata] +build_systems/codetoanalyze/objc_getters_setters/B.m, B_npe_no_bad_footprint_in_setter:andMetadata:, 3, NULL_DEREFERENCE, ERROR, [start of procedure npe_no_bad_footprint_in_setter:andMetadata:,Executing synthesized setter setMetadata:] build_systems/codetoanalyze/objc_getters_setters/B.m, B_npe_no_precondition_not_met:, 4, NULL_DEREFERENCE, ERROR, [start of procedure npe_no_precondition_not_met:,start of procedure infer_field_get_spec:,start of procedure withMetadata:,return from a call to A_withMetadata:,return from a call to B_infer_field_get_spec:,start of procedure getX,return from a call to A_getX,Condition is true] diff --git a/infer/tests/codetoanalyze/objc/errors/issues.exp b/infer/tests/codetoanalyze/objc/errors/issues.exp index f9f6201b1..2f44cafba 100644 --- a/infer/tests/codetoanalyze/objc/errors/issues.exp +++ b/infer/tests/codetoanalyze/objc/errors/issues.exp @@ -7,7 +7,7 @@ codetoanalyze/objc/errors/npe/null_returned_by_method.m, NullReturnedByMethodA_t codetoanalyze/objc/errors/procdescs/main.c, ProcdescMain, 3, MEMORY_LEAK, ERROR, [start of procedure ProcdescMain(),Skipping plusX:andY:: function or method not found] codetoanalyze/objc/errors/procdescs/main.c, call_nslog, 3, MEMORY_LEAK, ERROR, [start of procedure call_nslog(),Skipping NSLog(): function or method not found] codetoanalyze/objc/errors/property/main.c, property_main, 3, MEMORY_LEAK, ERROR, [start of procedure property_main(),Skipping aProperty: function or method not found] -codetoanalyze/objc/errors/warnings/ParameterNotNullableExample.m, FBAudioRecorder_FBAudioInputCallbackChain:, 2, NULL_DEREFERENCE, ERROR, [start of procedure FBAudioInputCallbackChain:,Message recordState with receiver nil returns nil.] +codetoanalyze/objc/errors/warnings/ParameterNotNullableExample.m, FBAudioRecorder_FBAudioInputCallbackChain:, 2, NULL_DEREFERENCE, ERROR, [start of procedure FBAudioInputCallbackChain:,Executing synthesized getter recorder Message recordState with receiver nil returns nil.] codetoanalyze/objc/errors/warnings/ParameterNotNullableExample.m, FBAudioRecorder_FBAudioInputCallbackChain:, 2, PARAMETER_NOT_NULL_CHECKED, WARNING, [start of procedure FBAudioInputCallbackChain:,Message recorder with receiver nil returns nil. Message recordState with receiver nil returns nil.] codetoanalyze/objc/errors/warnings/ParameterNotNullableExample.m, FBAudioRecorder_FBAudioInputCallbackField, 2, NULL_DEREFERENCE, ERROR, [start of procedure FBAudioInputCallbackField,Message recordState with receiver nil returns nil.] codetoanalyze/objc/errors/warnings/ParameterNotNullableExample.m, FBAudioRecorder_FBAudioInputCallbackSimple:, 2, PARAMETER_NOT_NULL_CHECKED, WARNING, [start of procedure FBAudioInputCallbackSimple:,Message recordState with receiver nil returns nil.] @@ -21,7 +21,7 @@ codetoanalyze/objc/shared/block/block.m, main1, 31, DIVIDE_BY_ZERO, ERROR, [star codetoanalyze/objc/shared/block/block_no_args.m, My_manager_m, 10, NULL_DEREFERENCE, ERROR, [start of procedure m,start of procedure block,return from a call to objc_blockMy_manager_m_1,Condition is true] codetoanalyze/objc/shared/category_procdesc/main.c, CategoryProcdescMain, 3, MEMORY_LEAK, ERROR, [start of procedure CategoryProcdescMain(),Skipping performDaysWork: function or method not found] codetoanalyze/objc/shared/field_superclass/SuperExample.m, ASuper_init, 2, NULL_DEREFERENCE, ERROR, [start of procedure init,start of procedure init,return from a call to BSuper_init] -codetoanalyze/objc/errors/blocks_in_heap/BlockInHeap.m, block_in_heap_executed_after_bi_abduction_ok_test, 3, NULL_DEREFERENCE, ERROR, [start of procedure block_in_heap_executed_after_bi_abduction_ok_test(),start of procedure block_in_heap_executed_after_bi_abduction_ok_no_retain_cycle(),start of procedure assign_block_to_ivar,return from a call to BlockInHeap_assign_block_to_ivar,start of procedure block,return from a call to objc_blockBlockInHeap_assign_block_to_ivar_1,return from a call to block_in_heap_executed_after_bi_abduction_ok_no_retain_cycle,Condition is true] +codetoanalyze/objc/errors/blocks_in_heap/BlockInHeap.m, block_in_heap_executed_after_bi_abduction_ok_test, 3, NULL_DEREFERENCE, ERROR, [start of procedure block_in_heap_executed_after_bi_abduction_ok_test(),start of procedure block_in_heap_executed_after_bi_abduction_ok_no_retain_cycle(),start of procedure assign_block_to_ivar,Executing synthesized setter setHandler:,return from a call to BlockInHeap_assign_block_to_ivar,Executing synthesized getter handler,start of procedure block,return from a call to objc_blockBlockInHeap_assign_block_to_ivar_1,return from a call to block_in_heap_executed_after_bi_abduction_ok_no_retain_cycle,Condition is true] codetoanalyze/objc/errors/field_superclass/SubtypingExample.m, Employee_initWithName:andAge:andEducation:, 3, NULL_TEST_AFTER_DEREFERENCE, WARNING, [start of procedure initWithName:andAge:andEducation:,start of procedure initWithName:andAge:,return from a call to Person_initWithName:andAge:,Condition is false] codetoanalyze/objc/errors/field_superclass/SubtypingExample.m, Employee_initWithName:andAge:andEducation:, 6, DIVIDE_BY_ZERO, ERROR, [start of procedure initWithName:andAge:andEducation:,start of procedure initWithName:andAge:,return from a call to Person_initWithName:andAge:,Condition is true] codetoanalyze/objc/errors/field_superclass/SubtypingExample.m, subtyping_test, 0, DIVIDE_BY_ZERO, ERROR, [start of procedure subtyping_test(),start of procedure testFields(),start of procedure setEmployeeEducation:,return from a call to Employee_setEmployeeEducation:,start of procedure setAge:,return from a call to Person_setAge:,start of procedure setEmployeeEducation:,return from a call to Employee_setEmployeeEducation:,start of procedure getAge,return from a call to Person_getAge,return from a call to testFields] @@ -32,9 +32,9 @@ codetoanalyze/objc/errors/memory_leaks_benchmark/CADisplayLinkRetainCycle.m, CAD codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlockCapturedVar.m, LinkResolver_test_bad, 3, RETAIN_CYCLE, ERROR, [start of procedure test_bad] codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m, RCBlock_retain_self_in_block, 1, RETAIN_CYCLE, ERROR, [start of procedure retain_self_in_block] codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m, objc_blockretain_a_in_block_cycle_3, 1, RETAIN_CYCLE, ERROR, [start of procedure block] -codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m, retain_a_in_block_cycle, 4, RETAIN_CYCLE, ERROR, [start of procedure retain_a_in_block_cycle()] -codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCyclePropertyInProtocol.m, MyCustomViewController_loadViewBad, 3, RETAIN_CYCLE, ERROR, [start of procedure loadViewBad] -codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle.m, strongcycle, 6, RETAIN_CYCLE, ERROR, [start of procedure strongcycle()] +codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m, retain_a_in_block_cycle, 4, RETAIN_CYCLE, ERROR, [start of procedure retain_a_in_block_cycle(),Executing synthesized setter setB:] +codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCyclePropertyInProtocol.m, MyCustomViewController_loadViewBad, 3, RETAIN_CYCLE, ERROR, [start of procedure loadViewBad,Executing synthesized setter setView:] +codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle.m, strongcycle, 6, RETAIN_CYCLE, ERROR, [start of procedure strongcycle(),Executing synthesized setter setB:] codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle2.m, strongcycle2, 4, RETAIN_CYCLE, ERROR, [start of procedure strongcycle2(),start of procedure init,return from a call to Parent_init,start of procedure init,return from a call to Child_init,start of procedure setChild:,return from a call to Parent_setChild:] codetoanalyze/objc/errors/npe/UpdateDict.m, add_nil_in_dict, 10, NULL_DEREFERENCE, ERROR, [start of procedure add_nil_in_dict(),Skipping dictionaryWithObjectsAndKeys:: function or method not found] codetoanalyze/objc/errors/npe/UpdateDict.m, add_nil_to_array, 4, NULL_DEREFERENCE, ERROR, [start of procedure add_nil_to_array()] @@ -73,7 +73,7 @@ codetoanalyze/objc/errors/variadic_methods/premature_nil_termination.m, Prematur codetoanalyze/objc/errors/memory_leaks_benchmark/CoreVideoExample.m, CoreVideoExample_cvpixelbuffer_not_released_leak, 1, MEMORY_LEAK, ERROR, [start of procedure cvpixelbuffer_not_released_leak] codetoanalyze/objc/errors/memory_leaks_benchmark/NSData_models_tests.m, NSData_models_tests_macForIV:, 2, MEMORY_LEAK, ERROR, [start of procedure macForIV:] codetoanalyze/objc/errors/memory_leaks_benchmark/NSString_models_tests.m, StringInitA_hexStringValue, 11, MEMORY_LEAK, ERROR, [start of procedure hexStringValue,Skipping CFStringCreateWithBytesNoCopy(): function or method not found,Condition is false] -codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleLength3.m, strongcycle, 6, RETAIN_CYCLE, ERROR, [start of procedure strongcycle()] +codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleLength3.m, strongcycle, 6, RETAIN_CYCLE, ERROR, [start of procedure strongcycle(),Executing synthesized setter setB:,Executing synthesized setter setC:] codetoanalyze/objc/errors/npe/Fraction.m, test_virtual_call, 7, NULL_DEREFERENCE, ERROR, [start of procedure test_virtual_call(),start of procedure setNumerator:,return from a call to Fraction_setNumerator:,start of procedure getNumerator,return from a call to Fraction_getNumerator,Condition is true] codetoanalyze/objc/errors/npe/Npe_with_equal_names.m, EqualNamesTest, 3, NULL_DEREFERENCE, ERROR, [start of procedure EqualNamesTest(),start of procedure meth,return from a call to EqualNamesA_meth] codetoanalyze/objc/errors/npe/block.m, BlockA_doSomethingThenCallback:, 2, PARAMETER_NOT_NULL_CHECKED, WARNING, [start of procedure doSomethingThenCallback:]