[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 5 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 in
let return = let return =
if Self.is_var_self pvar (CContext.is_objc_method context) && CType.is_class typ then 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 sizeof_expr_class (CContext.get_curr_class_typename stmt_info context)
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
else (var_exp, typ) else (var_exp, typ)
in in
L.(debug Capture Verbose) "@\n@\n PVAR ='%s'@\n@\n" (Pvar.to_string pvar) ; 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 CMethod_trans.get_class_name_method_call_from_receiver_kind context obj_c_message_expr_info
act_params act_params
in in
if trans_state.is_fst_arg_objc_instance_method_call && is_receiver_instance receiver_kind then Some (mk_trans_result (sizeof_expr_class class_name) empty_control)
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)
else if else if
(* alloc or new *) (* alloc or new *)
String.equal selector CFrontend_config.alloc 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 = let param_trans_results =
List.mapi ~f:(exec_instruction_with_trans_state trans_state_param callee_ms_opt) rest List.mapi ~f:(exec_instruction_with_trans_state trans_state_param callee_ms_opt) rest
in in
try
let trans_state_param' = let trans_state_param' =
if is_receiver_instance obj_c_message_expr_info.Clang_ast_t.omei_receiver_kind then { trans_state_param with
{trans_state_param with is_fst_arg_objc_instance_method_call= true} is_fst_arg_objc_instance_method_call=
else {trans_state_param with is_fst_arg_objc_instance_method_call= false} is_receiver_instance obj_c_message_expr_info.Clang_ast_t.omei_receiver_kind }
in in
let fst_res_trans = match CTrans_utils.should_remove_first_param trans_state_param' stmt with
exec_instruction_with_trans_state trans_state_param' callee_ms_opt 0 stmt | Some class_name ->
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 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 selector = obj_c_message_expr_info.Clang_ast_t.omei_selector in
let obj_c_message_expr_info = let obj_c_message_expr_info =
Ast_expressions.make_obj_c_message_expr_info_class selector e.class_name pointer 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 in
(obj_c_message_expr_info, param_trans_results) ) (obj_c_message_expr_info, fst_res_trans :: param_trans_results) )
| [] -> | [] ->
(obj_c_message_expr_info, []) (obj_c_message_expr_info, [])

@ -581,10 +581,6 @@ let extract_stmt_from_singleton stmt_list source_range warning_string =
module Self = struct 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 = let add_self_parameter_for_super_instance stmt_info context procname loc mei =
if is_superinstance mei then if is_superinstance mei then
let typ, self_expr, instrs = let typ, self_expr, instrs =
@ -644,3 +640,33 @@ let last_or_mk_fresh_void_exp_typ exp_typs =
last_exp_typ last_exp_typ
| None -> | None ->
mk_fresh_void_exp_typ () 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 (** 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. *) used both as a variable in instance method calls and also as a type in class method calls. *)
module Self : sig 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 : val add_self_parameter_for_super_instance :
Clang_ast_t.stmt_info Clang_ast_t.stmt_info
-> CContext.t -> 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 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 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_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" ; "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_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_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" ; "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_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_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_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_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_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_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_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_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" ; "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_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_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_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_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" ; "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_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" ; "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_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" ; "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_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" ; "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_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" ; "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_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" ; "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_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" ; "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_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_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" ; "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_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" ; "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) { bool string_has_prefix_linear(NSString* str, NSString* prefix) {
return [str hasPrefix: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_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_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/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_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, 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:] 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_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_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/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, 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, 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] 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