[frontend] Revise translation of message expression in ObjC frontend

Summary:
This diff revises the translation of message expression's arguments in ObjC frontend.  In the
frontend, it massages the arguments when calling a static method, so the class or object value is
not given to the static method as the first parameter.

The problem is that it used a raise-exception-and-catch way to detect where we remove the first
parameter.  This way of using an exception is not only hard to understand, but also incorrectly
removed the first parameter, with breaking abstract semantics sometimes.  (See the added test.)  This diff
avoids using the exception.

Reviewed By: jvillard

Differential Revision: D24565513

fbshipit-source-id: 0a84ca394
master
Sungkeun Cho 4 years ago committed by Facebook GitHub Bot
parent 4473c6a193
commit 6bf091d8c0

@ -838,14 +838,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
in
let return =
if Self.is_var_self pvar (CContext.is_objc_method context) && CType.is_class typ then
let class_name = CContext.get_curr_class_typename stmt_info context in
if trans_state.is_fst_arg_objc_instance_method_call then
raise
(Self.SelfClassException
{class_name; position= __POS__; source_range= stmt_info.Clang_ast_t.si_source_range})
else
let exp_typ = sizeof_expr_class class_name in
exp_typ
sizeof_expr_class (CContext.get_curr_class_typename stmt_info context)
else (var_exp, typ)
in
L.(debug Capture Verbose) "@\n@\n PVAR ='%s'@\n@\n" (Pvar.to_string pvar) ;
@ -1289,13 +1282,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
CMethod_trans.get_class_name_method_call_from_receiver_kind context obj_c_message_expr_info
act_params
in
if trans_state.is_fst_arg_objc_instance_method_call && is_receiver_instance receiver_kind then
raise
(Self.SelfClassException
{class_name; position= __POS__; source_range= si.Clang_ast_t.si_source_range})
else
let exp, typ = sizeof_expr_class class_name in
Some (mk_trans_result (exp, typ) empty_control)
Some (mk_trans_result (sizeof_expr_class class_name) empty_control)
else if
(* alloc or new *)
String.equal selector CFrontend_config.alloc
@ -1347,23 +1334,24 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let param_trans_results =
List.mapi ~f:(exec_instruction_with_trans_state trans_state_param callee_ms_opt) rest
in
try
let trans_state_param' =
if is_receiver_instance obj_c_message_expr_info.Clang_ast_t.omei_receiver_kind then
{trans_state_param with is_fst_arg_objc_instance_method_call= true}
else {trans_state_param with is_fst_arg_objc_instance_method_call= false}
in
let fst_res_trans =
exec_instruction_with_trans_state trans_state_param' callee_ms_opt 0 stmt
in
(obj_c_message_expr_info, fst_res_trans :: param_trans_results)
with Self.SelfClassException e ->
let pointer = obj_c_message_expr_info.Clang_ast_t.omei_decl_pointer in
let selector = obj_c_message_expr_info.Clang_ast_t.omei_selector in
let obj_c_message_expr_info =
Ast_expressions.make_obj_c_message_expr_info_class selector e.class_name pointer
in
(obj_c_message_expr_info, param_trans_results) )
let trans_state_param' =
{ trans_state_param with
is_fst_arg_objc_instance_method_call=
is_receiver_instance obj_c_message_expr_info.Clang_ast_t.omei_receiver_kind }
in
match CTrans_utils.should_remove_first_param trans_state_param' stmt with
| Some class_name ->
let pointer = obj_c_message_expr_info.Clang_ast_t.omei_decl_pointer in
let selector = obj_c_message_expr_info.Clang_ast_t.omei_selector in
let obj_c_message_expr_info =
Ast_expressions.make_obj_c_message_expr_info_class selector class_name pointer
in
(obj_c_message_expr_info, param_trans_results)
| None ->
let fst_res_trans =
exec_instruction_with_trans_state trans_state_param' callee_ms_opt 0 stmt
in
(obj_c_message_expr_info, fst_res_trans :: param_trans_results) )
| [] ->
(obj_c_message_expr_info, [])

@ -581,10 +581,6 @@ let extract_stmt_from_singleton stmt_list source_range warning_string =
module Self = struct
exception
SelfClassException of
{class_name: Typ.Name.t; position: Logging.ocaml_pos; source_range: Clang_ast_t.source_range}
let add_self_parameter_for_super_instance stmt_info context procname loc mei =
if is_superinstance mei then
let typ, self_expr, instrs =
@ -644,3 +640,33 @@ let last_or_mk_fresh_void_exp_typ exp_typs =
last_exp_typ
| None ->
mk_fresh_void_exp_typ ()
let should_remove_first_param {context= {tenv} as context; is_fst_arg_objc_instance_method_call}
stmt =
let some_class_name stmt_info = Some (CContext.get_curr_class_typename stmt_info context) in
match (stmt : Clang_ast_t.stmt) with
| ImplicitCastExpr
( _
, [ DeclRefExpr
( stmt_info
, _
, _
, {drti_decl_ref= Some {dr_name= Some {ni_name= name}; dr_qual_type= Some qual_type}} )
]
, _
, {cei_cast_kind= `LValueToRValue} )
when is_fst_arg_objc_instance_method_call && String.equal name "self"
&& CType.is_class (CType_decl.qual_type_to_sil_type tenv qual_type) ->
some_class_name stmt_info
| ObjCMessageExpr
( _
, [ ImplicitCastExpr
(_, [DeclRefExpr (stmt_info, _, _, _)], _, {cei_cast_kind= `LValueToRValue}) ]
, _
, {omei_selector= selector} )
when is_fst_arg_objc_instance_method_call && String.equal selector CFrontend_config.class_method
->
some_class_name stmt_info
| _ ->
None

@ -231,10 +231,6 @@ end
(** This module handles the translation of the variable self which is challenging because self is
used both as a variable in instance method calls and also as a type in class method calls. *)
module Self : sig
exception
SelfClassException of
{class_name: Typ.Name.t; position: Logging.ocaml_pos; source_range: Clang_ast_t.source_range}
val add_self_parameter_for_super_instance :
Clang_ast_t.stmt_info
-> CContext.t
@ -256,3 +252,7 @@ val mk_fresh_void_id_typ : unit -> Ident.t * Typ.t
val mk_fresh_void_return : unit -> (Ident.t * Typ.t) * (Exp.t * Typ.t)
val last_or_mk_fresh_void_exp_typ : (Exp.t * Typ.t) list -> Exp.t * Typ.t
val should_remove_first_param : trans_state -> Clang_ast_t.stmt -> Typ.name option
(** Return a class name when the first parameter should be removed according to its context, for
example, when [self] or [\[x class\]] is given as the first parameter for a class method. *)

@ -61,18 +61,18 @@ digraph cfg {
"calling_super#A#class.0edc1d1d1c4ade7cd9adaa77e7322ad1_2" [label="2: Exit A.calling_super \n " color=yellow style=filled]
"calling_super#A#class.0edc1d1d1c4ade7cd9adaa77e7322ad1_3" [label="3: Message Call: test_class \n n$18=_fun_C.test_class() [line 82, column 3]\n " shape="box"]
"calling_super#A#class.0edc1d1d1c4ade7cd9adaa77e7322ad1_3" [label="3: Message Call: test_class \n n$15=_fun_C.test_class() [line 82, column 3]\n " shape="box"]
"calling_super#A#class.0edc1d1d1c4ade7cd9adaa77e7322ad1_3" -> "calling_super#A#class.0edc1d1d1c4ade7cd9adaa77e7322ad1_2" ;
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_1" [label="1: Start A.class_method_fst_arg_of_class_method_inside_instance_method\nFormals: \nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$30:NSBundle* stringsBundlePath:NSString* \n " color=yellow style=filled]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_1" [label="1: Start A.class_method_fst_arg_of_class_method_inside_instance_method\nFormals: \nLocals: 0$?%__sil_tmpSIL_temp_conditional___n$27:NSBundle* stringsBundlePath:NSString* \n " color=yellow style=filled]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_1" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_11" ;
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_2" [label="2: Exit A.class_method_fst_arg_of_class_method_inside_instance_method \n " color=yellow style=filled]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_3" [label="3: Return Stmt \n n$27=*&#GB<codetoanalyze/objc/frontend/self_static/Self.m>$A.class_method_fst_arg_of_class_method_inside_instance_method.bundle:NSBundle* [line 120, column 10]\n *&return:NSBundle*=n$27 [line 120, column 3]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_3" [label="3: Return Stmt \n n$24=*&#GB<codetoanalyze/objc/frontend/self_static/Self.m>$A.class_method_fst_arg_of_class_method_inside_instance_method.bundle:NSBundle* [line 120, column 10]\n *&return:NSBundle*=n$24 [line 120, column 3]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_3" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_2" ;
@ -80,32 +80,32 @@ digraph cfg {
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_4" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_10" ;
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_5" [label="5: Prune (true branch, boolean exp) \n PRUNE(n$29, true); [line 119, column 12]\n " shape="invhouse"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_5" [label="5: Prune (true branch, boolean exp) \n PRUNE(n$26, true); [line 119, column 12]\n " shape="invhouse"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_5" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_7" ;
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_6" [label="6: Prune (false branch, boolean exp) \n PRUNE(!n$29, false); [line 119, column 12]\n " shape="invhouse"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_6" [label="6: Prune (false branch, boolean exp) \n PRUNE(!n$26, false); [line 119, column 12]\n " shape="invhouse"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_6" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_8" ;
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_7" [label="7: ConditionalStmt Branch \n *&0$?%__sil_tmpSIL_temp_conditional___n$30:NSBundle*=n$29 [line 119, column 12]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_7" [label="7: ConditionalStmt Branch \n *&0$?%__sil_tmpSIL_temp_conditional___n$27:NSBundle*=n$26 [line 119, column 12]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_7" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_4" ;
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_8" [label="8: ConditionalStmt Branch \n n$31=_fun_NSBundle.mainBundle() [line 119, column 59]\n *&0$?%__sil_tmpSIL_temp_conditional___n$30:NSBundle*=n$31 [line 119, column 12]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_8" [label="8: ConditionalStmt Branch \n n$28=_fun_NSBundle.mainBundle() [line 119, column 59]\n *&0$?%__sil_tmpSIL_temp_conditional___n$27:NSBundle*=n$28 [line 119, column 12]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_8" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_4" ;
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_9" [label="9: BinaryConditionalStmt Init \n n$28=*&stringsBundlePath:NSString* [line 119, column 37]\n n$29=_fun_NSBundle.bundleWithPath:(n$28:NSString*) [line 119, column 12]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_9" [label="9: BinaryConditionalStmt Init \n n$25=*&stringsBundlePath:NSString* [line 119, column 37]\n n$26=_fun_NSBundle.bundleWithPath:(n$25:NSString*) [line 119, column 12]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_9" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_5" ;
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_9" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_6" ;
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_10" [label="10: BinaryOperatorStmt: Assign \n n$32=*&0$?%__sil_tmpSIL_temp_conditional___n$30:NSBundle* [line 119, column 12]\n *&#GB<codetoanalyze/objc/frontend/self_static/Self.m>$A.class_method_fst_arg_of_class_method_inside_instance_method.bundle:NSBundle*=n$32 [line 119, column 3]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_10" [label="10: BinaryOperatorStmt: Assign \n n$29=*&0$?%__sil_tmpSIL_temp_conditional___n$27:NSBundle* [line 119, column 12]\n *&#GB<codetoanalyze/objc/frontend/self_static/Self.m>$A.class_method_fst_arg_of_class_method_inside_instance_method.bundle:NSBundle*=n$29 [line 119, column 3]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_10" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_3" ;
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_11" [label="11: DeclStmt \n VARIABLE_DECLARED(stringsBundlePath:NSString*); [line 116, column 3]\n n$35=_fun_NSBundle.bundleForClass:(sizeof(t=B):unsigned long) [line 117, column 8]\n n$33=_fun_NSString.stringWithUTF8String:(\"Strings\":char* const ) [line 117, column 60]\n n$34=_fun_NSString.stringWithUTF8String:(\"bundle\":char* const ) [line 118, column 60]\n n$36=_fun_NSBundle.pathForResource:ofType:(n$35:NSBundle*,n$33:NSString*,n$34:NSString*) virtual [line 117, column 7]\n *&stringsBundlePath:NSString*=n$36 [line 116, column 3]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_11" [label="11: DeclStmt \n VARIABLE_DECLARED(stringsBundlePath:NSString*); [line 116, column 3]\n n$32=_fun_NSBundle.bundleForClass:(sizeof(t=B):unsigned long) [line 117, column 8]\n n$30=_fun_NSString.stringWithUTF8String:(\"Strings\":char* const ) [line 117, column 60]\n n$31=_fun_NSString.stringWithUTF8String:(\"bundle\":char* const ) [line 118, column 60]\n n$33=_fun_NSBundle.pathForResource:ofType:(n$32:NSBundle*,n$30:NSString*,n$31:NSString*) virtual [line 117, column 7]\n *&stringsBundlePath:NSString*=n$33 [line 116, column 3]\n " shape="box"]
"class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_11" -> "class_method_fst_arg_of_class_method_inside_instance_method#A#class.7bda69c598fb7e024d776cec3122e2a6_9" ;
@ -131,16 +131,16 @@ digraph cfg {
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_4" -> "used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_2" ;
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_5" [label="5: BinaryOperatorStmt: NE \n n$23=*sizeof(t=A):objc_class* [line 94, column 7]\n n$24=*&c:objc_class* [line 94, column 15]\n " shape="box"]
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_5" [label="5: BinaryOperatorStmt: NE \n n$20=*sizeof(t=A):objc_class* [line 94, column 7]\n n$21=*&c:objc_class* [line 94, column 15]\n " shape="box"]
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_5" -> "used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_6" ;
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_5" -> "used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_7" ;
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_6" [label="6: Prune (true branch, if) \n PRUNE((n$23 != n$24), true); [line 94, column 7]\n " shape="invhouse"]
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_6" [label="6: Prune (true branch, if) \n PRUNE((n$20 != n$21), true); [line 94, column 7]\n " shape="invhouse"]
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_6" -> "used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_8" ;
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_7" [label="7: Prune (false branch, if) \n PRUNE(!(n$23 != n$24), false); [line 94, column 7]\n " shape="invhouse"]
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_7" [label="7: Prune (false branch, if) \n PRUNE(!(n$20 != n$21), false); [line 94, column 7]\n " shape="invhouse"]
"used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_7" -> "used_in_binary_op:#A(struct objc_class)#class.da9fc6494d494952f5246c6cf4478263_9" ;
@ -159,7 +159,7 @@ digraph cfg {
"call_alloc_instance#A#instance.70a20314d55f22fb46408deb70d9aabb_2" [label="2: Exit A.call_alloc_instance \n " color=yellow style=filled]
"call_alloc_instance#A#instance.70a20314d55f22fb46408deb70d9aabb_3" [label="3: Call alloc \n n$7=_fun___objc_alloc_no_fail(sizeof(t=A):unsigned long) [line 61, column 3]\n " shape="box"]
"call_alloc_instance#A#instance.70a20314d55f22fb46408deb70d9aabb_3" [label="3: Call alloc \n n$6=_fun___objc_alloc_no_fail(sizeof(t=A):unsigned long) [line 61, column 3]\n " shape="box"]
"call_alloc_instance#A#instance.70a20314d55f22fb46408deb70d9aabb_3" -> "call_alloc_instance#A#instance.70a20314d55f22fb46408deb70d9aabb_2" ;
@ -170,7 +170,7 @@ digraph cfg {
"call_class_instance#A#instance.eb1ae02cd94582eb1fc7cb426794f9f0_2" [label="2: Exit A.call_class_instance \n " color=yellow style=filled]
"call_class_instance#A#instance.eb1ae02cd94582eb1fc7cb426794f9f0_3" [label="3: Message Call: test_class \n n$9=_fun_C.test_class() [line 65, column 3]\n " shape="box"]
"call_class_instance#A#instance.eb1ae02cd94582eb1fc7cb426794f9f0_3" [label="3: Message Call: test_class \n n$7=_fun_C.test_class() [line 65, column 3]\n " shape="box"]
"call_class_instance#A#instance.eb1ae02cd94582eb1fc7cb426794f9f0_3" -> "call_class_instance#A#instance.eb1ae02cd94582eb1fc7cb426794f9f0_2" ;
@ -181,7 +181,7 @@ digraph cfg {
"call_class_instance_with_class_name#A#instance.1baf88c0fb5549c04909fab0bed63c39_2" [label="2: Exit A.call_class_instance_with_class_name \n " color=yellow style=filled]
"call_class_instance_with_class_name#A#instance.1baf88c0fb5549c04909fab0bed63c39_3" [label="3: Message Call: test_class \n n$10=_fun_A.test_class() [line 69, column 3]\n " shape="box"]
"call_class_instance_with_class_name#A#instance.1baf88c0fb5549c04909fab0bed63c39_3" [label="3: Message Call: test_class \n n$8=_fun_A.test_class() [line 69, column 3]\n " shape="box"]
"call_class_instance_with_class_name#A#instance.1baf88c0fb5549c04909fab0bed63c39_3" -> "call_class_instance_with_class_name#A#instance.1baf88c0fb5549c04909fab0bed63c39_2" ;
@ -203,7 +203,7 @@ digraph cfg {
"class_method_fst_arg_of_class_method#A#instance.cf9f3087f45649c74ef1f7ca002450f2_2" [label="2: Exit A.class_method_fst_arg_of_class_method \n " color=yellow style=filled]
"class_method_fst_arg_of_class_method#A#instance.cf9f3087f45649c74ef1f7ca002450f2_3" [label="3: Return Stmt \n n$26=_fun_NSBundle.bundleForClass:(sizeof(t=A):unsigned long) [line 111, column 10]\n *&return:NSBundle*=n$26 [line 111, column 3]\n " shape="box"]
"class_method_fst_arg_of_class_method#A#instance.cf9f3087f45649c74ef1f7ca002450f2_3" [label="3: Return Stmt \n n$23=_fun_NSBundle.bundleForClass:(sizeof(t=A):unsigned long) [line 111, column 10]\n *&return:NSBundle*=n$23 [line 111, column 3]\n " shape="box"]
"class_method_fst_arg_of_class_method#A#instance.cf9f3087f45649c74ef1f7ca002450f2_3" -> "class_method_fst_arg_of_class_method#A#instance.cf9f3087f45649c74ef1f7ca002450f2_2" ;
@ -225,7 +225,7 @@ digraph cfg {
"init#A#instance.eee79aaaddd644404e17691a7e7d809a_2" [label="2: Exit A.init \n " color=yellow style=filled]
"init#A#instance.eee79aaaddd644404e17691a7e7d809a_3" [label="3: Message Call: init \n n$19=*&self:A* [line 86, column 3]\n n$20=_fun_NSObject.init(n$19:A*) [line 86, column 3]\n " shape="box"]
"init#A#instance.eee79aaaddd644404e17691a7e7d809a_3" [label="3: Message Call: init \n n$16=*&self:A* [line 86, column 3]\n n$17=_fun_NSObject.init(n$16:A*) [line 86, column 3]\n " shape="box"]
"init#A#instance.eee79aaaddd644404e17691a7e7d809a_3" -> "init#A#instance.eee79aaaddd644404e17691a7e7d809a_2" ;
@ -236,7 +236,7 @@ digraph cfg {
"loggerName#A#instance.36b9a42412bcf7d8d3f8397eb2bcb555_2" [label="2: Exit A.loggerName \n " color=yellow style=filled]
"loggerName#A#instance.36b9a42412bcf7d8d3f8397eb2bcb555_3" [label="3: Return Stmt \n n$22=_fun_NSStringFromClass(sizeof(t=A):unsigned long) [line 90, column 10]\n *&return:NSString*=n$22 [line 90, column 3]\n " shape="box"]
"loggerName#A#instance.36b9a42412bcf7d8d3f8397eb2bcb555_3" [label="3: Return Stmt \n n$19=_fun_NSStringFromClass(sizeof(t=A):unsigned long) [line 90, column 10]\n *&return:NSString*=n$19 [line 90, column 3]\n " shape="box"]
"loggerName#A#instance.36b9a42412bcf7d8d3f8397eb2bcb555_3" -> "loggerName#A#instance.36b9a42412bcf7d8d3f8397eb2bcb555_2" ;
@ -247,11 +247,11 @@ digraph cfg {
"t#A#instance.e31b9a7bced712626784e2860af1a31b_2" [label="2: Exit A.t \n " color=yellow style=filled]
"t#A#instance.e31b9a7bced712626784e2860af1a31b_3" [label="3: Message Call: b_m \n n$12=_fun_B.b_m() [line 74, column 3]\n " shape="box"]
"t#A#instance.e31b9a7bced712626784e2860af1a31b_3" [label="3: Message Call: b_m \n n$9=_fun_B.b_m() [line 74, column 3]\n " shape="box"]
"t#A#instance.e31b9a7bced712626784e2860af1a31b_3" -> "t#A#instance.e31b9a7bced712626784e2860af1a31b_2" ;
"t#A#instance.e31b9a7bced712626784e2860af1a31b_4" [label="4: DeclStmt \n VARIABLE_DECLARED(b:B*); [line 73, column 3]\n n$13=_fun___objc_alloc_no_fail(sizeof(t=B):unsigned long) [line 73, column 10]\n n$14=_fun_NSObject.init(n$13:B*) virtual [line 73, column 10]\n *&b:B*=n$14 [line 73, column 3]\n " shape="box"]
"t#A#instance.e31b9a7bced712626784e2860af1a31b_4" [label="4: DeclStmt \n VARIABLE_DECLARED(b:B*); [line 73, column 3]\n n$10=_fun___objc_alloc_no_fail(sizeof(t=B):unsigned long) [line 73, column 10]\n n$11=_fun_NSObject.init(n$10:B*) virtual [line 73, column 10]\n *&b:B*=n$11 [line 73, column 3]\n " shape="box"]
"t#A#instance.e31b9a7bced712626784e2860af1a31b_4" -> "t#A#instance.e31b9a7bced712626784e2860af1a31b_3" ;
@ -269,7 +269,7 @@ digraph cfg {
"use_class_in_other_ways:#A(class B)#instance.7a96604c2c855db834d214f72f83a306_2" [label="2: Exit A.use_class_in_other_ways: \n " color=yellow style=filled]
"use_class_in_other_ways:#A(class B)#instance.7a96604c2c855db834d214f72f83a306_3" [label="3: Return Stmt \n n$16=*&object:B* [line 78, column 11]\n n$17=_fun_B.isC:(n$16:B*,sizeof(t=A):unsigned long) virtual [line 78, column 10]\n *&return:_Bool=n$17 [line 78, column 3]\n " shape="box"]
"use_class_in_other_ways:#A(class B)#instance.7a96604c2c855db834d214f72f83a306_3" [label="3: Return Stmt \n n$13=*&object:B* [line 78, column 11]\n n$14=_fun_B.isC:(n$13:B*,sizeof(t=A):unsigned long) virtual [line 78, column 10]\n *&return:_Bool=n$14 [line 78, column 3]\n " shape="box"]
"use_class_in_other_ways:#A(class B)#instance.7a96604c2c855db834d214f72f83a306_3" -> "use_class_in_other_ways:#A(class B)#instance.7a96604c2c855db834d214f72f83a306_2" ;

@ -123,3 +123,14 @@ NSString* string_by_appending_path_component_linear(NSString* path,
bool string_has_prefix_linear(NSString* str, NSString* prefix) {
return [str hasPrefix:prefix];
}
@interface DummyClass : NSObject
@end
@implementation DummyClass
+ (void)call_string_by_appending_string_constant_FP {
NSString* s = [NSStringFromClass(self) stringByAppendingString:@"abc"];
}
@end

@ -81,6 +81,8 @@ codetoanalyze/objc/performance/NSSet.m, nsset_init_with_array_linear, 7 + 3 ⋅
codetoanalyze/objc/performance/NSSet.m, nsset_init_with_set_constant, 6, OnUIThread:false, []
codetoanalyze/objc/performance/NSSet.m, nsset_iterate_linear, 6 + 8 ⋅ (set->elements.length.ub + 1), OnUIThread:false, [{set->elements.length.ub + 1},Loop]
codetoanalyze/objc/performance/NSSet.m, nsset_next_object_linear, 5 + 5 ⋅ (set->elements.length.ub + 1), OnUIThread:false, [{set->elements.length.ub + 1},Loop]
codetoanalyze/objc/performance/NSString.m, DummyClass.call_string_by_appending_string_constant_FP, , OnUIThread:false, [Unbounded loop,Modeled call to NSString.stringByAppendingString:]
codetoanalyze/objc/performance/NSString.m, DummyClass.dealloc, 1, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, call_component_separated_by_char_constant, 46, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, call_init_with_string_constant, 15, OnUIThread:false, []
codetoanalyze/objc/performance/NSString.m, component_seperated_by_char_linear, 6 + m.length.ub + 3 ⋅ (-1+max(2, m.length.ub)) + 3 ⋅ (max(2, m.length.ub)), OnUIThread:false, [{max(2, m.length.ub)},Loop,{-1+max(2, m.length.ub)},Loop,{m.length.ub},Modeled call to NSString.componentsSeparatedByString:]

@ -12,6 +12,7 @@ codetoanalyze/objc/performance/NSMutableArray.m, nsmarray_set_linear, 2, INTEGER
codetoanalyze/objc/performance/NSSet.m, nsset_enumerator_linear, 7, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [<LHS trace>,Assignment,<RHS trace>,Assignment,Binary operation: ([0, +oo] + [1, set->elements.length.ub + 1]):signed64]
codetoanalyze/objc/performance/NSSet.m, nsset_init_constant, 3, CONDITION_ALWAYS_FALSE, no_bucket, WARNING, [Here]
codetoanalyze/objc/performance/NSSet.m, nsset_iterate_linear, 3, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [<LHS trace>,Assignment,<RHS trace>,Assignment,Binary operation: ([0, +oo] + [1, set->elements.length.ub + 1]):signed64]
codetoanalyze/objc/performance/NSString.m, DummyClass.call_string_by_appending_string_constant_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Modeled call to NSString.stringByAppendingString:]
codetoanalyze/objc/performance/NSString.m, init_string_constant, 2, CONDITION_ALWAYS_FALSE, no_bucket, WARNING, [Here]
codetoanalyze/objc/performance/NSString.m, replace_linear_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSString.m, replace_linear_FP, 2, INTEGER_OVERFLOW_U5, no_bucket, ERROR, [<LHS trace>,Unknown value from: NSString.stringByReplacingOccurrencesOfString:withString:,Binary operation: ([0, +oo] + 1):signed32]

Loading…
Cancel
Save