From c67f3d5753db08e06faa9b2b78106c40cc1f04c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezgi=20=C3=87i=C3=A7ek?= Date: Fri, 12 Mar 2021 02:55:59 -0800 Subject: [PATCH] [objc] Suppress block counter when getting method name Summary: We use `procedure_name` which is coming from `Procname.get_method` in explanation of cost issues. For blocks, procedure name includes a prefix `objc_block` and a suffix with `_x` where x is the block counter. However, displaying this name to the user is not pretty. Especially when we have nested blocks, procedure name looks like `objc_blockobjc_blockdirectUIMessageFromContentAndMetadata_10_23`. This diff drops the block index suffix and replaces `objc_block` with a prettier version `^`(signifying block). so instead, in the cost report, we will have `^^blockdirectUIMessageFromContentAndMetadata`. Reviewed By: skcho Differential Revision: D26945333 fbshipit-source-id: 9d135423c --- infer/src/IR/Procname.ml | 50 +++++++++++++++---- infer/src/IR/Procname.mli | 13 +++-- infer/src/clang/CType_decl.ml | 14 +++--- .../introduced.exp | 2 +- .../objc/frontend/block/static.m.dot | 22 ++++---- .../objc/shared/block/block.m.dot | 30 +++++------ 6 files changed, 85 insertions(+), 46 deletions(-) diff --git a/infer/src/IR/Procname.ml b/infer/src/IR/Procname.ml index 032e90a4f..81dc5df97 100644 --- a/infer/src/IR/Procname.ml +++ b/infer/src/IR/Procname.ml @@ -466,21 +466,44 @@ end module Block = struct (** Type of Objective C block names. *) - type block_name = string [@@deriving compare, yojson_of] + type block_type = + | InOuterScope of {outer_scope: block_type; block_index: int} + | SurroundingProc of {name: string} + [@@deriving compare, yojson_of] - type t = {name: block_name; parameters: Parameter.clang_parameter list} + type t = {block_type: block_type; parameters: Parameter.clang_parameter list} [@@deriving compare, yojson_of] - let make name parameters = {name; parameters} + let make_surrounding name parameters = {block_type= SurroundingProc {name}; parameters} + + let make_in_outer_scope outer_scope block_index parameters = + {block_type= InOuterScope {outer_scope; block_index}; parameters} + + + let pp_block_type fmt ~with_prefix_and_index = + let prefix = if with_prefix_and_index then Config.anonymous_block_prefix else "^" in + let pp_index fmt index = + if with_prefix_and_index then F.fprintf fmt "%s%d" Config.anonymous_block_num_sep index + in + let rec aux fmt proc = + match proc with + | SurroundingProc {name} -> + F.pp_print_string fmt name + | InOuterScope {outer_scope; block_index} -> + F.fprintf fmt "%s%a%a" prefix aux outer_scope pp_index block_index + in + aux fmt + let pp verbosity fmt bsig = + let pp_block = pp_block_type ~with_prefix_and_index:true in match verbosity with | Simple -> F.pp_print_string fmt "block" | Non_verbose -> - F.pp_print_string fmt bsig.name + pp_block fmt bsig.block_type | Verbose -> - F.fprintf fmt "%s%a" bsig.name Parameter.pp_parameters bsig.parameters + F.fprintf fmt "%a%a" pp_block bsig.block_type Parameter.pp_parameters bsig.parameters let get_parameters block = block.parameters @@ -549,7 +572,7 @@ let block_of_procname procname = Logging.die InternalError "Only to be called with Objective-C block names" -let empty_block = Block {name= ""; parameters= []} +let empty_block = Block (Block.make_surrounding "" []) (** Replace the class name component of a procedure name. In case of Java, replace package and class name. *) @@ -603,7 +626,8 @@ let rec objc_cpp_replace_method_name t (new_method_name : string) = t -(** Return the method/function of a procname. *) +(** Return the method/function of a procname. For Blocks, we don't display objc_block prefix or + block index suffix. *) let rec get_method = function | ObjC_Cpp name -> name.method_name @@ -611,8 +635,8 @@ let rec get_method = function get_method base | C {name} -> QualifiedCppName.to_qual_string name - | Block {name} -> - name + | Block {block_type} -> + F.asprintf "%a" (Block.pp_block_type ~with_prefix_and_index:false) block_type | Java j -> j.method_name | CSharp cs -> @@ -737,6 +761,14 @@ let rec pp fmt = function let to_string proc_name = F.asprintf "%a" pp proc_name +let get_block_type proc = + match proc with + | Block {block_type} -> + block_type + | _ -> + Block.SurroundingProc {name= to_string proc} + + (** Convenient representation of a procname for external tools (e.g. eclipse plugin) *) let rec pp_simplified_string ?(withclass = false) fmt = function | Java j -> diff --git a/infer/src/IR/Procname.mli b/infer/src/IR/Procname.mli index 252ef7e82..508896e1b 100644 --- a/infer/src/IR/Procname.mli +++ b/infer/src/IR/Procname.mli @@ -200,11 +200,16 @@ end module Block : sig (** Type of Objective C block names. *) - type block_name = string + type block_type = + | InOuterScope of {outer_scope: block_type; block_index: int} + (** a block nested in the scope of an outer one *) + | SurroundingProc of {name: string} (** tracks the name of the surrounding proc *) - type t = {name: block_name; parameters: Parameter.clang_parameter list} [@@deriving compare] + type t = {block_type: block_type; parameters: Parameter.clang_parameter list} [@@deriving compare] - val make : block_name -> Parameter.clang_parameter list -> t + val make_surrounding : string -> Parameter.clang_parameter list -> t + + val make_in_outer_scope : block_type -> int -> Parameter.clang_parameter list -> t end (** Type of procedure names. WithBlockParameters is used for creating an instantiation of a method @@ -304,6 +309,8 @@ val make_objc_copyWithZone : is_mutable:bool -> Typ.Name.t -> t val empty_block : t (** Empty block name. *) +val get_block_type : t -> Block.block_type + val get_language : t -> Language.t (** Return the language of the procedure. *) diff --git a/infer/src/clang/CType_decl.ml b/infer/src/clang/CType_decl.ml index d97931738..7d9216fdd 100644 --- a/infer/src/clang/CType_decl.ml +++ b/infer/src/clang/CType_decl.ml @@ -640,13 +640,13 @@ and objc_method_procname ?tenv decl_info method_name mdi = and objc_block_procname outer_proc_opt parameters = - let outer_proc_string = Option.value_map ~f:Procname.to_string outer_proc_opt ~default:"" in - let block_procname_with_index i = - Printf.sprintf "%s%s%s%d" Config.anonymous_block_prefix outer_proc_string - Config.anonymous_block_num_sep i + let block_type = + Option.value_map ~f:Procname.get_block_type outer_proc_opt + ~default:(Procname.Block.SurroundingProc {name= ""}) in - let name = block_procname_with_index (CFrontend_config.get_fresh_block_index ()) in - Procname.Block (Procname.Block.make name parameters) + let block_index = CFrontend_config.get_fresh_block_index () in + let block = Procname.Block.make_in_outer_scope block_type block_index parameters in + Procname.Block block and procname_from_decl ?tenv ?block_return_type ?outer_proc meth_decl = @@ -785,7 +785,7 @@ module CProcname = struct in objc_method_procname decl_info method_name mdi [] | BlockDecl _ -> - Procname.Block (Procname.Block.make Config.anonymous_block_prefix []) + Procname.Block (Procname.Block.make_surrounding Config.anonymous_block_prefix []) | _ -> from_decl method_decl end diff --git a/infer/tests/build_systems/differential_of_costs_report_objc/introduced.exp b/infer/tests/build_systems/differential_of_costs_report_objc/introduced.exp index cd88bf1fa..e151c2918 100644 --- a/infer/tests/build_systems/differential_of_costs_report_objc/introduced.exp +++ b/infer/tests/build_systems/differential_of_costs_report_objc/introduced.exp @@ -1,3 +1,3 @@ EXECUTION_TIME_COMPLEXITY_INCREASE, no_bucket, src/DiffBlock.m, CallBlocks.take_two_blocks:block1:block2:[objc_blockHandler.create_block_here:array:call:_2^objc_blockHandler.create_block_here:array:call:_3], 0, [Previous Cost of take_two_blocks:block1:block2: is 6 (degree is 0),Updated Cost of take_two_blocks:block1:block2: is 22 + 9 ⋅ (array[create_block_here:array:call:]->elements.length + 1) (degree is 1),{array[create_block_here:array:call:]->elements.length + 1},Call to objc_blockHandler.create_block_here:array:call:_2,Loop] EXECUTION_TIME_COMPLEXITY_INCREASE, no_bucket, src/DiffBlock.m, Handler.func_linear:, 0, [Previous Cost of func_linear: is 4 + 5 ⋅ (array->elements.length + 1) (degree is 1),{array->elements.length + 1},Loop,Updated Cost of func_linear: is 4 + 3 ⋅ array->elements.length × (array->elements.length + 1) + 8 ⋅ (array->elements.length + 1) + 3 ⋅ (array->elements.length + 1) × (array->elements.length + 1) (degree is 2),{array->elements.length + 1},Loop,{array->elements.length},Call to Handler.loop_linear:,Loop] -EXECUTION_TIME_COMPLEXITY_INCREASE, no_bucket, src/DiffBlock.m, objc_blockHandler.func_linear_1, 0, [Previous Cost of objc_blockHandler.func_linear_1 is 21 (degree is 0),Updated Cost of objc_blockHandler.func_linear_1 is 23 + 3 ⋅ str.length + 3 ⋅ (str.length + 1) (degree is 1),{str.length},Loop] +EXECUTION_TIME_COMPLEXITY_INCREASE, no_bucket, src/DiffBlock.m, objc_blockHandler.func_linear_1, 0, [Previous Cost of ^Handler.func_linear is 21 (degree is 0),Updated Cost of ^Handler.func_linear is 23 + 3 ⋅ str.length + 3 ⋅ (str.length + 1) (degree is 1),{str.length},Loop] diff --git a/infer/tests/codetoanalyze/objc/frontend/block/static.m.dot b/infer/tests/codetoanalyze/objc/frontend/block/static.m.dot index e7aeb2edb..deab4d4d0 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/static.m.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/static.m.dot @@ -11,6 +11,17 @@ digraph cfg { "main.fad58de7366495db4650cfefac2fcd61_3" -> "main.fad58de7366495db4650cfefac2fcd61_2" ; +"objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_1" [label="1: Start objc_blockA.test_1\nFormals: \nLocals: \n " color=yellow style=filled] + + + "objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_1" -> "objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_3" ; +"objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_2" [label="2: Exit objc_blockA.test_1 \n " color=yellow style=filled] + + +"objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_3" [label="3: BinaryOperatorStmt: Assign \n n$1=_fun___objc_alloc_no_fail(sizeof(t=A):unsigned long) [line 19, column 23]\n n$2=_fun_NSObject.init(n$1:A*) virtual [line 19, column 22]\n *&#GB$A.test.sharedInstance:objc_object*=n$2 [line 19, column 5]\n " shape="box"] + + + "objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_3" -> "objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_2" ; "objc_blockA.test2_3.9e734e5048a7cd48cace952a9e183154_1" [label="1: Start objc_blockA.test2_3\nFormals: \nLocals: p:objc_object* \n " color=yellow style=filled] @@ -33,17 +44,6 @@ digraph cfg { "objc_blockA.test3_4.cf509a07e14b642d4e78e323de50d37f_3" -> "objc_blockA.test3_4.cf509a07e14b642d4e78e323de50d37f_2" ; -"objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_1" [label="1: Start objc_blockA.test_1\nFormals: \nLocals: \n " color=yellow style=filled] - - - "objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_1" -> "objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_3" ; -"objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_2" [label="2: Exit objc_blockA.test_1 \n " color=yellow style=filled] - - -"objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_3" [label="3: BinaryOperatorStmt: Assign \n n$1=_fun___objc_alloc_no_fail(sizeof(t=A):unsigned long) [line 19, column 23]\n n$2=_fun_NSObject.init(n$1:A*) virtual [line 19, column 22]\n *&#GB$A.test.sharedInstance:objc_object*=n$2 [line 19, column 5]\n " shape="box"] - - - "objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_3" -> "objc_blockA.test_1.78a4922219b515f90379bfccc4d8771a_2" ; "objc_blockA.test_leak_2.283de372da56cae6e3edcf8db6c39b92_1" [label="1: Start objc_blockA.test_leak_2\nFormals: \nLocals: \n " color=yellow style=filled] diff --git a/infer/tests/codetoanalyze/objc/shared/block/block.m.dot b/infer/tests/codetoanalyze/objc/shared/block/block.m.dot index bef826d46..8d5eb55cf 100644 --- a/infer/tests/codetoanalyze/objc/shared/block/block.m.dot +++ b/infer/tests/codetoanalyze/objc/shared/block/block.m.dot @@ -58,6 +58,21 @@ digraph cfg { "main1.38f534a9576db7ec6ebcbca8c111f942_11" -> "main1.38f534a9576db7ec6ebcbca8c111f942_10" ; +"objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_1" [label="1: Start objc_blockobjc_blockmain1_2_3\nFormals: x:int bla:int z:int\nLocals: \nCaptured: [by value]x:int [by value]bla:int \n " color=yellow style=filled] + + + "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_1" -> "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_3" ; +"objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_2" [label="2: Exit objc_blockobjc_blockmain1_2_3 \n " color=yellow style=filled] + + +"objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_3" [label="3: Return Stmt \n n$17=*&z:int [line 22, column 14]\n n$18=*&#GB$main1.s:int [line 22, column 18]\n n$19=*&x:int [line 22, column 22]\n n$20=*&bla:int [line 22, column 26]\n " shape="box"] + + + "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_3" -> "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_4" ; +"objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_4" [label="4: Return Stmt \n *&return:int=(((n$17 + n$18) + n$19) + n$20) [line 22, column 7]\n " shape="box"] + + + "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_4" -> "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_2" ; "objc_blockmain1_1.74199543de3b6a9a736f23ef5e45586a_1" [label="1: Start objc_blockmain1_1\nFormals: e:int f:int\nLocals: \n " color=yellow style=filled] @@ -100,19 +115,4 @@ digraph cfg { "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_7" -> "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_6" ; -"objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_1" [label="1: Start objc_blockobjc_blockmain1_2_3\nFormals: x:int bla:int z:int\nLocals: \nCaptured: [by value]x:int [by value]bla:int \n " color=yellow style=filled] - - - "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_1" -> "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_3" ; -"objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_2" [label="2: Exit objc_blockobjc_blockmain1_2_3 \n " color=yellow style=filled] - - -"objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_3" [label="3: Return Stmt \n n$17=*&z:int [line 22, column 14]\n n$18=*&#GB$main1.s:int [line 22, column 18]\n n$19=*&x:int [line 22, column 22]\n n$20=*&bla:int [line 22, column 26]\n " shape="box"] - - - "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_3" -> "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_4" ; -"objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_4" [label="4: Return Stmt \n *&return:int=(((n$17 + n$18) + n$19) + n$20) [line 22, column 7]\n " shape="box"] - - - "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_4" -> "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_2" ; }