diff --git a/infer/src/bufferoverrun/bufferOverrunModels.ml b/infer/src/bufferoverrun/bufferOverrunModels.ml index 9be12e3ab..2c3de412c 100644 --- a/infer/src/bufferoverrun/bufferOverrunModels.ml +++ b/infer/src/bufferoverrun/bufferOverrunModels.ml @@ -1690,6 +1690,8 @@ module Call = struct &:: "removeAllObjects:" <>$ capt_var_exn $--> NSCollection.remove_all ; +PatternMatch.ObjectiveC.implements "NSMutableArray" &:: "addObjectsFromArray:" <>$ capt_var_exn $+ capt_exp $--> NSCollection.addAll + ; +PatternMatch.ObjectiveC.implements "NSDictionary" + &:: "dictionary" <>--> NSCollection.new_collection ; +PatternMatch.ObjectiveC.implements "NSDictionary" &:: "dictionaryWithObjects:forKeys:count:" <>$ any_arg $+ capt_exp $+ capt_exp $--> NSCollection.create_from_array diff --git a/infer/tests/codetoanalyze/objc/performance/NSDictionary.m b/infer/tests/codetoanalyze/objc/performance/NSDictionary.m index 7f603b9c0..e614f5f97 100644 --- a/infer/tests/codetoanalyze/objc/performance/NSDictionary.m +++ b/infer/tests/codetoanalyze/objc/performance/NSDictionary.m @@ -107,3 +107,8 @@ void nsdictionary_enumerate_call_constant_FP() { nsdictionary_all_values_linear(dict); } + +void nsdictionary_dictionary_constant() { + NSDictionary* dict = nsdictionary_init_dictionary_constant(); + nsdictionary_all_values_linear(dict); +} diff --git a/infer/tests/codetoanalyze/objc/performance/cost-issues.exp b/infer/tests/codetoanalyze/objc/performance/cost-issues.exp index 6b68e5cf4..d60c4309d 100644 --- a/infer/tests/codetoanalyze/objc/performance/cost-issues.exp +++ b/infer/tests/codetoanalyze/objc/performance/cost-issues.exp @@ -26,6 +26,7 @@ codetoanalyze/objc/performance/NSArray.m, nsarray_sort_using_descriptors_nlogn, codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_all_keys_linear1, 3 + 3 ⋅ dict->elements.length.ub + 4 ⋅ (dict->elements.length.ub + 1), OnUIThread:false, [{dict->elements.length.ub + 1},Loop,{dict->elements.length.ub},Loop] codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_all_keys_linear2, 6 + 3 ⋅ dict->elements.length.ub + 3 ⋅ (dict->elements.length.ub + 1), OnUIThread:false, [{dict->elements.length.ub + 1},Loop,{dict->elements.length.ub},Loop] codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_all_values_linear, 3 + 3 ⋅ dict->elements.length.ub + 4 ⋅ (dict->elements.length.ub + 1), OnUIThread:false, [{dict->elements.length.ub + 1},Loop,{dict->elements.length.ub},Loop] +codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_dictionary_constant, 13, OnUIThread:false, [] codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_dictionary_with_objects_linear, 14 + 15 ⋅ n_entries + 3 ⋅ n_entries + 2 ⋅ (1+max(0, n_entries)) + 4 ⋅ (1+max(0, n_entries)), OnUIThread:false, [{1+max(0, n_entries)},Loop,{1+max(0, n_entries)},Loop,{n_entries},Loop,{n_entries},Loop] codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_enumerate_call_constant_FP, ⊤, OnUIThread:false, [Unbounded value dict->elements.length.ub,Call to nsdictionary_all_values_linear,Loop] codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_enumerate_constant, 52, OnUIThread:false, []