diff --git a/infer/src/clang/cFrontend_config.ml b/infer/src/clang/cFrontend_config.ml index 4bbb6bc66..8b5823d8d 100644 --- a/infer/src/clang/cFrontend_config.ml +++ b/infer/src/clang/cFrontend_config.ml @@ -25,6 +25,8 @@ type decl_trans_context = [`DeclTraversal | `Translation | `CppLambdaExprTransla let alloc = "alloc" +let allocWithZone = "allocWithZone:" + let arrayWithObjects_count = "arrayWithObjects:count:" let dictionaryWithObjects_forKeys_count = "dictionaryWithObjects:forKeys:count:" diff --git a/infer/src/clang/cFrontend_config.mli b/infer/src/clang/cFrontend_config.mli index 9ae92868a..b6b95e021 100644 --- a/infer/src/clang/cFrontend_config.mli +++ b/infer/src/clang/cFrontend_config.mli @@ -25,6 +25,8 @@ type decl_trans_context = [`DeclTraversal | `Translation | `CppLambdaExprTransla val alloc : string +val allocWithZone : string + val arrayWithObjects_count : string val dictionaryWithObjects_forKeys_count : string diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 13600b932..c8528f586 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -1298,7 +1298,12 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s Some (mk_trans_result (exp, typ) empty_control) else if (* alloc or new *) - String.equal selector CFrontend_config.alloc || String.equal selector CFrontend_config.new_str + String.equal selector CFrontend_config.alloc + (* allocWithZone is like alloc: This method exists for + historical reasons; memory zones are no longer used by + Objective-C. *) + || String.equal selector CFrontend_config.allocWithZone + || String.equal selector CFrontend_config.new_str then match receiver_kind with | `Class qual_type -> @@ -2221,10 +2226,10 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s for (__begin = __range.begin(), __end = __range.end(); __begin != __end; ++__begin) - { - v = *__begin; - loop_body; - } + { + v = *__begin; + loop_body; + } ]} *) and cxxForRangeStmt_trans trans_state stmt_info stmt_list = let open Clang_ast_t in @@ -2899,11 +2904,11 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s {[ n$1=NSNumber.numberWithInt:(2:int) - n$2=NSNumber.numberWithInt:(3:int) - temp[0]:objc_object*=n$1 - temp[1]:objc_object*=n$2 - n$3=NSArray.arrayWithObjects:count:(temp:objc_object* const [2*8],2:int) - a:NSArray*=n$3 + n$2=NSNumber.numberWithInt:(3:int) + temp[0]:objc_object*=n$1 + temp[1]:objc_object*=n$2 + n$3=NSArray.arrayWithObjects:count:(temp:objc_object* const [2*8],2:int) + a:NSArray*=n$3 ]} where [temp] is an additional local variable declared as array. *) @@ -2992,15 +2997,15 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s {[ n$1=NSString.stringWithUTF8:(@"firstName") - n$2=NSNumber.stringWithUTF8:(@"Foo") - n$3=NSNumber.stringWithUTF8:(@"lastName") - n$4=NSNumber.stringWithUTF8:(@"Bar") - temp1[0]:objc_object*=n$1 - temp1[1]:objc_object*=n$3 - temp2[0]:objc_object*=n$2 - temp2[1]:objc_object*=n$4 - n$3=NSDictionary.dictionaryWithObjects:forKeys:count:(temp2:objc_object* const [2*8], - temp1:objc_object* const [2*8], 2:int) + n$2=NSNumber.stringWithUTF8:(@"Foo") + n$3=NSNumber.stringWithUTF8:(@"lastName") + n$4=NSNumber.stringWithUTF8:(@"Bar") + temp1[0]:objc_object*=n$1 + temp1[1]:objc_object*=n$3 + temp2[0]:objc_object*=n$2 + temp2[1]:objc_object*=n$4 + n$3=NSDictionary.dictionaryWithObjects:forKeys:count:(temp2:objc_object* const [2*8], + temp1:objc_object* const [2*8], 2:int) ]} where [temp1] [temp2] are additional local variables declared as array. *) diff --git a/infer/src/clang/cTrans_utils.ml b/infer/src/clang/cTrans_utils.ml index 73ffe5490..92bd2dc0e 100644 --- a/infer/src/clang/cTrans_utils.ml +++ b/infer/src/clang/cTrans_utils.ml @@ -363,7 +363,10 @@ let new_or_alloc_trans trans_state loc stmt_info qual_type class_name_opt select | None -> CType.objc_classname_of_type function_type in - if String.equal selector CFrontend_config.alloc then + if + String.equal selector CFrontend_config.alloc + || String.equal selector CFrontend_config.allocWithZone + then alloc_trans trans_state ~alloc_builtin:BuiltinDecl.__objc_alloc_no_fail loc stmt_info function_type else if String.equal selector CFrontend_config.new_str then diff --git a/infer/tests/codetoanalyze/objc/performance/NSDictionary.m b/infer/tests/codetoanalyze/objc/performance/NSDictionary.m index 32453761c..ffc68d52d 100644 --- a/infer/tests/codetoanalyze/objc/performance/NSDictionary.m +++ b/infer/tests/codetoanalyze/objc/performance/NSDictionary.m @@ -25,6 +25,14 @@ void nsdictionary_init_with_dictionary_linear(NSDictionary* dict) { } } +void nsdictionary_alloc_with_zone_init_with_dictionary_linear( + NSDictionary* dict, NSZone* zone) { + NSDictionary* copy_dict = + [[NSDictionary allocWithZone:zone] initWithDictionary:dict]; + for (int i = 0; i < [copy_dict allValues].count; i++) { + } +} + NSDictionary* nsdictionary_dictionary_with_objects_linear(int n_entries) { NSDictionary* asciiDict; NSString* keyArray[n_entries]; diff --git a/infer/tests/codetoanalyze/objc/performance/cost-issues.exp b/infer/tests/codetoanalyze/objc/performance/cost-issues.exp index e28f67618..2f264e9bc 100644 --- a/infer/tests/codetoanalyze/objc/performance/cost-issues.exp +++ b/infer/tests/codetoanalyze/objc/performance/cost-issues.exp @@ -31,6 +31,7 @@ codetoanalyze/objc/performance/NSArray.m, objc_blocknsarray_binary_search_log_FN 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_alloc_with_zone_init_with_dictionary_linear, 7 + 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, 65, OnUIThread:false, []