From 054ad223a83d34fe3b79cd7735f2e8e9e5738f44 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Thu, 14 Apr 2016 09:20:44 -0700 Subject: [PATCH] Fix control-flow graph shape when conditional is last instruction. Summary:public When a conditional is the last instruction, there will be a join node leading directly to the exit node. Some instructions, such as nullification of dead variables, and abstraction, are added to the control flow graph automatically. But, join nodes cannot contain instructions. So when a procedure ends with a conditional, there might be no place to store these instructions. This diff adds one extra node between the join and the exit node in that situation. Reviewed By: jvillard Differential Revision: D3179056 fb-gh-sync-id: 2b9cd7e fbshipit-source-id: 2b9cd7e --- infer/src/IR/cfg.ml | 35 +- infer/src/IR/cfg.mli | 2 +- infer/src/clang/cFrontend_decl.ml | 2 +- infer/src/clang/cMethod_trans.ml | 2 +- infer/src/clang/cTrans.ml | 53 +-- infer/src/clang/cTrans_utils.ml | 15 +- infer/src/clang/cTrans_utils.mli | 2 +- infer/src/harness/inhabit.ml | 4 +- infer/src/java/jFrontend.ml | 21 +- infer/src/java/jTrans.ml | 2 +- infer/src/java/jTransExn.ml | 6 +- infer/src/llvm/lTrans.ml | 6 +- infer/src/unit/analyzerTester.ml | 2 +- .../c/errors/memory_leaks/test.c | 7 + .../conditional_operator/array_access.c.dot | 66 +-- .../if_short_circuit.c.dot | 382 +++++++++--------- .../conditional_operator/int_negation.c.dot | 112 ++--- .../c/frontend/enumeration/other_enum.c.dot | 34 +- .../var_decl_inside_if.cpp.dot | 282 +++++++------ .../reference/reference_struct_e2e.cpp.dot | 266 ++++++------ .../cpp/frontend/types/typeid_expr.cpp.dot | 214 +++++----- .../RetainReleaseExample2.dot | 20 +- .../objc/frontend/block/BlockVar.dot | 168 ++++---- .../objc/frontend/block/block-it.dot | 138 ++++--- .../objc/frontend/block/block_no_args.dot | 54 +-- .../objc/frontend/block/block_release.dot | 34 +- .../objc/frontend/block/dispatch.dot | 34 +- .../frontend/exceptions/ExceptionExample.dot | 28 +- .../objc/frontend/protocol/protocol.dot | 24 +- .../objc/frontend/returnstmt/void_return.dot | 52 +-- .../objc/frontend/self_static/Self.dot | 26 +- infer/tests/endtoend/c/MemoryLeakTest.java | 1 + 32 files changed, 1130 insertions(+), 964 deletions(-) diff --git a/infer/src/IR/cfg.ml b/infer/src/IR/cfg.ml index cb0c793a3..e19ab4d5e 100644 --- a/infer/src/IR/cfg.ml +++ b/infer/src/IR/cfg.ml @@ -246,12 +246,34 @@ module Node = struct let set_proc_desc node proc = node.nd_proc <- Some proc + (** Get the proc desc of the node *) + let get_proc_desc node = + match node.nd_proc with + | None -> + L.out "node_get_proc_desc: at node %d@\n" node.nd_id; + assert false + | Some proc_desc -> proc_desc + (** Set the successor nodes and exception nodes, and build predecessor links *) - let set_succs_exn node succs exn = + let set_succs_exn_base node succs exn = node.nd_succs <- succs; node.nd_exn <- exn; IList.iter (fun n -> n.nd_preds <- (node :: n.nd_preds)) succs + (** Set the successor and exception nodes. + If this is a join node right before the exit node, add an extra node in the middle, + otherwise nullify and abstract instructions cannot be added after a conditional. *) + let set_succs_exn cfg node succs exn = + match node.nd_kind, succs with + | Join_node, [({nd_kind = (Exit_node _)} as exit_node)] -> + let kind = Stmt_node "between_join_and_exit" in + let pdesc = get_proc_desc node in + let node' = create cfg node.nd_loc kind node.nd_instrs pdesc node.nd_temps in + set_succs_exn_base node [node'] exn; + set_succs_exn_base node' [exit_node] exn + | _ -> + set_succs_exn_base node succs exn + (** Get the predecessors of the node *) let get_preds node = node.nd_preds @@ -332,15 +354,6 @@ module Node = struct let pp f node = F.fprintf f "%n" (get_id node) - (** Get the proc desc of the node *) - let get_proc_desc node = - let proc_desc = match node.nd_proc with - | None -> - L.out "node_get_proc_desc: at node %d@\n" node.nd_id; - assert false - | Some proc_desc -> proc_desc in - proc_desc - let proc_desc_from_name cfg proc_name = try Some (pdesc_tbl_find cfg proc_name) with Not_found -> None @@ -733,7 +746,7 @@ module Node = struct proc_desc_set_start_node resolved_proc_desc new_node; if equal node callee_exit_node then proc_desc_set_exit_node resolved_proc_desc new_node; - set_succs_exn new_node (loop successors) (loop exn_nodes); + set_succs_exn cfg new_node (loop successors) (loop exn_nodes); new_node in converted_node :: (loop other_node) in ignore (loop [callee_start_node]); diff --git a/infer/src/IR/cfg.mli b/infer/src/IR/cfg.mli index 5b8e6403b..872395313 100644 --- a/infer/src/IR/cfg.mli +++ b/infer/src/IR/cfg.mli @@ -262,7 +262,7 @@ module Node : sig val set_proc_desc : t -> Procdesc.t -> unit (** Set the successor nodes and exception nodes, and build predecessor links *) - val set_succs_exn : t -> t list -> t list -> unit + val set_succs_exn : cfg -> t -> t list -> t list -> unit (** Set the temporary variables *) val set_temps : t -> Ident.t list -> unit diff --git a/infer/src/clang/cFrontend_decl.ml b/infer/src/clang/cFrontend_decl.ml index a0a98e293..9783bf149 100644 --- a/infer/src/clang/cFrontend_decl.ml +++ b/infer/src/clang/cFrontend_decl.ml @@ -48,7 +48,7 @@ struct (Procname.to_string procname); let meth_body_nodes = T.instructions_trans context body extra_instrs exit_node in Cfg.Node.add_locals_ret_declaration start_node (Cfg.Procdesc.get_locals procdesc); - Cfg.Node.set_succs_exn start_node meth_body_nodes []; + Cfg.Node.set_succs_exn cfg start_node meth_body_nodes []; Cg.add_defined_node (CContext.get_cg context) (Cfg.Procdesc.get_proc_name procdesc)) | None -> ()) with diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index d72fdc109..7800dd431 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -458,7 +458,7 @@ let get_method_for_frontend_checks cfg cg loc = let exit_node = Cfg.Node.create cfg loc (Cfg.Node.Exit_node pdesc) [] pdesc [] in Cfg.Procdesc.set_start_node pdesc start_node; Cfg.Procdesc.set_exit_node pdesc exit_node; - Cfg.Node.set_succs_exn start_node [exit_node] []; + Cfg.Node.set_succs_exn cfg start_node [exit_node] []; Cg.add_defined_node cg proc_name; pdesc diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index b1250f324..5edee143a 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -638,7 +638,7 @@ struct (* create the label root node into the hashtbl *) let sil_loc = CLocation.get_sil_location stmt_info trans_state.context in let root_node' = GotoLabel.find_goto_label trans_state.context label_name sil_loc in - Cfg.Node.set_succs_exn root_node' res_trans.root_nodes []; + Cfg.Node.set_succs_exn trans_state.context.cfg root_node' res_trans.root_nodes []; { empty_res_trans with root_nodes = [root_node']; leaf_nodes = trans_state.succ_nodes } and decl_ref_trans trans_state pre_trans_result stmt_info decl_ref ~is_constructor_init = @@ -732,7 +732,7 @@ struct if res_trans_idx.root_nodes <> [] then IList.iter - (fun n -> Cfg.Node.set_succs_exn n res_trans_idx.root_nodes []) + (fun n -> Cfg.Node.set_succs_exn trans_state.context.cfg n res_trans_idx.root_nodes []) res_trans_a.leaf_nodes; (* Note the order of res_trans_idx.ids @ res_trans_a.ids is important. *) @@ -1121,6 +1121,7 @@ struct and conditionalOperator_trans trans_state stmt_info stmt_list expr_info = let context = trans_state.context in + let cfg = context.cfg in let succ_nodes = trans_state.succ_nodes in let procname = Cfg.Procdesc.get_proc_name context.CContext.procdesc in let mk_temp_var id = @@ -1143,7 +1144,7 @@ struct "ConditinalStmt Branch" stmt_info all_res_trans in let prune_nodes_t, prune_nodes_f = IList.partition is_true_prune_node prune_nodes in let prune_nodes' = if branch then prune_nodes_t else prune_nodes_f in - IList.iter (fun n -> Cfg.Node.set_succs_exn n res_trans.root_nodes []) prune_nodes' in + IList.iter (fun n -> Cfg.Node.set_succs_exn cfg n res_trans.root_nodes []) prune_nodes' in (match stmt_list with | [cond; exp1; exp2] -> let typ = @@ -1151,7 +1152,7 @@ struct context.CContext.tenv expr_info.Clang_ast_t.ei_type_ptr in let var_typ = add_reference_if_glvalue typ expr_info in let join_node = create_node (Cfg.Node.Join_node) [] [] sil_loc context in - Cfg.Node.set_succs_exn join_node succ_nodes []; + Cfg.Node.set_succs_exn cfg join_node succ_nodes []; let pvar = mk_temp_var (Cfg.Node.get_id join_node) in let continuation' = mk_cond_continuation trans_state.continuation in let trans_state' = { trans_state with continuation = continuation'; succ_nodes = [] } in @@ -1201,7 +1202,7 @@ struct let prune_t = mk_prune_node true e' res_trans_cond.ids instrs' in let prune_f = mk_prune_node false e' res_trans_cond.ids instrs' in IList.iter - (fun n' -> Cfg.Node.set_succs_exn n' [prune_t; prune_f] []) + (fun n' -> Cfg.Node.set_succs_exn context.cfg n' [prune_t; prune_f] []) res_trans_cond.leaf_nodes; let rnodes = if (IList.length res_trans_cond.root_nodes) = 0 then [prune_t; prune_f] @@ -1234,7 +1235,9 @@ struct | Sil.LAnd -> prune_nodes_t, prune_nodes_f | Sil.LOr -> prune_nodes_f, prune_nodes_t | _ -> assert false) in - IList.iter (fun n -> Cfg.Node.set_succs_exn n res_trans_s2.root_nodes []) prune_to_s2; + IList.iter + (fun n -> Cfg.Node.set_succs_exn context.cfg n res_trans_s2.root_nodes []) + prune_to_s2; let root_nodes_to_parent = if (IList.length res_trans_s1.root_nodes) = 0 then res_trans_s1.leaf_nodes @@ -1275,7 +1278,7 @@ struct let succ_nodes = trans_state.succ_nodes in let sil_loc = CLocation.get_sil_location stmt_info context in let join_node = create_node (Cfg.Node.Join_node) [] [] sil_loc context in - Cfg.Node.set_succs_exn join_node succ_nodes []; + Cfg.Node.set_succs_exn context.cfg join_node succ_nodes []; let trans_state' = { trans_state with succ_nodes = [join_node] } in let do_branch branch stmt_branch prune_nodes = (* leaf nodes are ignored here as they will be already attached to join_node *) @@ -1289,7 +1292,7 @@ struct res_trans_b.root_nodes) in let prune_nodes_t, prune_nodes_f = IList.partition is_true_prune_node prune_nodes in let prune_nodes' = if branch then prune_nodes_t else prune_nodes_f in - IList.iter (fun n -> Cfg.Node.set_succs_exn n nodes_branch []) prune_nodes'; + IList.iter (fun n -> Cfg.Node.set_succs_exn context.cfg n nodes_branch []) prune_nodes'; res_trans_b.ids in (match stmt_list with | [decl_stmt; cond; stmt1; stmt2] -> @@ -1327,7 +1330,7 @@ struct let node_kind = Cfg.Node.Stmt_node "Switch_stmt" in create_node node_kind [] res_trans_cond_tmp.instrs sil_loc context in IList.iter - (fun n' -> Cfg.Node.set_succs_exn n' [switch_special_cond_node] []) + (fun n' -> Cfg.Node.set_succs_exn context.cfg n' [switch_special_cond_node] []) res_trans_cond_tmp.leaf_nodes; let root_nodes = if res_trans_cond_tmp.root_nodes <> [] then res_trans_cond_tmp.root_nodes @@ -1427,8 +1430,8 @@ struct let case_entry_point = connected_instruction (IList.rev case_content) last_nodes in (* connects between cases, then continuation has priority about breaks *) let prune_node_t, prune_node_f = create_prune_nodes_for_case case in - Cfg.Node.set_succs_exn prune_node_t case_entry_point []; - Cfg.Node.set_succs_exn prune_node_f last_prune_nodes []; + Cfg.Node.set_succs_exn context.cfg prune_node_t case_entry_point []; + Cfg.Node.set_succs_exn context.cfg prune_node_f last_prune_nodes []; case_entry_point, [prune_node_t; prune_node_f] | DefaultStmt(stmt_info, default_content) :: rest -> let sil_loc = CLocation.get_sil_location stmt_info context in @@ -1438,13 +1441,13 @@ struct translate_and_connect_cases rest next_nodes [placeholder_entry_point] in let default_entry_point = connected_instruction (IList.rev default_content) last_nodes in - Cfg.Node.set_succs_exn placeholder_entry_point default_entry_point []; + Cfg.Node.set_succs_exn context.cfg placeholder_entry_point default_entry_point []; default_entry_point, last_prune_nodes | _ -> assert false in let top_entry_point, top_prune_nodes = translate_and_connect_cases list_of_cases succ_nodes succ_nodes in let _ = connected_instruction (IList.rev pre_case_stmts) top_entry_point in - Cfg.Node.set_succs_exn switch_special_cond_node top_prune_nodes []; + Cfg.Node.set_succs_exn context.cfg switch_special_cond_node top_prune_nodes []; let top_nodes = res_trans_decl.root_nodes in IList.iter (fun n' -> Cfg.Node.append_instrs_temps n' [] res_trans_cond.ids) succ_nodes; @@ -1539,9 +1542,9 @@ struct match loop_kind with | Loops.For _ | Loops.While _ -> res_trans_body.root_nodes | Loops.DoWhile _ -> [join_node] in - Cfg.Node.set_succs_exn join_node join_succ_nodes []; - IList.iter (fun n -> Cfg.Node.set_succs_exn n prune_t_succ_nodes []) prune_nodes_t; - IList.iter (fun n -> Cfg.Node.set_succs_exn n succ_nodes []) prune_nodes_f; + Cfg.Node.set_succs_exn context.cfg join_node join_succ_nodes []; + IList.iter (fun n -> Cfg.Node.set_succs_exn context.cfg n prune_t_succ_nodes []) prune_nodes_t; + IList.iter (fun n -> Cfg.Node.set_succs_exn context.cfg n succ_nodes []) prune_nodes_f; let root_nodes = match loop_kind with | Loops.For _ -> @@ -1879,7 +1882,8 @@ struct let trans_state_pri = PriorityNode.try_claim_priority_node trans_state stmt_info in let mk_ret_node ids instrs = let ret_node = create_node (Cfg.Node.Stmt_node "Return Stmt") ids instrs sil_loc context in - Cfg.Node.set_succs_exn ret_node [(Cfg.Procdesc.get_exit_node context.CContext.procdesc)] []; + Cfg.Node.set_succs_exn + context.cfg ret_node [(Cfg.Procdesc.get_exit_node context.CContext.procdesc)] []; ret_node in let trans_result = (match stmt_list with | [stmt] -> (* return exp; *) @@ -1911,7 +1915,9 @@ struct let instrs = var_instrs @ res_trans_stmt.instrs @ ret_instrs @ autorelease_instrs in let ids = var_ids @ res_trans_stmt.ids @ autorelease_ids in let ret_node = mk_ret_node ids instrs in - IList.iter (fun n -> Cfg.Node.set_succs_exn n [ret_node] []) res_trans_stmt.leaf_nodes; + IList.iter + (fun n -> Cfg.Node.set_succs_exn context.cfg n [ret_node] []) + res_trans_stmt.leaf_nodes; let root_nodes_to_parent = if IList.length res_trans_stmt.root_nodes >0 then res_trans_stmt.root_nodes @@ -1985,16 +1991,17 @@ struct ignored when checking for memory leaks. When the end of the block autoreleasepool is reached, then those objects are released and the autorelease flag is removed. *) and objcAutoreleasePool_trans trans_state stmt_info stmts = - let sil_loc = CLocation.get_sil_location stmt_info trans_state.context in + let context = trans_state.context in + let sil_loc = CLocation.get_sil_location stmt_info context in let fname = ModelBuiltins.__objc_release_autorelease_pool in let ret_id = Ident.create_fresh Ident.knormal in - let autorelease_pool_vars = CVar_decl.compute_autorelease_pool_vars trans_state.context stmts in + let autorelease_pool_vars = CVar_decl.compute_autorelease_pool_vars context stmts in let stmt_call = Sil.Call([ret_id], (Sil.Const (Sil.Cfun fname)), autorelease_pool_vars, sil_loc, Sil.cf_default) in let node_kind = Cfg.Node.Stmt_node ("Release the autorelease pool") in - let call_node = create_node node_kind ([ret_id]) ([stmt_call]) sil_loc trans_state.context in - Cfg.Node.set_succs_exn call_node trans_state.succ_nodes []; + let call_node = create_node node_kind ([ret_id]) ([stmt_call]) sil_loc context in + Cfg.Node.set_succs_exn context.cfg call_node trans_state.succ_nodes []; let trans_state'={ trans_state with continuation = None; succ_nodes =[call_node] } in instructions trans_state' stmts @@ -2112,7 +2119,7 @@ struct let (var_exp, typ) = var_exp_typ in let res_trans_init_list = initListExpr_initializers_trans trans_state_init var_exp 0 stmts typ is_dyn_array stmt_info in - CTrans_utils.collect_res_trans res_trans_init_list + CTrans_utils.collect_res_trans context.cfg res_trans_init_list else init_expr_trans trans_state_init var_exp_typ init_stmt_info stmt_opt in let all_res_trans = [res_trans_size; res_trans_new; res_trans_init] in let nname = "CXXNewExpr" in diff --git a/infer/src/clang/cTrans_utils.ml b/infer/src/clang/cTrans_utils.ml index 130375a7e..6fadeb37f 100644 --- a/infer/src/clang/cTrans_utils.ml +++ b/infer/src/clang/cTrans_utils.ml @@ -156,7 +156,7 @@ let empty_res_trans = { } (** Collect the results of translating a list of instructions, and link up the nodes created. *) -let collect_res_trans l = +let collect_res_trans cfg l = let rec collect l rt = match l with | [] -> rt @@ -168,7 +168,7 @@ let collect_res_trans l = if rt'.leaf_nodes <> [] then rt'.leaf_nodes else rt.leaf_nodes in if rt'.root_nodes <> [] then - IList.iter (fun n -> Cfg.Node.set_succs_exn n rt'.root_nodes []) rt.leaf_nodes; + IList.iter (fun n -> Cfg.Node.set_succs_exn cfg n rt'.root_nodes []) rt.leaf_nodes; collect l' { root_nodes = root_nodes; leaf_nodes = leaf_nodes; @@ -238,7 +238,8 @@ struct (* deals with creating or not a cfg node depending of owning the *) (* priority_node. It returns nodes, ids, instrs that should be passed to parent *) let compute_results_to_parent trans_state loc nd_name stmt_info res_states_children = - let res_state = collect_res_trans res_states_children in + let cfg = trans_state.context.cfg in + let res_state = collect_res_trans cfg res_states_children in let create_node = own_priority_node trans_state.priority stmt_info && res_state.instrs <> [] in if create_node then (* We need to create a node *) @@ -246,8 +247,8 @@ struct let ids_parent = ids_to_parent trans_state.continuation res_state.ids in let node_kind = Cfg.Node.Stmt_node (nd_name) in let node = Nodes.create_node node_kind ids_node res_state.instrs loc trans_state.context in - Cfg.Node.set_succs_exn node trans_state.succ_nodes []; - IList.iter (fun leaf -> Cfg.Node.set_succs_exn leaf [node] []) res_state.leaf_nodes; + Cfg.Node.set_succs_exn cfg node trans_state.succ_nodes []; + IList.iter (fun leaf -> Cfg.Node.set_succs_exn cfg leaf [node] []) res_state.leaf_nodes; (* Invariant: if root_nodes is empty then the params have not created a node.*) let root_nodes = (if res_state.root_nodes <> [] then res_state.root_nodes else [node]) in @@ -445,13 +446,13 @@ let trans_assertion_failure sil_loc context = let exit_node = Cfg.Procdesc.get_exit_node (CContext.get_procdesc context) and failure_node = Nodes.create_node (Cfg.Node.Stmt_node "Assertion failure") [] [call_instr] sil_loc context in - Cfg.Node.set_succs_exn failure_node [exit_node] []; + Cfg.Node.set_succs_exn context.CContext.cfg failure_node [exit_node] []; { empty_res_trans with root_nodes = [failure_node]; } let trans_assume_false sil_loc context succ_nodes = let instrs_cond = [Sil.Prune (Sil.exp_zero, sil_loc, true, Sil.Ik_land_lor)] in let prune_node = Nodes.create_node (Nodes.prune_kind true) [] instrs_cond sil_loc context in - Cfg.Node.set_succs_exn prune_node succ_nodes []; + Cfg.Node.set_succs_exn context.CContext.cfg prune_node succ_nodes []; { empty_res_trans with root_nodes = [prune_node]; leaf_nodes = [prune_node] } let define_condition_side_effects e_cond instrs_cond sil_loc = diff --git a/infer/src/clang/cTrans_utils.mli b/infer/src/clang/cTrans_utils.mli index 31340d85c..b7c014954 100644 --- a/infer/src/clang/cTrans_utils.mli +++ b/infer/src/clang/cTrans_utils.mli @@ -41,7 +41,7 @@ type trans_result = { val empty_res_trans: trans_result -val collect_res_trans : trans_result list -> trans_result +val collect_res_trans : Cfg.cfg -> trans_result list -> trans_result val extract_var_exp_or_fail : trans_state -> Sil.exp * Sil.typ diff --git a/infer/src/harness/inhabit.ml b/infer/src/harness/inhabit.ml index 28ec9ab7d..24de032d6 100644 --- a/infer/src/harness/inhabit.ml +++ b/infer/src/harness/inhabit.ml @@ -249,8 +249,8 @@ let setup_harness_cfg harness_name env cg cfg = Cfg.Procdesc.set_start_node procdesc start_node; Cfg.Procdesc.set_exit_node procdesc exit_node; Cfg.Node.add_locals_ret_declaration start_node []; - Cfg.Node.set_succs_exn start_node [harness_node] [exit_node]; - Cfg.Node.set_succs_exn harness_node [exit_node] [exit_node]; + Cfg.Node.set_succs_exn cfg start_node [harness_node] [exit_node]; + Cfg.Node.set_succs_exn cfg harness_node [exit_node] [exit_node]; add_harness_to_cg harness_name harness_node cg (** create a procedure named harness_name that calls each of the methods in trace in the specified diff --git a/infer/src/java/jFrontend.ml b/infer/src/java/jFrontend.ml index 4999ce3f7..959d3f816 100644 --- a/infer/src/java/jFrontend.ml +++ b/infer/src/java/jFrontend.ml @@ -17,6 +17,7 @@ module L = Logging let add_edges context start_node exn_node exit_nodes method_body_nodes impl super_call = + let cfg = (JContext.get_icfg context).cfg in let pc_nb = Array.length method_body_nodes in let last_pc = pc_nb - 1 in let is_last pc = (pc = last_pc) in @@ -47,7 +48,7 @@ let add_edges context start_node exn_node exit_nodes method_body_nodes impl supe if super_call then (fun _ -> exit_nodes) else JTransExn.create_exception_handlers context [exn_node] get_body_nodes impl in let connect node pc = - Cfg.Node.set_succs_exn node (get_succ_nodes node pc) (get_exn_nodes pc) in + Cfg.Node.set_succs_exn cfg node (get_succ_nodes node pc) (get_exn_nodes pc) in let connect_nodes pc translated_instruction = match translated_instruction with | JTrans.Skip -> () @@ -56,13 +57,19 @@ let add_edges context start_node exn_node exit_nodes method_body_nodes impl supe connect node_true pc; connect node_false pc | JTrans.Loop (join_node, node_true, node_false) -> - Cfg.Node.set_succs_exn join_node [node_true; node_false] []; + Cfg.Node.set_succs_exn cfg join_node [node_true; node_false] []; connect node_true pc; connect node_false pc in - let first_nodes = direct_successors (-1) in (* deals with the case of an empty array *) - Cfg.Node.set_succs_exn start_node first_nodes exit_nodes; (* the exceptions edges here are going directly to the exit node *) + let first_nodes = + (* deals with the case of an empty array *) + direct_successors (-1) in + + (* the exceptions edges here are going directly to the exit node *) + Cfg.Node.set_succs_exn cfg start_node first_nodes exit_nodes; + if not super_call then - Cfg.Node.set_succs_exn exn_node exit_nodes exit_nodes; (* the exceptions node is just before the exit node *) + (* the exceptions node is just before the exit node *) + Cfg.Node.set_succs_exn cfg exn_node exit_nodes exit_nodes; Array.iteri connect_nodes method_body_nodes (** Add a concrete method. *) @@ -72,8 +79,8 @@ let add_cmethod never_null_matcher program icfg node cm is_static = let cn, ms = JBasics.cms_split cm.Javalib.cm_class_method_signature in let is_clinit = JBasics.ms_equal ms JBasics.clinit_signature in if !JTrans.no_static_final = false - && is_clinit - && not (JTransStaticField.has_static_final_fields node) then + && is_clinit + && not (JTransStaticField.has_static_final_fields node) then JUtils.log "\t\tskipping class initializer: %s@." (JBasics.ms_name ms) else match JTrans.get_method_procdesc program cfg tenv cn ms is_static with diff --git a/infer/src/java/jTrans.ml b/infer/src/java/jTrans.ml index 0574a7786..2a122fcef 100644 --- a/infer/src/java/jTrans.ml +++ b/infer/src/java/jTrans.ml @@ -301,7 +301,7 @@ let create_local_procdesc program linereader cfg tenv node m = let start_node = Cfg.Node.create cfg Location.dummy start_kind [] procdesc [] in let exit_kind = (Cfg.Node.Exit_node procdesc) in let exit_node = Cfg.Node.create cfg Location.dummy exit_kind [] procdesc [] in - Cfg.Node.set_succs_exn start_node [exit_node] [exit_node]; + Cfg.Node.set_succs_exn cfg start_node [exit_node] [exit_node]; Cfg.Procdesc.set_start_node procdesc start_node; Cfg.Procdesc.set_exit_node procdesc exit_node | Javalib.ConcreteMethod cm when is_java_native cm -> diff --git a/infer/src/java/jTransExn.ml b/infer/src/java/jTransExn.ml index 1ceaf370d..6c5aef3bf 100644 --- a/infer/src/java/jTransExn.ml +++ b/infer/src/java/jTransExn.ml @@ -83,8 +83,8 @@ let translate_exceptions context exit_nodes get_body_nodes handler_table = let instrs_false = [instr_call_instanceof; instr_prune_false] @ (if rethrow_exception then [instr_rethrow_exn] else []) in let ids_false = (if last_handler then [id_exn_val] else []) @ [id_instanceof] in create_node loc node_kind_false instrs_false ids_false in - Cfg.Node.set_succs_exn node_true catch_nodes exit_nodes; - Cfg.Node.set_succs_exn node_false succ_nodes exit_nodes; + Cfg.Node.set_succs_exn cfg node_true catch_nodes exit_nodes; + Cfg.Node.set_succs_exn cfg node_false succ_nodes exit_nodes; let is_finally = handler.JBir.e_catch_type = None in if is_finally then [node_true] (* TODO (#4759480): clean up the translation so prune nodes are not created at all *) @@ -103,7 +103,7 @@ let translate_exceptions context exit_nodes get_body_nodes handler_table = | n:: _ -> Cfg.Node.get_loc n | [] -> Location.dummy in let entry_node = create_entry_node loc in - Cfg.Node.set_succs_exn entry_node nodes_first_handler exit_nodes; + Cfg.Node.set_succs_exn cfg entry_node nodes_first_handler exit_nodes; Hashtbl.add catch_block_table handler_list [entry_node] in Hashtbl.iter (fun _ handler_list -> create_entry_block handler_list) handler_table; catch_block_table diff --git a/infer/src/llvm/lTrans.ml b/infer/src/llvm/lTrans.ml index 3a20343f1..62ed62b71 100644 --- a/infer/src/llvm/lTrans.ml +++ b/infer/src/llvm/lTrans.ml @@ -148,8 +148,10 @@ let trans_function_def (cfg : Cfg.cfg) (cg: Cg.t) (metadata : LAst.metadata_map) [sil_instr] procdesc [] in let rec link_nodes (start_node : Cfg.Node.t) : Cfg.Node.t list -> unit = function (* link all nodes in a chain for now *) - | [] -> Cfg.Node.set_succs_exn start_node [exit_node] [exit_node] - | nd :: nds -> Cfg.Node.set_succs_exn start_node [nd] [exit_node]; link_nodes nd nds in + | [] -> + Cfg.Node.set_succs_exn cfg start_node [exit_node] [exit_node] + | nd :: nds -> + Cfg.Node.set_succs_exn cfg start_node [nd] [exit_node]; link_nodes nd nds in let (sil_instrs, locals) = trans_annotated_instructions cfg procdesc metadata annotated_instrs in let nodes = IList.map (node_of_sil_instr cfg procdesc) sil_instrs in diff --git a/infer/src/unit/analyzerTester.ml b/infer/src/unit/analyzerTester.ml index 0cfc374dc..d02da152d 100644 --- a/infer/src/unit/analyzerTester.ml +++ b/infer/src/unit/analyzerTester.ml @@ -145,7 +145,7 @@ module Make Cfg.Node.create cfg dummy_loc kind cmds pdesc no_tmp_idents in let set_succs cur_node succs = let no_exc_succs = [] in - Cfg.Node.set_succs_exn cur_node succs no_exc_succs in + Cfg.Node.set_succs_exn cfg cur_node succs no_exc_succs in let mk_prune_nodes_for_cond cond_exp if_kind = let mk_prune_node cond_exp if_kind true_branch = let prune_instr = Sil.Prune (cond_exp, dummy_loc, true_branch, if_kind) in diff --git a/infer/tests/codetoanalyze/c/errors/memory_leaks/test.c b/infer/tests/codetoanalyze/c/errors/memory_leaks/test.c index db964e9de..df69d18a7 100644 --- a/infer/tests/codetoanalyze/c/errors/memory_leaks/test.c +++ b/infer/tests/codetoanalyze/c/errors/memory_leaks/test.c @@ -45,3 +45,10 @@ void* builtin_no_leak(size_t s) { return memset(str, 0, s); } } + +void conditional_last_instruction() { + int* p = malloc(sizeof(int)); + if (0) { + free(p); + } +} diff --git a/infer/tests/codetoanalyze/c/frontend/conditional_operator/array_access.c.dot b/infer/tests/codetoanalyze/c/frontend/conditional_operator/array_access.c.dot index 8983161f5..60486c62e 100644 --- a/infer/tests/codetoanalyze/c/frontend/conditional_operator/array_access.c.dot +++ b/infer/tests/codetoanalyze/c/frontend/conditional_operator/array_access.c.dot @@ -1,77 +1,81 @@ digraph iCFG { -18 [label="18: Prune (false branch) \n n$14=*&p:int ** [line 11]\n n$15=*n$14[0]:int * [line 11]\n PRUNE((n$15 == 0), false); [line 11]\n REMOVE_TEMPS(n$14,n$15); [line 11]\n APPLY_ABSTRACTION; [line 11]\n " shape="invhouse"] +19 [label="19: Prune (false branch) \n n$14=*&p:int ** [line 11]\n n$15=*n$14[0]:int * [line 11]\n PRUNE((n$15 == 0), false); [line 11]\n REMOVE_TEMPS(n$14,n$15); [line 11]\n APPLY_ABSTRACTION; [line 11]\n " shape="invhouse"] - 18 -> 16 ; -17 [label="17: Prune (true branch) \n n$14=*&p:int ** [line 11]\n n$15=*n$14[0]:int * [line 11]\n PRUNE((n$15 != 0), true); [line 11]\n REMOVE_TEMPS(n$14,n$15); [line 11]\n APPLY_ABSTRACTION; [line 11]\n " shape="invhouse"] + 19 -> 17 ; +18 [label="18: Prune (true branch) \n n$14=*&p:int ** [line 11]\n n$15=*n$14[0]:int * [line 11]\n PRUNE((n$15 != 0), true); [line 11]\n REMOVE_TEMPS(n$14,n$15); [line 11]\n APPLY_ABSTRACTION; [line 11]\n " shape="invhouse"] - 17 -> 16 ; -16 [label="16: + \n " ] + 18 -> 17 ; +17 [label="17: + \n " ] + + + 17 -> 14 ; +16 [label="16: Prune (false branch) \n n$12=*n$11:int * [line 13]\n n$13=*n$12[1]:int [line 13]\n PRUNE((n$13 == 0), false); [line 13]\n REMOVE_TEMPS(n$11,n$12,n$13); [line 13]\n APPLY_ABSTRACTION; [line 13]\n " shape="invhouse"] 16 -> 13 ; -15 [label="15: Prune (false branch) \n n$12=*n$11:int * [line 13]\n n$13=*n$12[1]:int [line 13]\n PRUNE((n$13 == 0), false); [line 13]\n REMOVE_TEMPS(n$11,n$12,n$13); [line 13]\n APPLY_ABSTRACTION; [line 13]\n " shape="invhouse"] +15 [label="15: Prune (true branch) \n n$12=*n$11:int * [line 13]\n n$13=*n$12[1]:int [line 13]\n PRUNE((n$13 != 0), true); [line 13]\n REMOVE_TEMPS(n$11,n$12,n$13); [line 13]\n APPLY_ABSTRACTION; [line 13]\n " shape="invhouse"] - 15 -> 12 ; -14 [label="14: Prune (true branch) \n n$12=*n$11:int * [line 13]\n n$13=*n$12[1]:int [line 13]\n PRUNE((n$13 != 0), true); [line 13]\n REMOVE_TEMPS(n$11,n$12,n$13); [line 13]\n APPLY_ABSTRACTION; [line 13]\n " shape="invhouse"] + 15 -> 13 ; +14 [label="14: UnaryOperator \n n$11=*&p:int ** [line 13]\n " shape="box"] - 14 -> 12 ; -13 [label="13: UnaryOperator \n n$11=*&p:int ** [line 13]\n " shape="box"] + 14 -> 15 ; + 14 -> 16 ; +13 [label="13: + \n " ] - 13 -> 14 ; - 13 -> 15 ; -12 [label="12: + \n " ] + 13 -> 10 ; +12 [label="12: Prune (false branch) \n n$6=*&p:int ** [line 15]\n n$9=*n$8:int [line 15]\n n$10=*n$6[n$9]:int * [line 15]\n PRUNE((n$10 == 0), false); [line 15]\n REMOVE_TEMPS(n$7,n$8,n$9,n$6,n$10); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="invhouse"] 12 -> 9 ; -11 [label="11: Prune (false branch) \n n$6=*&p:int ** [line 15]\n n$9=*n$8:int [line 15]\n n$10=*n$6[n$9]:int * [line 15]\n PRUNE((n$10 == 0), false); [line 15]\n REMOVE_TEMPS(n$7,n$8,n$9,n$6,n$10); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="invhouse"] +11 [label="11: Prune (true branch) \n n$6=*&p:int ** [line 15]\n n$9=*n$8:int [line 15]\n n$10=*n$6[n$9]:int * [line 15]\n PRUNE((n$10 != 0), true); [line 15]\n REMOVE_TEMPS(n$7,n$8,n$9,n$6,n$10); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="invhouse"] - 11 -> 8 ; -10 [label="10: Prune (true branch) \n n$6=*&p:int ** [line 15]\n n$9=*n$8:int [line 15]\n n$10=*n$6[n$9]:int * [line 15]\n PRUNE((n$10 != 0), true); [line 15]\n REMOVE_TEMPS(n$7,n$8,n$9,n$6,n$10); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="invhouse"] + 11 -> 9 ; +10 [label="10: UnaryOperator \n n$7=*&p:int ** [line 15]\n n$8=*n$7:int * [line 15]\n " shape="box"] - 10 -> 8 ; -9 [label="9: UnaryOperator \n n$7=*&p:int ** [line 15]\n n$8=*n$7:int * [line 15]\n " shape="box"] + 10 -> 11 ; + 10 -> 12 ; +9 [label="9: + \n " ] - 9 -> 10 ; - 9 -> 11 ; -8 [label="8: + \n " ] + 9 -> 5 ; +8 [label="8: Prune (false branch) \n n$1=*n$0:int * [line 17]\n n$4=*n$3:int [line 17]\n n$5=*n$1[n$4]:int [line 17]\n PRUNE((n$5 == 0), false); [line 17]\n REMOVE_TEMPS(n$2,n$3,n$4,n$0,n$1,n$5); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="invhouse"] - 8 -> 4 ; -7 [label="7: Prune (false branch) \n n$1=*n$0:int * [line 17]\n n$4=*n$3:int [line 17]\n n$5=*n$1[n$4]:int [line 17]\n PRUNE((n$5 == 0), false); [line 17]\n REMOVE_TEMPS(n$2,n$3,n$4,n$0,n$1,n$5); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="invhouse"] + 8 -> 3 ; +7 [label="7: Prune (true branch) \n n$1=*n$0:int * [line 17]\n n$4=*n$3:int [line 17]\n n$5=*n$1[n$4]:int [line 17]\n PRUNE((n$5 != 0), true); [line 17]\n REMOVE_TEMPS(n$2,n$3,n$4,n$0,n$1,n$5); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="invhouse"] 7 -> 3 ; -6 [label="6: Prune (true branch) \n n$1=*n$0:int * [line 17]\n n$4=*n$3:int [line 17]\n n$5=*n$1[n$4]:int [line 17]\n PRUNE((n$5 != 0), true); [line 17]\n REMOVE_TEMPS(n$2,n$3,n$4,n$0,n$1,n$5); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="invhouse"] +6 [label="6: UnaryOperator \n n$2=*&p:int ** [line 17]\n n$3=*n$2:int * [line 17]\n NULLIFY(&p,false); [line 17]\n " shape="box"] - 6 -> 3 ; -5 [label="5: UnaryOperator \n n$2=*&p:int ** [line 17]\n n$3=*n$2:int * [line 17]\n NULLIFY(&p,false); [line 17]\n " shape="box"] + 6 -> 7 ; + 6 -> 8 ; +5 [label="5: UnaryOperator \n n$0=*&p:int ** [line 17]\n " shape="box"] 5 -> 6 ; - 5 -> 7 ; -4 [label="4: UnaryOperator \n n$0=*&p:int ** [line 17]\n " shape="box"] +4 [label="4: between_join_and_exit \n APPLY_ABSTRACTION; [line 17]\n " shape="box"] - 4 -> 5 ; + 4 -> 2 ; 3 [label="3: + \n " ] - 3 -> 2 ; + 3 -> 4 ; 2 [label="2: Exit dereference_in_array_access \n " color=yellow style=filled] 1 [label="1: Start dereference_in_array_access\nFormals: p:int **\nLocals: \n DECLARE_LOCALS(&return); [line 10]\n " color=yellow style=filled] - 1 -> 17 ; 1 -> 18 ; + 1 -> 19 ; } diff --git a/infer/tests/codetoanalyze/c/frontend/conditional_operator/if_short_circuit.c.dot b/infer/tests/codetoanalyze/c/frontend/conditional_operator/if_short_circuit.c.dot index fd8755b70..db992f8f4 100644 --- a/infer/tests/codetoanalyze/c/frontend/conditional_operator/if_short_circuit.c.dot +++ b/infer/tests/codetoanalyze/c/frontend/conditional_operator/if_short_circuit.c.dot @@ -1,389 +1,397 @@ digraph iCFG { -93 [label="93: BinaryOperatorStmt: Assign \n n$10=_fun_getenv(\"BLOCK\":char *) [line 47]\n *&spec:char *=n$10 [line 47]\n REMOVE_TEMPS(n$10); [line 47]\n " shape="box"] +95 [label="95: BinaryOperatorStmt: Assign \n n$10=_fun_getenv(\"BLOCK\":char *) [line 47]\n *&spec:char *=n$10 [line 47]\n REMOVE_TEMPS(n$10); [line 47]\n " shape="box"] - 93 -> 65 ; - 93 -> 66 ; -92 [label="92: BinaryOperatorStmt: Assign \n *&block_size:char *=0 [line 53]\n NULLIFY(&block_size,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"] + 95 -> 67 ; + 95 -> 68 ; +94 [label="94: BinaryOperatorStmt: Assign \n *&block_size:char *=0 [line 53]\n NULLIFY(&block_size,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"] - 92 -> 88 ; -91 [label="91: Prune (false branch) \n PRUNE(((n$9 == 39) == 0), false); [line 52]\n REMOVE_TEMPS(n$8,n$9); [line 52]\n APPLY_ABSTRACTION; [line 52]\n " shape="invhouse"] + 94 -> 90 ; +93 [label="93: Prune (false branch) \n PRUNE(((n$9 == 39) == 0), false); [line 52]\n REMOVE_TEMPS(n$8,n$9); [line 52]\n APPLY_ABSTRACTION; [line 52]\n " shape="invhouse"] - 91 -> 88 ; -90 [label="90: Prune (true branch) \n PRUNE(((n$9 == 39) != 0), true); [line 52]\n REMOVE_TEMPS(n$8,n$9); [line 52]\n " shape="invhouse"] + 93 -> 90 ; +92 [label="92: Prune (true branch) \n PRUNE(((n$9 == 39) != 0), true); [line 52]\n REMOVE_TEMPS(n$8,n$9); [line 52]\n " shape="invhouse"] - 90 -> 92 ; -89 [label="89: BinaryOperatorStmt: EQ \n n$8=*&spec:char * [line 52]\n n$9=*n$8:char [line 52]\n NULLIFY(&spec,false); [line 52]\n " shape="box"] + 92 -> 94 ; +91 [label="91: BinaryOperatorStmt: EQ \n n$8=*&spec:char * [line 52]\n n$9=*n$8:char [line 52]\n NULLIFY(&spec,false); [line 52]\n " shape="box"] - 89 -> 90 ; - 89 -> 91 ; -88 [label="88: + \n " ] + 91 -> 92 ; + 91 -> 93 ; +90 [label="90: + \n " ] - 88 -> 63 ; -87 [label="87: BinaryOperatorStmt: Assign \n *&block_size:char *=0 [line 50]\n NULLIFY(&block_size,false); [line 50]\n APPLY_ABSTRACTION; [line 50]\n " shape="box"] + 90 -> 65 ; +89 [label="89: BinaryOperatorStmt: Assign \n *&block_size:char *=0 [line 50]\n NULLIFY(&block_size,false); [line 50]\n APPLY_ABSTRACTION; [line 50]\n " shape="box"] - 87 -> 63 ; -86 [label="86: Prune (false branch) \n n$7=*&SIL_temp_conditional___79:int [line 49]\n NULLIFY(&SIL_temp_conditional___79,true); [line 49]\n PRUNE((n$7 == 0), false); [line 49]\n REMOVE_TEMPS(n$7); [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="invhouse"] + 89 -> 65 ; +88 [label="88: Prune (false branch) \n n$7=*&SIL_temp_conditional___81:int [line 49]\n NULLIFY(&SIL_temp_conditional___81,true); [line 49]\n PRUNE((n$7 == 0), false); [line 49]\n REMOVE_TEMPS(n$7); [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="invhouse"] - 86 -> 89 ; -85 [label="85: Prune (true branch) \n n$7=*&SIL_temp_conditional___79:int [line 49]\n NULLIFY(&SIL_temp_conditional___79,true); [line 49]\n PRUNE((n$7 != 0), true); [line 49]\n REMOVE_TEMPS(n$7); [line 49]\n NULLIFY(&spec,false); [line 49]\n " shape="invhouse"] + 88 -> 91 ; +87 [label="87: Prune (true branch) \n n$7=*&SIL_temp_conditional___81:int [line 49]\n NULLIFY(&SIL_temp_conditional___81,true); [line 49]\n PRUNE((n$7 != 0), true); [line 49]\n REMOVE_TEMPS(n$7); [line 49]\n NULLIFY(&spec,false); [line 49]\n " shape="invhouse"] - 85 -> 87 ; -84 [label="84: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___79); [line 49]\n *&SIL_temp_conditional___79:int =1 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] + 87 -> 89 ; +86 [label="86: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___81); [line 49]\n *&SIL_temp_conditional___81:int =1 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] - 84 -> 79 ; -83 [label="83: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___79); [line 49]\n *&SIL_temp_conditional___79:int =0 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] + 86 -> 81 ; +85 [label="85: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___81); [line 49]\n *&SIL_temp_conditional___81:int =0 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] - 83 -> 79 ; -82 [label="82: Prune (false branch) \n PRUNE((n$6 == 0), false); [line 49]\n REMOVE_TEMPS(n$5,n$6); [line 49]\n " shape="invhouse"] + 85 -> 81 ; +84 [label="84: Prune (false branch) \n PRUNE((n$6 == 0), false); [line 49]\n REMOVE_TEMPS(n$5,n$6); [line 49]\n " shape="invhouse"] + 84 -> 86 ; +83 [label="83: Prune (true branch) \n PRUNE((n$6 != 0), true); [line 49]\n REMOVE_TEMPS(n$5,n$6); [line 49]\n " shape="invhouse"] + + + 83 -> 85 ; +82 [label="82: BinaryOperatorStmt: Assign \n n$5=_fun_getenv(\"BLOCKSIZE\":char *) [line 49]\n *&spec:char *=n$5 [line 49]\n n$6=*&spec:char * [line 49]\n " shape="box"] + + + 82 -> 83 ; 82 -> 84 ; -81 [label="81: Prune (true branch) \n PRUNE((n$6 != 0), true); [line 49]\n REMOVE_TEMPS(n$5,n$6); [line 49]\n " shape="invhouse"] +81 [label="81: + \n " ] - 81 -> 83 ; -80 [label="80: BinaryOperatorStmt: Assign \n n$5=_fun_getenv(\"BLOCKSIZE\":char *) [line 49]\n *&spec:char *=n$5 [line 49]\n n$6=*&spec:char * [line 49]\n " shape="box"] + 81 -> 87 ; + 81 -> 88 ; +80 [label="80: Prune (false branch) \n n$4=*&SIL_temp_conditional___73:int [line 49]\n NULLIFY(&SIL_temp_conditional___73,true); [line 49]\n PRUNE((n$4 == 0), false); [line 49]\n REMOVE_TEMPS(n$4); [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="invhouse"] - 80 -> 81 ; - 80 -> 82 ; -79 [label="79: + \n " ] + 80 -> 91 ; +79 [label="79: Prune (true branch) \n n$4=*&SIL_temp_conditional___73:int [line 49]\n NULLIFY(&SIL_temp_conditional___73,true); [line 49]\n PRUNE((n$4 != 0), true); [line 49]\n REMOVE_TEMPS(n$4); [line 49]\n NULLIFY(&spec,false); [line 49]\n " shape="invhouse"] - 79 -> 85 ; - 79 -> 86 ; -78 [label="78: Prune (false branch) \n n$4=*&SIL_temp_conditional___71:int [line 49]\n NULLIFY(&SIL_temp_conditional___71,true); [line 49]\n PRUNE((n$4 == 0), false); [line 49]\n REMOVE_TEMPS(n$4); [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="invhouse"] + 79 -> 82 ; +78 [label="78: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___73); [line 49]\n *&SIL_temp_conditional___73:int =1 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] - 78 -> 89 ; -77 [label="77: Prune (true branch) \n n$4=*&SIL_temp_conditional___71:int [line 49]\n NULLIFY(&SIL_temp_conditional___71,true); [line 49]\n PRUNE((n$4 != 0), true); [line 49]\n REMOVE_TEMPS(n$4); [line 49]\n NULLIFY(&spec,false); [line 49]\n " shape="invhouse"] + 78 -> 73 ; +77 [label="77: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___73); [line 49]\n *&SIL_temp_conditional___73:int =0 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] - 77 -> 80 ; -76 [label="76: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___71); [line 49]\n *&SIL_temp_conditional___71:int =1 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] + 77 -> 73 ; +76 [label="76: Prune (false branch) \n PRUNE((n$3 == 0), false); [line 49]\n REMOVE_TEMPS(n$2,n$3); [line 49]\n " shape="invhouse"] - 76 -> 71 ; -75 [label="75: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___71); [line 49]\n *&SIL_temp_conditional___71:int =0 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] + 76 -> 78 ; +75 [label="75: Prune (true branch) \n PRUNE((n$3 != 0), true); [line 49]\n REMOVE_TEMPS(n$2,n$3); [line 49]\n " shape="invhouse"] - 75 -> 71 ; -74 [label="74: Prune (false branch) \n PRUNE((n$3 == 0), false); [line 49]\n REMOVE_TEMPS(n$2,n$3); [line 49]\n " shape="invhouse"] + 75 -> 77 ; +74 [label="74: BinaryOperatorStmt: Assign \n n$2=_fun_getenv(\"BLOCK_SIZE\":char *) [line 49]\n *&spec:char *=n$2 [line 49]\n n$3=*&spec:char * [line 49]\n " shape="box"] + 74 -> 75 ; 74 -> 76 ; -73 [label="73: Prune (true branch) \n PRUNE((n$3 != 0), true); [line 49]\n REMOVE_TEMPS(n$2,n$3); [line 49]\n " shape="invhouse"] +73 [label="73: + \n " ] - 73 -> 75 ; -72 [label="72: BinaryOperatorStmt: Assign \n n$2=_fun_getenv(\"BLOCK_SIZE\":char *) [line 49]\n *&spec:char *=n$2 [line 49]\n n$3=*&spec:char * [line 49]\n " shape="box"] + 73 -> 79 ; + 73 -> 80 ; +72 [label="72: Prune (false branch) \n n$1=*&SIL_temp_conditional___66:int [line 49]\n NULLIFY(&SIL_temp_conditional___66,true); [line 49]\n PRUNE((n$1 == 0), false); [line 49]\n REMOVE_TEMPS(n$1); [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="invhouse"] - 72 -> 73 ; - 72 -> 74 ; -71 [label="71: + \n " ] + 72 -> 91 ; +71 [label="71: Prune (true branch) \n n$1=*&SIL_temp_conditional___66:int [line 49]\n NULLIFY(&SIL_temp_conditional___66,true); [line 49]\n PRUNE((n$1 != 0), true); [line 49]\n REMOVE_TEMPS(n$1); [line 49]\n NULLIFY(&spec,false); [line 49]\n " shape="invhouse"] - 71 -> 77 ; - 71 -> 78 ; -70 [label="70: Prune (false branch) \n n$1=*&SIL_temp_conditional___64:int [line 49]\n NULLIFY(&SIL_temp_conditional___64,true); [line 49]\n PRUNE((n$1 == 0), false); [line 49]\n REMOVE_TEMPS(n$1); [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="invhouse"] + 71 -> 74 ; +70 [label="70: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___66); [line 49]\n *&SIL_temp_conditional___66:int =1 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] - 70 -> 89 ; -69 [label="69: Prune (true branch) \n n$1=*&SIL_temp_conditional___64:int [line 49]\n NULLIFY(&SIL_temp_conditional___64,true); [line 49]\n PRUNE((n$1 != 0), true); [line 49]\n REMOVE_TEMPS(n$1); [line 49]\n NULLIFY(&spec,false); [line 49]\n " shape="invhouse"] + 70 -> 66 ; +69 [label="69: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___66); [line 49]\n *&SIL_temp_conditional___66:int =0 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] - 69 -> 72 ; -68 [label="68: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___64); [line 49]\n *&SIL_temp_conditional___64:int =1 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] + 69 -> 66 ; +68 [label="68: Prune (false branch) \n n$0=*&spec:char * [line 49]\n PRUNE((n$0 == 0), false); [line 49]\n REMOVE_TEMPS(n$0); [line 49]\n " shape="invhouse"] - 68 -> 64 ; -67 [label="67: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___64); [line 49]\n *&SIL_temp_conditional___64:int =0 [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] + 68 -> 70 ; +67 [label="67: Prune (true branch) \n n$0=*&spec:char * [line 49]\n PRUNE((n$0 != 0), true); [line 49]\n REMOVE_TEMPS(n$0); [line 49]\n " shape="invhouse"] - 67 -> 64 ; -66 [label="66: Prune (false branch) \n n$0=*&spec:char * [line 49]\n PRUNE((n$0 == 0), false); [line 49]\n REMOVE_TEMPS(n$0); [line 49]\n " shape="invhouse"] + 67 -> 69 ; +66 [label="66: + \n " ] - 66 -> 68 ; -65 [label="65: Prune (true branch) \n n$0=*&spec:char * [line 49]\n PRUNE((n$0 != 0), true); [line 49]\n REMOVE_TEMPS(n$0); [line 49]\n " shape="invhouse"] + 66 -> 71 ; + 66 -> 72 ; +65 [label="65: + \n " ] - 65 -> 67 ; -64 [label="64: + \n " ] + 65 -> 64 ; +64 [label="64: Return Stmt \n *&return:int =0 [line 56]\n APPLY_ABSTRACTION; [line 56]\n " shape="box"] - 64 -> 69 ; - 64 -> 70 ; -63 [label="63: + \n " ] + 64 -> 63 ; +63 [label="63: Exit main \n " color=yellow style=filled] - 63 -> 62 ; -62 [label="62: Return Stmt \n *&return:int =0 [line 56]\n APPLY_ABSTRACTION; [line 56]\n " shape="box"] +62 [label="62: Start main\nFormals: \nLocals: block_size:char * spec:char * \n DECLARE_LOCALS(&return,&block_size,&spec); [line 42]\n NULLIFY(&block_size,false); [line 42]\n NULLIFY(&spec,false); [line 42]\n " color=yellow style=filled] - 62 -> 61 ; -61 [label="61: Exit main \n " color=yellow style=filled] + 62 -> 95 ; +61 [label="61: BinaryOperatorStmt: Assign \n n$8=_fun_getenv(\"BLOCK\":char *) [line 34]\n *&spec:char *=n$8 [line 34]\n REMOVE_TEMPS(n$8); [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] -60 [label="60: Start main\nFormals: \nLocals: block_size:char * spec:char * \n DECLARE_LOCALS(&return,&block_size,&spec); [line 42]\n NULLIFY(&block_size,false); [line 42]\n NULLIFY(&spec,false); [line 42]\n " color=yellow style=filled] + 61 -> 36 ; +60 [label="60: BinaryOperatorStmt: Assign \n *&block_size:char *=0 [line 38]\n NULLIFY(&block_size,false); [line 38]\n APPLY_ABSTRACTION; [line 38]\n " shape="box"] - 60 -> 93 ; -59 [label="59: BinaryOperatorStmt: Assign \n n$8=_fun_getenv(\"BLOCK\":char *) [line 34]\n *&spec:char *=n$8 [line 34]\n REMOVE_TEMPS(n$8); [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] + 60 -> 36 ; +59 [label="59: Prune (false branch) \n n$7=*&SIL_temp_conditional___52:int [line 37]\n NULLIFY(&SIL_temp_conditional___52,true); [line 37]\n PRUNE((n$7 == 0), false); [line 37]\n REMOVE_TEMPS(n$7); [line 37]\n NULLIFY(&spec,false); [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="invhouse"] - 59 -> 34 ; -58 [label="58: BinaryOperatorStmt: Assign \n *&block_size:char *=0 [line 38]\n NULLIFY(&block_size,false); [line 38]\n APPLY_ABSTRACTION; [line 38]\n " shape="box"] + 59 -> 35 ; +58 [label="58: Prune (true branch) \n n$7=*&SIL_temp_conditional___52:int [line 37]\n NULLIFY(&SIL_temp_conditional___52,true); [line 37]\n PRUNE((n$7 != 0), true); [line 37]\n REMOVE_TEMPS(n$7); [line 37]\n " shape="invhouse"] - 58 -> 34 ; -57 [label="57: Prune (false branch) \n n$7=*&SIL_temp_conditional___50:int [line 37]\n NULLIFY(&SIL_temp_conditional___50,true); [line 37]\n PRUNE((n$7 == 0), false); [line 37]\n REMOVE_TEMPS(n$7); [line 37]\n NULLIFY(&spec,false); [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="invhouse"] + 58 -> 60 ; +57 [label="57: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___52); [line 37]\n *&SIL_temp_conditional___52:int =1 [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"] - 57 -> 33 ; -56 [label="56: Prune (true branch) \n n$7=*&SIL_temp_conditional___50:int [line 37]\n NULLIFY(&SIL_temp_conditional___50,true); [line 37]\n PRUNE((n$7 != 0), true); [line 37]\n REMOVE_TEMPS(n$7); [line 37]\n " shape="invhouse"] + 57 -> 52 ; +56 [label="56: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___52); [line 37]\n *&SIL_temp_conditional___52:int =0 [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"] - 56 -> 58 ; -55 [label="55: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___50); [line 37]\n *&SIL_temp_conditional___50:int =1 [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"] + 56 -> 52 ; +55 [label="55: Prune (false branch) \n PRUNE((n$6 == 0), false); [line 37]\n REMOVE_TEMPS(n$5,n$6); [line 37]\n " shape="invhouse"] - 55 -> 50 ; -54 [label="54: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___50); [line 37]\n *&SIL_temp_conditional___50:int =0 [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"] + 55 -> 57 ; +54 [label="54: Prune (true branch) \n PRUNE((n$6 != 0), true); [line 37]\n REMOVE_TEMPS(n$5,n$6); [line 37]\n " shape="invhouse"] - 54 -> 50 ; -53 [label="53: Prune (false branch) \n PRUNE((n$6 == 0), false); [line 37]\n REMOVE_TEMPS(n$5,n$6); [line 37]\n " shape="invhouse"] + 54 -> 56 ; +53 [label="53: BinaryOperatorStmt: Assign \n n$5=_fun_getenv(\"BLOCKSIZE\":char *) [line 37]\n *&spec:char *=n$5 [line 37]\n n$6=*&spec:char * [line 37]\n " shape="box"] + 53 -> 54 ; 53 -> 55 ; -52 [label="52: Prune (true branch) \n PRUNE((n$6 != 0), true); [line 37]\n REMOVE_TEMPS(n$5,n$6); [line 37]\n " shape="invhouse"] +52 [label="52: + \n " ] - 52 -> 54 ; -51 [label="51: BinaryOperatorStmt: Assign \n n$5=_fun_getenv(\"BLOCKSIZE\":char *) [line 37]\n *&spec:char *=n$5 [line 37]\n n$6=*&spec:char * [line 37]\n " shape="box"] + 52 -> 58 ; + 52 -> 59 ; +51 [label="51: Prune (false branch) \n n$4=*&SIL_temp_conditional___44:int [line 36]\n NULLIFY(&SIL_temp_conditional___44,true); [line 36]\n PRUNE((n$4 == 0), false); [line 36]\n REMOVE_TEMPS(n$4); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="invhouse"] - 51 -> 52 ; - 51 -> 53 ; -50 [label="50: + \n " ] + 51 -> 35 ; +50 [label="50: Prune (true branch) \n n$4=*&SIL_temp_conditional___44:int [line 36]\n NULLIFY(&SIL_temp_conditional___44,true); [line 36]\n PRUNE((n$4 != 0), true); [line 36]\n REMOVE_TEMPS(n$4); [line 36]\n " shape="invhouse"] - 50 -> 56 ; - 50 -> 57 ; -49 [label="49: Prune (false branch) \n n$4=*&SIL_temp_conditional___42:int [line 36]\n NULLIFY(&SIL_temp_conditional___42,true); [line 36]\n PRUNE((n$4 == 0), false); [line 36]\n REMOVE_TEMPS(n$4); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="invhouse"] + 50 -> 53 ; +49 [label="49: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___44); [line 36]\n *&SIL_temp_conditional___44:int =1 [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] - 49 -> 33 ; -48 [label="48: Prune (true branch) \n n$4=*&SIL_temp_conditional___42:int [line 36]\n NULLIFY(&SIL_temp_conditional___42,true); [line 36]\n PRUNE((n$4 != 0), true); [line 36]\n REMOVE_TEMPS(n$4); [line 36]\n " shape="invhouse"] + 49 -> 44 ; +48 [label="48: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___44); [line 36]\n *&SIL_temp_conditional___44:int =0 [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] - 48 -> 51 ; -47 [label="47: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___42); [line 36]\n *&SIL_temp_conditional___42:int =1 [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] + 48 -> 44 ; +47 [label="47: Prune (false branch) \n PRUNE((n$3 == 0), false); [line 36]\n REMOVE_TEMPS(n$2,n$3); [line 36]\n " shape="invhouse"] - 47 -> 42 ; -46 [label="46: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___42); [line 36]\n *&SIL_temp_conditional___42:int =0 [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] + 47 -> 49 ; +46 [label="46: Prune (true branch) \n PRUNE((n$3 != 0), true); [line 36]\n REMOVE_TEMPS(n$2,n$3); [line 36]\n " shape="invhouse"] - 46 -> 42 ; -45 [label="45: Prune (false branch) \n PRUNE((n$3 == 0), false); [line 36]\n REMOVE_TEMPS(n$2,n$3); [line 36]\n " shape="invhouse"] + 46 -> 48 ; +45 [label="45: BinaryOperatorStmt: Assign \n n$2=_fun_getenv(\"BLOCK_SIZE\":char *) [line 36]\n *&spec:char *=n$2 [line 36]\n n$3=*&spec:char * [line 36]\n NULLIFY(&spec,false); [line 36]\n " shape="box"] + 45 -> 46 ; 45 -> 47 ; -44 [label="44: Prune (true branch) \n PRUNE((n$3 != 0), true); [line 36]\n REMOVE_TEMPS(n$2,n$3); [line 36]\n " shape="invhouse"] +44 [label="44: + \n " ] - 44 -> 46 ; -43 [label="43: BinaryOperatorStmt: Assign \n n$2=_fun_getenv(\"BLOCK_SIZE\":char *) [line 36]\n *&spec:char *=n$2 [line 36]\n n$3=*&spec:char * [line 36]\n NULLIFY(&spec,false); [line 36]\n " shape="box"] + 44 -> 50 ; + 44 -> 51 ; +43 [label="43: Prune (false branch) \n n$1=*&SIL_temp_conditional___37:int [line 36]\n NULLIFY(&SIL_temp_conditional___37,true); [line 36]\n PRUNE((n$1 == 0), false); [line 36]\n REMOVE_TEMPS(n$1); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="invhouse"] - 43 -> 44 ; - 43 -> 45 ; -42 [label="42: + \n " ] + 43 -> 35 ; +42 [label="42: Prune (true branch) \n n$1=*&SIL_temp_conditional___37:int [line 36]\n NULLIFY(&SIL_temp_conditional___37,true); [line 36]\n PRUNE((n$1 != 0), true); [line 36]\n REMOVE_TEMPS(n$1); [line 36]\n " shape="invhouse"] - 42 -> 48 ; - 42 -> 49 ; -41 [label="41: Prune (false branch) \n n$1=*&SIL_temp_conditional___35:int [line 36]\n NULLIFY(&SIL_temp_conditional___35,true); [line 36]\n PRUNE((n$1 == 0), false); [line 36]\n REMOVE_TEMPS(n$1); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="invhouse"] + 42 -> 45 ; +41 [label="41: ConditinalStmt Branch \n NULLIFY(&spec,false); [line 36]\n DECLARE_LOCALS(&SIL_temp_conditional___37); [line 36]\n *&SIL_temp_conditional___37:int =1 [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] - 41 -> 33 ; -40 [label="40: Prune (true branch) \n n$1=*&SIL_temp_conditional___35:int [line 36]\n NULLIFY(&SIL_temp_conditional___35,true); [line 36]\n PRUNE((n$1 != 0), true); [line 36]\n REMOVE_TEMPS(n$1); [line 36]\n " shape="invhouse"] + 41 -> 37 ; +40 [label="40: ConditinalStmt Branch \n NULLIFY(&spec,false); [line 36]\n DECLARE_LOCALS(&SIL_temp_conditional___37); [line 36]\n *&SIL_temp_conditional___37:int =0 [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] - 40 -> 43 ; -39 [label="39: ConditinalStmt Branch \n NULLIFY(&spec,false); [line 36]\n DECLARE_LOCALS(&SIL_temp_conditional___35); [line 36]\n *&SIL_temp_conditional___35:int =1 [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] + 40 -> 37 ; +39 [label="39: Prune (false branch) \n n$0=*&spec:char * [line 36]\n PRUNE((n$0 == 0), false); [line 36]\n REMOVE_TEMPS(n$0); [line 36]\n " shape="invhouse"] - 39 -> 35 ; -38 [label="38: ConditinalStmt Branch \n NULLIFY(&spec,false); [line 36]\n DECLARE_LOCALS(&SIL_temp_conditional___35); [line 36]\n *&SIL_temp_conditional___35:int =0 [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] + 39 -> 41 ; +38 [label="38: Prune (true branch) \n n$0=*&spec:char * [line 36]\n PRUNE((n$0 != 0), true); [line 36]\n REMOVE_TEMPS(n$0); [line 36]\n " shape="invhouse"] - 38 -> 35 ; -37 [label="37: Prune (false branch) \n n$0=*&spec:char * [line 36]\n PRUNE((n$0 == 0), false); [line 36]\n REMOVE_TEMPS(n$0); [line 36]\n " shape="invhouse"] + 38 -> 40 ; +37 [label="37: + \n " ] - 37 -> 39 ; -36 [label="36: Prune (true branch) \n n$0=*&spec:char * [line 36]\n PRUNE((n$0 != 0), true); [line 36]\n REMOVE_TEMPS(n$0); [line 36]\n " shape="invhouse"] + 37 -> 42 ; + 37 -> 43 ; +36 [label="36: + \n " ] 36 -> 38 ; -35 [label="35: + \n " ] + 36 -> 39 ; +35 [label="35: Exit test_loop \n " color=yellow style=filled] - 35 -> 40 ; - 35 -> 41 ; -34 [label="34: + \n " ] +34 [label="34: Start test_loop\nFormals: \nLocals: block_size:char * spec:char * \n DECLARE_LOCALS(&return,&block_size,&spec); [line 29]\n NULLIFY(&block_size,false); [line 29]\n NULLIFY(&spec,false); [line 29]\n " color=yellow style=filled] - 34 -> 36 ; - 34 -> 37 ; -33 [label="33: Exit test_loop \n " color=yellow style=filled] + 34 -> 61 ; +33 [label="33: BinaryOperatorStmt: Assign \n n$5=*&x:int * [line 25]\n *n$5:int =32 [line 25]\n REMOVE_TEMPS(n$5); [line 25]\n NULLIFY(&x,false); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] -32 [label="32: Start test_loop\nFormals: \nLocals: block_size:char * spec:char * \n DECLARE_LOCALS(&return,&block_size,&spec); [line 29]\n NULLIFY(&block_size,false); [line 29]\n NULLIFY(&spec,false); [line 29]\n " color=yellow style=filled] + 33 -> 15 ; +32 [label="32: BinaryOperatorStmt: Assign \n *&x:int *=17 [line 23]\n NULLIFY(&x,false); [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"] - 32 -> 59 ; -31 [label="31: BinaryOperatorStmt: Assign \n n$5=*&x:int * [line 25]\n *n$5:int =32 [line 25]\n REMOVE_TEMPS(n$5); [line 25]\n NULLIFY(&x,false); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] + 32 -> 15 ; +31 [label="31: Prune (false branch) \n n$4=*&SIL_temp_conditional___24:int [line 22]\n NULLIFY(&SIL_temp_conditional___24,true); [line 22]\n PRUNE((n$4 == 0), false); [line 22]\n REMOVE_TEMPS(n$4); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="invhouse"] - 31 -> 14 ; -30 [label="30: BinaryOperatorStmt: Assign \n *&x:int *=17 [line 23]\n NULLIFY(&x,false); [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"] + 31 -> 33 ; +30 [label="30: Prune (true branch) \n n$4=*&SIL_temp_conditional___24:int [line 22]\n NULLIFY(&SIL_temp_conditional___24,true); [line 22]\n PRUNE((n$4 != 0), true); [line 22]\n REMOVE_TEMPS(n$4); [line 22]\n NULLIFY(&x,false); [line 22]\n " shape="invhouse"] - 30 -> 14 ; -29 [label="29: Prune (false branch) \n n$4=*&SIL_temp_conditional___22:int [line 22]\n NULLIFY(&SIL_temp_conditional___22,true); [line 22]\n PRUNE((n$4 == 0), false); [line 22]\n REMOVE_TEMPS(n$4); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="invhouse"] + 30 -> 32 ; +29 [label="29: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___24); [line 22]\n *&SIL_temp_conditional___24:int =1 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 29 -> 31 ; -28 [label="28: Prune (true branch) \n n$4=*&SIL_temp_conditional___22:int [line 22]\n NULLIFY(&SIL_temp_conditional___22,true); [line 22]\n PRUNE((n$4 != 0), true); [line 22]\n REMOVE_TEMPS(n$4); [line 22]\n NULLIFY(&x,false); [line 22]\n " shape="invhouse"] + 29 -> 24 ; +28 [label="28: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___24); [line 22]\n *&SIL_temp_conditional___24:int =0 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 28 -> 30 ; -27 [label="27: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___22); [line 22]\n *&SIL_temp_conditional___22:int =1 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] + 28 -> 24 ; +27 [label="27: Prune (false branch) \n PRUNE((n$3 == 0), false); [line 22]\n REMOVE_TEMPS(n$2,n$3); [line 22]\n " shape="invhouse"] - 27 -> 22 ; -26 [label="26: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___22); [line 22]\n *&SIL_temp_conditional___22:int =0 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] + 27 -> 29 ; +26 [label="26: Prune (true branch) \n PRUNE((n$3 != 0), true); [line 22]\n REMOVE_TEMPS(n$2,n$3); [line 22]\n " shape="invhouse"] - 26 -> 22 ; -25 [label="25: Prune (false branch) \n PRUNE((n$3 == 0), false); [line 22]\n REMOVE_TEMPS(n$2,n$3); [line 22]\n " shape="invhouse"] + 26 -> 28 ; +25 [label="25: BinaryOperatorStmt: Assign \n n$2=_fun_getenv(\"BLOCK\":char *) [line 22]\n *&x:int *=n$2 [line 22]\n n$3=*&x:int * [line 22]\n " shape="box"] + 25 -> 26 ; 25 -> 27 ; -24 [label="24: Prune (true branch) \n PRUNE((n$3 != 0), true); [line 22]\n REMOVE_TEMPS(n$2,n$3); [line 22]\n " shape="invhouse"] +24 [label="24: + \n " ] - 24 -> 26 ; -23 [label="23: BinaryOperatorStmt: Assign \n n$2=_fun_getenv(\"BLOCK\":char *) [line 22]\n *&x:int *=n$2 [line 22]\n n$3=*&x:int * [line 22]\n " shape="box"] + 24 -> 30 ; + 24 -> 31 ; +23 [label="23: Prune (false branch) \n n$1=*&SIL_temp_conditional___17:int [line 22]\n NULLIFY(&SIL_temp_conditional___17,true); [line 22]\n PRUNE((n$1 == 0), false); [line 22]\n REMOVE_TEMPS(n$1); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="invhouse"] - 23 -> 24 ; - 23 -> 25 ; -22 [label="22: + \n " ] + 23 -> 33 ; +22 [label="22: Prune (true branch) \n n$1=*&SIL_temp_conditional___17:int [line 22]\n NULLIFY(&SIL_temp_conditional___17,true); [line 22]\n PRUNE((n$1 != 0), true); [line 22]\n REMOVE_TEMPS(n$1); [line 22]\n NULLIFY(&x,false); [line 22]\n " shape="invhouse"] - 22 -> 28 ; - 22 -> 29 ; -21 [label="21: Prune (false branch) \n n$1=*&SIL_temp_conditional___15:int [line 22]\n NULLIFY(&SIL_temp_conditional___15,true); [line 22]\n PRUNE((n$1 == 0), false); [line 22]\n REMOVE_TEMPS(n$1); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="invhouse"] + 22 -> 25 ; +21 [label="21: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___17); [line 22]\n *&SIL_temp_conditional___17:int =1 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 21 -> 31 ; -20 [label="20: Prune (true branch) \n n$1=*&SIL_temp_conditional___15:int [line 22]\n NULLIFY(&SIL_temp_conditional___15,true); [line 22]\n PRUNE((n$1 != 0), true); [line 22]\n REMOVE_TEMPS(n$1); [line 22]\n NULLIFY(&x,false); [line 22]\n " shape="invhouse"] + 21 -> 17 ; +20 [label="20: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___17); [line 22]\n *&SIL_temp_conditional___17:int =0 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 20 -> 23 ; -19 [label="19: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___15); [line 22]\n *&SIL_temp_conditional___15:int =1 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] + 20 -> 17 ; +19 [label="19: Prune (false branch) \n n$0=*&x:int * [line 22]\n PRUNE((n$0 == 0), false); [line 22]\n REMOVE_TEMPS(n$0); [line 22]\n " shape="invhouse"] - 19 -> 15 ; -18 [label="18: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___15); [line 22]\n *&SIL_temp_conditional___15:int =0 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] + 19 -> 21 ; +18 [label="18: Prune (true branch) \n n$0=*&x:int * [line 22]\n PRUNE((n$0 != 0), true); [line 22]\n REMOVE_TEMPS(n$0); [line 22]\n " shape="invhouse"] - 18 -> 15 ; -17 [label="17: Prune (false branch) \n n$0=*&x:int * [line 22]\n PRUNE((n$0 == 0), false); [line 22]\n REMOVE_TEMPS(n$0); [line 22]\n " shape="invhouse"] + 18 -> 20 ; +17 [label="17: + \n " ] - 17 -> 19 ; -16 [label="16: Prune (true branch) \n n$0=*&x:int * [line 22]\n PRUNE((n$0 != 0), true); [line 22]\n REMOVE_TEMPS(n$0); [line 22]\n " shape="invhouse"] + 17 -> 22 ; + 17 -> 23 ; +16 [label="16: between_join_and_exit \n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 16 -> 18 ; + 16 -> 14 ; 15 [label="15: + \n " ] - 15 -> 20 ; - 15 -> 21 ; -14 [label="14: + \n " ] + 15 -> 16 ; +14 [label="14: Exit shortcircuit_and \n " color=yellow style=filled] - 14 -> 13 ; -13 [label="13: Exit shortcircuit_and \n " color=yellow style=filled] +13 [label="13: Start shortcircuit_and\nFormals: x:int *\nLocals: \n DECLARE_LOCALS(&return); [line 21]\n " color=yellow style=filled] -12 [label="12: Start shortcircuit_and\nFormals: x:int *\nLocals: \n DECLARE_LOCALS(&return); [line 21]\n " color=yellow style=filled] + 13 -> 18 ; + 13 -> 19 ; +12 [label="12: BinaryOperatorStmt: Assign \n *&x:int *=32 [line 17]\n NULLIFY(&x,false); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"] - 12 -> 16 ; - 12 -> 17 ; -11 [label="11: BinaryOperatorStmt: Assign \n *&x:int *=32 [line 17]\n NULLIFY(&x,false); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"] + 12 -> 3 ; +11 [label="11: BinaryOperatorStmt: Assign \n NULLIFY(&x,false); [line 15]\n *&x:int *=17 [line 15]\n NULLIFY(&x,false); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"] 11 -> 3 ; -10 [label="10: BinaryOperatorStmt: Assign \n NULLIFY(&x,false); [line 15]\n *&x:int *=17 [line 15]\n NULLIFY(&x,false); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"] +10 [label="10: Prune (false branch) \n PRUNE(((n$2 == 2) == 0), false); [line 14]\n REMOVE_TEMPS(n$1,n$2); [line 14]\n " shape="invhouse"] - 10 -> 3 ; -9 [label="9: Prune (false branch) \n PRUNE(((n$2 == 2) == 0), false); [line 14]\n REMOVE_TEMPS(n$1,n$2); [line 14]\n " shape="invhouse"] + 10 -> 12 ; +9 [label="9: Prune (true branch) \n PRUNE(((n$2 == 2) != 0), true); [line 14]\n REMOVE_TEMPS(n$1,n$2); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="invhouse"] 9 -> 11 ; -8 [label="8: Prune (true branch) \n PRUNE(((n$2 == 2) != 0), true); [line 14]\n REMOVE_TEMPS(n$1,n$2); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="invhouse"] +8 [label="8: BinaryOperatorStmt: EQ \n n$1=*&x:int * [line 14]\n n$2=*n$1:int [line 14]\n NULLIFY(&x,false); [line 14]\n " shape="box"] + 8 -> 9 ; 8 -> 10 ; -7 [label="7: BinaryOperatorStmt: EQ \n n$1=*&x:int * [line 14]\n n$2=*n$1:int [line 14]\n NULLIFY(&x,false); [line 14]\n " shape="box"] +7 [label="7: Prune (false branch) \n PRUNE(((n$0 == 0) == 0), false); [line 14]\n REMOVE_TEMPS(n$0); [line 14]\n " shape="invhouse"] 7 -> 8 ; - 7 -> 9 ; -6 [label="6: Prune (false branch) \n PRUNE(((n$0 == 0) == 0), false); [line 14]\n REMOVE_TEMPS(n$0); [line 14]\n " shape="invhouse"] +6 [label="6: Prune (true branch) \n PRUNE(((n$0 == 0) != 0), true); [line 14]\n REMOVE_TEMPS(n$0); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="invhouse"] - 6 -> 7 ; -5 [label="5: Prune (true branch) \n PRUNE(((n$0 == 0) != 0), true); [line 14]\n REMOVE_TEMPS(n$0); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="invhouse"] + 6 -> 11 ; +5 [label="5: BinaryOperatorStmt: EQ \n n$0=*&x:int * [line 14]\n " shape="box"] - 5 -> 10 ; -4 [label="4: BinaryOperatorStmt: EQ \n n$0=*&x:int * [line 14]\n " shape="box"] + 5 -> 6 ; + 5 -> 7 ; +4 [label="4: between_join_and_exit \n APPLY_ABSTRACTION; [line 14]\n " shape="box"] - 4 -> 5 ; - 4 -> 6 ; + 4 -> 2 ; 3 [label="3: + \n " ] - 3 -> 2 ; + 3 -> 4 ; 2 [label="2: Exit shortcircuit_or \n " color=yellow style=filled] 1 [label="1: Start shortcircuit_or\nFormals: x:int *\nLocals: \n DECLARE_LOCALS(&return); [line 12]\n " color=yellow style=filled] - 1 -> 4 ; + 1 -> 5 ; } diff --git a/infer/tests/codetoanalyze/c/frontend/conditional_operator/int_negation.c.dot b/infer/tests/codetoanalyze/c/frontend/conditional_operator/int_negation.c.dot index 013472aab..2ac6c60ad 100644 --- a/infer/tests/codetoanalyze/c/frontend/conditional_operator/int_negation.c.dot +++ b/infer/tests/codetoanalyze/c/frontend/conditional_operator/int_negation.c.dot @@ -1,121 +1,129 @@ digraph iCFG { -32 [label="32: Return Stmt \n n$1=*&SIL_temp_conditional___27:int [line 29]\n NULLIFY(&SIL_temp_conditional___27,true); [line 29]\n *&return:int =n$1 [line 29]\n REMOVE_TEMPS(n$1); [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] +34 [label="34: Return Stmt \n n$1=*&SIL_temp_conditional___29:int [line 29]\n NULLIFY(&SIL_temp_conditional___29,true); [line 29]\n *&return:int =n$1 [line 29]\n REMOVE_TEMPS(n$1); [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] - 32 -> 26 ; -31 [label="31: ConditinalStmt Branch \n NULLIFY(&x,false); [line 29]\n DECLARE_LOCALS(&SIL_temp_conditional___27); [line 29]\n *&SIL_temp_conditional___27:int =1 [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] + 34 -> 28 ; +33 [label="33: ConditinalStmt Branch \n NULLIFY(&x,false); [line 29]\n DECLARE_LOCALS(&SIL_temp_conditional___29); [line 29]\n *&SIL_temp_conditional___29:int =1 [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] - 31 -> 27 ; -30 [label="30: ConditinalStmt Branch \n NULLIFY(&x,false); [line 29]\n DECLARE_LOCALS(&SIL_temp_conditional___27); [line 29]\n *&SIL_temp_conditional___27:int =0 [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] + 33 -> 29 ; +32 [label="32: ConditinalStmt Branch \n NULLIFY(&x,false); [line 29]\n DECLARE_LOCALS(&SIL_temp_conditional___29); [line 29]\n *&SIL_temp_conditional___29:int =0 [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] - 30 -> 27 ; -29 [label="29: Prune (false branch) \n n$0=*&x:int [line 29]\n PRUNE((n$0 == 0), false); [line 29]\n REMOVE_TEMPS(n$0); [line 29]\n " shape="invhouse"] + 32 -> 29 ; +31 [label="31: Prune (false branch) \n n$0=*&x:int [line 29]\n PRUNE((n$0 == 0), false); [line 29]\n REMOVE_TEMPS(n$0); [line 29]\n " shape="invhouse"] - 29 -> 31 ; -28 [label="28: Prune (true branch) \n n$0=*&x:int [line 29]\n PRUNE((n$0 != 0), true); [line 29]\n REMOVE_TEMPS(n$0); [line 29]\n " shape="invhouse"] + 31 -> 33 ; +30 [label="30: Prune (true branch) \n n$0=*&x:int [line 29]\n PRUNE((n$0 != 0), true); [line 29]\n REMOVE_TEMPS(n$0); [line 29]\n " shape="invhouse"] - 28 -> 30 ; -27 [label="27: + \n " ] + 30 -> 32 ; +29 [label="29: + \n " ] - 27 -> 32 ; -26 [label="26: Exit neg \n " color=yellow style=filled] + 29 -> 34 ; +28 [label="28: Exit neg \n " color=yellow style=filled] -25 [label="25: Start neg\nFormals: x:int \nLocals: \n DECLARE_LOCALS(&return); [line 29]\n " color=yellow style=filled] +27 [label="27: Start neg\nFormals: x:int \nLocals: \n DECLARE_LOCALS(&return); [line 29]\n " color=yellow style=filled] - 25 -> 28 ; - 25 -> 29 ; -24 [label="24: Return Stmt \n *&return:int =0 [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] + 27 -> 30 ; + 27 -> 31 ; +26 [label="26: Return Stmt \n *&return:int =0 [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] - 24 -> 13 ; -23 [label="23: Return Stmt \n *&return:int =1 [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"] + 26 -> 14 ; +25 [label="25: Return Stmt \n *&return:int =1 [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"] - 23 -> 13 ; -22 [label="22: Prune (false branch) \n PRUNE((n$2 == 0), false); [line 22]\n REMOVE_TEMPS(n$1,n$2); [line 22]\n " shape="invhouse"] + 25 -> 14 ; +24 [label="24: Prune (false branch) \n PRUNE((n$2 == 0), false); [line 22]\n REMOVE_TEMPS(n$1,n$2); [line 22]\n " shape="invhouse"] + 24 -> 26 ; +23 [label="23: Prune (true branch) \n PRUNE((n$2 != 0), true); [line 22]\n REMOVE_TEMPS(n$1,n$2); [line 22]\n " shape="invhouse"] + + + 23 -> 25 ; +22 [label="22: Call _fun_identity \n n$1=*&SIL_temp_conditional___17:int [line 22]\n NULLIFY(&SIL_temp_conditional___17,true); [line 22]\n n$2=_fun_identity(n$1:int ) [line 22]\n " shape="box"] + + + 22 -> 23 ; 22 -> 24 ; -21 [label="21: Prune (true branch) \n PRUNE((n$2 != 0), true); [line 22]\n REMOVE_TEMPS(n$1,n$2); [line 22]\n " shape="invhouse"] +21 [label="21: ConditinalStmt Branch \n NULLIFY(&x,false); [line 22]\n DECLARE_LOCALS(&SIL_temp_conditional___17); [line 22]\n *&SIL_temp_conditional___17:int =1 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 21 -> 23 ; -20 [label="20: Call _fun_identity \n n$1=*&SIL_temp_conditional___15:int [line 22]\n NULLIFY(&SIL_temp_conditional___15,true); [line 22]\n n$2=_fun_identity(n$1:int ) [line 22]\n " shape="box"] + 21 -> 17 ; +20 [label="20: ConditinalStmt Branch \n NULLIFY(&x,false); [line 22]\n DECLARE_LOCALS(&SIL_temp_conditional___17); [line 22]\n *&SIL_temp_conditional___17:int =0 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 20 -> 21 ; - 20 -> 22 ; -19 [label="19: ConditinalStmt Branch \n NULLIFY(&x,false); [line 22]\n DECLARE_LOCALS(&SIL_temp_conditional___15); [line 22]\n *&SIL_temp_conditional___15:int =1 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] + 20 -> 17 ; +19 [label="19: Prune (false branch) \n n$0=*&x:int [line 22]\n PRUNE((n$0 == 0), false); [line 22]\n REMOVE_TEMPS(n$0); [line 22]\n " shape="invhouse"] - 19 -> 15 ; -18 [label="18: ConditinalStmt Branch \n NULLIFY(&x,false); [line 22]\n DECLARE_LOCALS(&SIL_temp_conditional___15); [line 22]\n *&SIL_temp_conditional___15:int =0 [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] + 19 -> 21 ; +18 [label="18: Prune (true branch) \n n$0=*&x:int [line 22]\n PRUNE((n$0 != 0), true); [line 22]\n REMOVE_TEMPS(n$0); [line 22]\n " shape="invhouse"] - 18 -> 15 ; -17 [label="17: Prune (false branch) \n n$0=*&x:int [line 22]\n PRUNE((n$0 == 0), false); [line 22]\n REMOVE_TEMPS(n$0); [line 22]\n " shape="invhouse"] + 18 -> 20 ; +17 [label="17: + \n " ] - 17 -> 19 ; -16 [label="16: Prune (true branch) \n n$0=*&x:int [line 22]\n PRUNE((n$0 != 0), true); [line 22]\n REMOVE_TEMPS(n$0); [line 22]\n " shape="invhouse"] + 17 -> 22 ; +16 [label="16: between_join_and_exit \n NULLIFY(&x,false); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 16 -> 18 ; + 16 -> 14 ; 15 [label="15: + \n " ] - 15 -> 20 ; -14 [label="14: + \n NULLIFY(&x,false); [line 22]\n " ] + 15 -> 16 ; +14 [label="14: Exit baz \n " color=yellow style=filled] - 14 -> 13 ; -13 [label="13: Exit baz \n " color=yellow style=filled] +13 [label="13: Start baz\nFormals: x:int \nLocals: \n DECLARE_LOCALS(&return); [line 20]\n " color=yellow style=filled] -12 [label="12: Start baz\nFormals: x:int \nLocals: \n DECLARE_LOCALS(&return); [line 20]\n " color=yellow style=filled] + 13 -> 18 ; + 13 -> 19 ; +12 [label="12: Return Stmt \n *&return:int =0 [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"] - 12 -> 16 ; - 12 -> 17 ; -11 [label="11: Return Stmt \n *&return:int =0 [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"] + 12 -> 5 ; +11 [label="11: Return Stmt \n *&return:int =1 [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"] 11 -> 5 ; -10 [label="10: Return Stmt \n *&return:int =1 [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"] +10 [label="10: Prune (false branch) \n PRUNE((n$1 == 0), false); [line 13]\n REMOVE_TEMPS(n$0,n$1); [line 13]\n " shape="invhouse"] - 10 -> 5 ; -9 [label="9: Prune (false branch) \n PRUNE((n$1 == 0), false); [line 13]\n REMOVE_TEMPS(n$0,n$1); [line 13]\n " shape="invhouse"] + 10 -> 12 ; +9 [label="9: Prune (true branch) \n PRUNE((n$1 != 0), true); [line 13]\n REMOVE_TEMPS(n$0,n$1); [line 13]\n " shape="invhouse"] 9 -> 11 ; -8 [label="8: Prune (true branch) \n PRUNE((n$1 != 0), true); [line 13]\n REMOVE_TEMPS(n$0,n$1); [line 13]\n " shape="invhouse"] +8 [label="8: Call _fun_identity \n n$0=*&x:int [line 13]\n n$1=_fun_identity(n$0:int ) [line 13]\n NULLIFY(&x,false); [line 13]\n " shape="box"] + 8 -> 9 ; 8 -> 10 ; -7 [label="7: Call _fun_identity \n n$0=*&x:int [line 13]\n n$1=_fun_identity(n$0:int ) [line 13]\n NULLIFY(&x,false); [line 13]\n " shape="box"] +7 [label="7: between_join_and_exit \n NULLIFY(&x,false); [line 13]\n APPLY_ABSTRACTION; [line 13]\n " shape="box"] - 7 -> 8 ; - 7 -> 9 ; -6 [label="6: + \n NULLIFY(&x,false); [line 13]\n " ] + 7 -> 5 ; +6 [label="6: + \n " ] - 6 -> 5 ; + 6 -> 7 ; 5 [label="5: Exit bar \n " color=yellow style=filled] 4 [label="4: Start bar\nFormals: x:int \nLocals: \n DECLARE_LOCALS(&return); [line 12]\n " color=yellow style=filled] - 4 -> 7 ; + 4 -> 8 ; 3 [label="3: Return Stmt \n n$0=*&x:int [line 10]\n *&return:int =n$0 [line 10]\n REMOVE_TEMPS(n$0); [line 10]\n NULLIFY(&x,false); [line 10]\n APPLY_ABSTRACTION; [line 10]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/c/frontend/enumeration/other_enum.c.dot b/infer/tests/codetoanalyze/c/frontend/enumeration/other_enum.c.dot index 4134ea00c..d147ebeac 100644 --- a/infer/tests/codetoanalyze/c/frontend/enumeration/other_enum.c.dot +++ b/infer/tests/codetoanalyze/c/frontend/enumeration/other_enum.c.dot @@ -1,44 +1,48 @@ digraph iCFG { -19 [label="19: DeclStmt \n *&foo_g:int =(2 + 10) [line 23]\n " shape="box"] +20 [label="20: DeclStmt \n *&foo_g:int =(2 + 10) [line 23]\n " shape="box"] - 19 -> 18 ; -18 [label="18: DeclStmt \n *&foo_a:int =0 [line 24]\n " shape="box"] + 20 -> 19 ; +19 [label="19: DeclStmt \n *&foo_a:int =0 [line 24]\n " shape="box"] - 18 -> 13 ; -17 [label="17: Return Stmt \n NULLIFY(&foo_a,false); [line 28]\n NULLIFY(&foo_g,false); [line 28]\n *&return:int =0 [line 28]\n APPLY_ABSTRACTION; [line 28]\n " shape="box"] + 19 -> 14 ; +18 [label="18: Return Stmt \n NULLIFY(&foo_a,false); [line 28]\n NULLIFY(&foo_g,false); [line 28]\n *&return:int =0 [line 28]\n APPLY_ABSTRACTION; [line 28]\n " shape="box"] + + + 18 -> 11 ; +17 [label="17: Return Stmt \n n$1=*&foo_g:int [line 26]\n n$2=*&foo_a:int [line 26]\n *&return:int =(n$1 / n$2) [line 26]\n REMOVE_TEMPS(n$1,n$2); [line 26]\n NULLIFY(&foo_a,false); [line 26]\n NULLIFY(&foo_g,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] 17 -> 11 ; -16 [label="16: Return Stmt \n n$1=*&foo_g:int [line 26]\n n$2=*&foo_a:int [line 26]\n *&return:int =(n$1 / n$2) [line 26]\n REMOVE_TEMPS(n$1,n$2); [line 26]\n NULLIFY(&foo_a,false); [line 26]\n NULLIFY(&foo_g,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] +16 [label="16: Prune (false branch) \n PRUNE(((n$0 == 12) == 0), false); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] - 16 -> 11 ; -15 [label="15: Prune (false branch) \n PRUNE(((n$0 == 12) == 0), false); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] + 16 -> 18 ; +15 [label="15: Prune (true branch) \n PRUNE(((n$0 == 12) != 0), true); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] 15 -> 17 ; -14 [label="14: Prune (true branch) \n PRUNE(((n$0 == 12) != 0), true); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] +14 [label="14: BinaryOperatorStmt: EQ \n n$0=*&foo_g:int [line 25]\n " shape="box"] + 14 -> 15 ; 14 -> 16 ; -13 [label="13: BinaryOperatorStmt: EQ \n n$0=*&foo_g:int [line 25]\n " shape="box"] +13 [label="13: between_join_and_exit \n NULLIFY(&foo_a,false); [line 25]\n NULLIFY(&foo_g,false); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] - 13 -> 14 ; - 13 -> 15 ; -12 [label="12: + \n NULLIFY(&foo_a,false); [line 25]\n NULLIFY(&foo_g,false); [line 25]\n " ] + 13 -> 11 ; +12 [label="12: + \n " ] - 12 -> 11 ; + 12 -> 13 ; 11 [label="11: Exit test \n " color=yellow style=filled] 10 [label="10: Start test\nFormals: \nLocals: foo_a:int foo_g:int \n DECLARE_LOCALS(&return,&foo_a,&foo_g); [line 22]\n NULLIFY(&foo_a,false); [line 22]\n NULLIFY(&foo_g,false); [line 22]\n " color=yellow style=filled] - 10 -> 19 ; + 10 -> 20 ; 9 [label="9: DeclStmt \n *&foo_a:int =0 [line 13]\n NULLIFY(&foo_a,false); [line 13]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/cpp/frontend/nestedoperators/var_decl_inside_if.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/nestedoperators/var_decl_inside_if.cpp.dot index 2559898e3..91546e58e 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/nestedoperators/var_decl_inside_if.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/nestedoperators/var_decl_inside_if.cpp.dot @@ -1,271 +1,295 @@ digraph iCFG { -67 [label="67: Return Stmt \n n$1=*&p:int * [line 60]\n n$2=*n$1:int [line 60]\n *&return:int =n$2 [line 60]\n REMOVE_TEMPS(n$1,n$2); [line 60]\n NULLIFY(&p,false); [line 60]\n APPLY_ABSTRACTION; [line 60]\n " shape="box"] +73 [label="73: Return Stmt \n n$1=*&p:int * [line 60]\n n$2=*n$1:int [line 60]\n *&return:int =n$2 [line 60]\n REMOVE_TEMPS(n$1,n$2); [line 60]\n NULLIFY(&p,false); [line 60]\n APPLY_ABSTRACTION; [line 60]\n " shape="box"] - 67 -> 61 ; -66 [label="66: Return Stmt \n NULLIFY(&p,false); [line 58]\n *&return:int =1 [line 58]\n APPLY_ABSTRACTION; [line 58]\n " shape="box"] + 73 -> 66 ; +72 [label="72: Return Stmt \n NULLIFY(&p,false); [line 58]\n *&return:int =1 [line 58]\n APPLY_ABSTRACTION; [line 58]\n " shape="box"] - 66 -> 61 ; -65 [label="65: DeclStmt \n *&p:int *=null [line 57]\n " shape="box"] + 72 -> 66 ; +71 [label="71: DeclStmt \n *&p:int *=null [line 57]\n " shape="box"] - 65 -> 63 ; - 65 -> 64 ; -64 [label="64: Prune (false branch) \n n$0=*&p:int * [line 57]\n PRUNE((n$0 == 0), false); [line 57]\n REMOVE_TEMPS(n$0); [line 57]\n " shape="invhouse"] + 71 -> 69 ; + 71 -> 70 ; +70 [label="70: Prune (false branch) \n n$0=*&p:int * [line 57]\n PRUNE((n$0 == 0), false); [line 57]\n REMOVE_TEMPS(n$0); [line 57]\n " shape="invhouse"] - 64 -> 67 ; -63 [label="63: Prune (true branch) \n n$0=*&p:int * [line 57]\n PRUNE((n$0 != 0), true); [line 57]\n REMOVE_TEMPS(n$0); [line 57]\n " shape="invhouse"] + 70 -> 73 ; +69 [label="69: Prune (true branch) \n n$0=*&p:int * [line 57]\n PRUNE((n$0 != 0), true); [line 57]\n REMOVE_TEMPS(n$0); [line 57]\n " shape="invhouse"] - 63 -> 66 ; -62 [label="62: + \n NULLIFY(&p,false); [line 57]\n " ] + 69 -> 72 ; +68 [label="68: between_join_and_exit \n NULLIFY(&p,false); [line 57]\n APPLY_ABSTRACTION; [line 57]\n " shape="box"] + 68 -> 66 ; +67 [label="67: + \n " ] + + + 67 -> 68 ; +66 [label="66: Exit simple_init_null_deref \n " color=yellow style=filled] + + +65 [label="65: Start simple_init_null_deref\nFormals: \nLocals: p:int * \n DECLARE_LOCALS(&return,&p); [line 56]\n NULLIFY(&p,false); [line 56]\n " color=yellow style=filled] + + + 65 -> 71 ; +64 [label="64: DeclStmt \n *&r:int =1 [line 49]\n " shape="box"] + + + 64 -> 62 ; +63 [label="63: BinaryOperatorStmt: Assign \n n$3=*&a:int & [line 51]\n *n$3:int =0 [line 51]\n REMOVE_TEMPS(n$3); [line 51]\n NULLIFY(&a,false); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"] + + + 63 -> 59 ; +62 [label="62: DeclStmt \n *&a:int &=&r [line 50]\n " shape="box"] + + + 62 -> 60 ; 62 -> 61 ; -61 [label="61: Exit simple_init_null_deref \n " color=yellow style=filled] +61 [label="61: Prune (false branch) \n n$1=*&a:int & [line 50]\n n$2=*n$1:int [line 50]\n PRUNE((n$2 == 0), false); [line 50]\n REMOVE_TEMPS(n$1,n$2); [line 50]\n APPLY_ABSTRACTION; [line 50]\n " shape="invhouse"] -60 [label="60: Start simple_init_null_deref\nFormals: \nLocals: p:int * \n DECLARE_LOCALS(&return,&p); [line 56]\n NULLIFY(&p,false); [line 56]\n " color=yellow style=filled] + 61 -> 59 ; +60 [label="60: Prune (true branch) \n n$1=*&a:int & [line 50]\n n$2=*n$1:int [line 50]\n PRUNE((n$2 != 0), true); [line 50]\n REMOVE_TEMPS(n$1,n$2); [line 50]\n " shape="invhouse"] - 60 -> 65 ; -59 [label="59: DeclStmt \n *&r:int =1 [line 49]\n " shape="box"] + 60 -> 63 ; +59 [label="59: + \n " ] - 59 -> 57 ; -58 [label="58: BinaryOperatorStmt: Assign \n n$3=*&a:int & [line 51]\n *n$3:int =0 [line 51]\n REMOVE_TEMPS(n$3); [line 51]\n NULLIFY(&a,false); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"] + 59 -> 58 ; +58 [label="58: Return Stmt \n NULLIFY(&a,false); [line 53]\n n$0=*&r:int [line 53]\n *&return:int =(1 / n$0) [line 53]\n REMOVE_TEMPS(n$0); [line 53]\n NULLIFY(&r,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"] - 58 -> 54 ; -57 [label="57: DeclStmt \n *&a:int &=&r [line 50]\n " shape="box"] + 58 -> 57 ; +57 [label="57: Exit reference_init_div0 \n " color=yellow style=filled] - 57 -> 55 ; - 57 -> 56 ; -56 [label="56: Prune (false branch) \n n$1=*&a:int & [line 50]\n n$2=*n$1:int [line 50]\n PRUNE((n$2 == 0), false); [line 50]\n REMOVE_TEMPS(n$1,n$2); [line 50]\n APPLY_ABSTRACTION; [line 50]\n " shape="invhouse"] +56 [label="56: Start reference_init_div0\nFormals: \nLocals: a:int & r:int \n DECLARE_LOCALS(&return,&a,&r); [line 48]\n NULLIFY(&a,false); [line 48]\n " color=yellow style=filled] - 56 -> 54 ; -55 [label="55: Prune (true branch) \n n$1=*&a:int & [line 50]\n n$2=*n$1:int [line 50]\n PRUNE((n$2 != 0), true); [line 50]\n REMOVE_TEMPS(n$1,n$2); [line 50]\n " shape="invhouse"] + 56 -> 64 ; +55 [label="55: Return Stmt \n n$2=*&a:int [line 44]\n *&return:int =(1 / (n$2 - 1)) [line 44]\n REMOVE_TEMPS(n$2); [line 44]\n NULLIFY(&a,false); [line 44]\n APPLY_ABSTRACTION; [line 44]\n " shape="box"] - 55 -> 58 ; -54 [label="54: + \n " ] + 55 -> 44 ; +54 [label="54: DeclStmt \n n$1=*&SIL_temp_conditional___49:int [line 43]\n NULLIFY(&SIL_temp_conditional___49,true); [line 43]\n *&a:int =n$1 [line 43]\n REMOVE_TEMPS(n$1); [line 43]\n " shape="box"] - 54 -> 53 ; -53 [label="53: Return Stmt \n NULLIFY(&a,false); [line 53]\n n$0=*&r:int [line 53]\n *&return:int =(1 / n$0) [line 53]\n REMOVE_TEMPS(n$0); [line 53]\n NULLIFY(&r,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"] + 54 -> 47 ; + 54 -> 48 ; +53 [label="53: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___49); [line 43]\n *&SIL_temp_conditional___49:int =0 [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] - 53 -> 52 ; -52 [label="52: Exit reference_init_div0 \n " color=yellow style=filled] + 53 -> 49 ; +52 [label="52: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___49); [line 43]\n *&SIL_temp_conditional___49:int =1 [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] -51 [label="51: Start reference_init_div0\nFormals: \nLocals: a:int & r:int \n DECLARE_LOCALS(&return,&a,&r); [line 48]\n NULLIFY(&a,false); [line 48]\n " color=yellow style=filled] + 52 -> 49 ; +51 [label="51: Prune (false branch) \n PRUNE((1 == 0), false); [line 43]\n " shape="invhouse"] - 51 -> 59 ; -50 [label="50: Return Stmt \n n$2=*&a:int [line 44]\n *&return:int =(1 / (n$2 - 1)) [line 44]\n REMOVE_TEMPS(n$2); [line 44]\n NULLIFY(&a,false); [line 44]\n APPLY_ABSTRACTION; [line 44]\n " shape="box"] + 51 -> 53 ; +50 [label="50: Prune (true branch) \n PRUNE((1 != 0), true); [line 43]\n " shape="invhouse"] - 50 -> 40 ; -49 [label="49: DeclStmt \n n$1=*&SIL_temp_conditional___44:int [line 43]\n NULLIFY(&SIL_temp_conditional___44,true); [line 43]\n *&a:int =n$1 [line 43]\n REMOVE_TEMPS(n$1); [line 43]\n " shape="box"] + 50 -> 52 ; +49 [label="49: + \n " ] - 49 -> 42 ; - 49 -> 43 ; -48 [label="48: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___44); [line 43]\n *&SIL_temp_conditional___44:int =0 [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] + 49 -> 54 ; +48 [label="48: Prune (false branch) \n n$0=*&a:int [line 43]\n PRUNE((n$0 == 0), false); [line 43]\n REMOVE_TEMPS(n$0); [line 43]\n " shape="invhouse"] - 48 -> 44 ; -47 [label="47: ConditinalStmt Branch \n DECLARE_LOCALS(&SIL_temp_conditional___44); [line 43]\n *&SIL_temp_conditional___44:int =1 [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] + 48 -> 45 ; +47 [label="47: Prune (true branch) \n n$0=*&a:int [line 43]\n PRUNE((n$0 != 0), true); [line 43]\n REMOVE_TEMPS(n$0); [line 43]\n " shape="invhouse"] - 47 -> 44 ; -46 [label="46: Prune (false branch) \n PRUNE((1 == 0), false); [line 43]\n " shape="invhouse"] + 47 -> 55 ; +46 [label="46: between_join_and_exit \n NULLIFY(&a,false); [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] - 46 -> 48 ; -45 [label="45: Prune (true branch) \n PRUNE((1 != 0), true); [line 43]\n " shape="invhouse"] + 46 -> 44 ; +45 [label="45: + \n " ] - 45 -> 47 ; -44 [label="44: + \n " ] + 45 -> 46 ; +44 [label="44: Exit conditional_init_div0 \n " color=yellow style=filled] - 44 -> 49 ; -43 [label="43: Prune (false branch) \n n$0=*&a:int [line 43]\n PRUNE((n$0 == 0), false); [line 43]\n REMOVE_TEMPS(n$0); [line 43]\n " shape="invhouse"] +43 [label="43: Start conditional_init_div0\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 42]\n NULLIFY(&a,false); [line 42]\n " color=yellow style=filled] - 43 -> 41 ; -42 [label="42: Prune (true branch) \n n$0=*&a:int [line 43]\n PRUNE((n$0 != 0), true); [line 43]\n REMOVE_TEMPS(n$0); [line 43]\n " shape="invhouse"] + 43 -> 50 ; + 43 -> 51 ; +42 [label="42: Return Stmt \n n$2=*&a:int [line 38]\n *&return:int =(1 / (n$2 - 1)) [line 38]\n REMOVE_TEMPS(n$2); [line 38]\n NULLIFY(&a,false); [line 38]\n APPLY_ABSTRACTION; [line 38]\n " shape="box"] - 42 -> 50 ; -41 [label="41: + \n NULLIFY(&a,false); [line 43]\n " ] + 42 -> 36 ; +41 [label="41: DeclStmt \n n$1=_fun_get1() [line 37]\n *&a:int =n$1 [line 37]\n REMOVE_TEMPS(n$1); [line 37]\n " shape="box"] + 41 -> 39 ; 41 -> 40 ; -40 [label="40: Exit conditional_init_div0 \n " color=yellow style=filled] +40 [label="40: Prune (false branch) \n n$0=*&a:int [line 37]\n PRUNE((n$0 == 0), false); [line 37]\n REMOVE_TEMPS(n$0); [line 37]\n " shape="invhouse"] -39 [label="39: Start conditional_init_div0\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 42]\n NULLIFY(&a,false); [line 42]\n " color=yellow style=filled] + 40 -> 37 ; +39 [label="39: Prune (true branch) \n n$0=*&a:int [line 37]\n PRUNE((n$0 != 0), true); [line 37]\n REMOVE_TEMPS(n$0); [line 37]\n " shape="invhouse"] - 39 -> 45 ; - 39 -> 46 ; -38 [label="38: Return Stmt \n n$2=*&a:int [line 38]\n *&return:int =(1 / (n$2 - 1)) [line 38]\n REMOVE_TEMPS(n$2); [line 38]\n NULLIFY(&a,false); [line 38]\n APPLY_ABSTRACTION; [line 38]\n " shape="box"] + 39 -> 42 ; +38 [label="38: between_join_and_exit \n NULLIFY(&a,false); [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"] - 38 -> 33 ; -37 [label="37: DeclStmt \n n$1=_fun_get1() [line 37]\n *&a:int =n$1 [line 37]\n REMOVE_TEMPS(n$1); [line 37]\n " shape="box"] + 38 -> 36 ; +37 [label="37: + \n " ] - 37 -> 35 ; - 37 -> 36 ; -36 [label="36: Prune (false branch) \n n$0=*&a:int [line 37]\n PRUNE((n$0 == 0), false); [line 37]\n REMOVE_TEMPS(n$0); [line 37]\n " shape="invhouse"] + 37 -> 38 ; +36 [label="36: Exit function_call_init_div0 \n " color=yellow style=filled] - 36 -> 34 ; -35 [label="35: Prune (true branch) \n n$0=*&a:int [line 37]\n PRUNE((n$0 != 0), true); [line 37]\n REMOVE_TEMPS(n$0); [line 37]\n " shape="invhouse"] +35 [label="35: Start function_call_init_div0\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 36]\n NULLIFY(&a,false); [line 36]\n " color=yellow style=filled] - 35 -> 38 ; -34 [label="34: + \n NULLIFY(&a,false); [line 37]\n " ] + 35 -> 41 ; +34 [label="34: Return Stmt \n *&return:int =1 [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] 34 -> 33 ; -33 [label="33: Exit function_call_init_div0 \n " color=yellow style=filled] +33 [label="33: Exit get1 \n " color=yellow style=filled] -32 [label="32: Start function_call_init_div0\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 36]\n NULLIFY(&a,false); [line 36]\n " color=yellow style=filled] +32 [label="32: Start get1\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 34]\n " color=yellow style=filled] - 32 -> 37 ; -31 [label="31: Return Stmt \n *&return:int =1 [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] + 32 -> 34 ; +31 [label="31: Return Stmt \n n$2=*&a:int [line 30]\n n$3=*&b:int [line 30]\n *&return:int =(1 / (n$2 + n$3)) [line 30]\n REMOVE_TEMPS(n$2,n$3); [line 30]\n NULLIFY(&a,false); [line 30]\n NULLIFY(&b,false); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"] - 31 -> 30 ; -30 [label="30: Exit get1 \n " color=yellow style=filled] + 31 -> 19 ; +30 [label="30: Return Stmt \n NULLIFY(&a,false); [line 28]\n NULLIFY(&b,false); [line 28]\n *&return:int =1 [line 28]\n APPLY_ABSTRACTION; [line 28]\n " shape="box"] -29 [label="29: Start get1\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 34]\n " color=yellow style=filled] + 30 -> 19 ; +29 [label="29: DeclStmt \n *&b:int =0 [line 27]\n " shape="box"] - 29 -> 31 ; -28 [label="28: Return Stmt \n n$2=*&a:int [line 30]\n n$3=*&b:int [line 30]\n *&return:int =(1 / (n$2 + n$3)) [line 30]\n REMOVE_TEMPS(n$2,n$3); [line 30]\n NULLIFY(&a,false); [line 30]\n NULLIFY(&b,false); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"] + 29 -> 27 ; + 29 -> 28 ; +28 [label="28: Prune (false branch) \n n$1=*&b:int [line 27]\n PRUNE((n$1 == 0), false); [line 27]\n REMOVE_TEMPS(n$1); [line 27]\n " shape="invhouse"] - 28 -> 17 ; -27 [label="27: Return Stmt \n NULLIFY(&a,false); [line 28]\n NULLIFY(&b,false); [line 28]\n *&return:int =1 [line 28]\n APPLY_ABSTRACTION; [line 28]\n " shape="box"] + 28 -> 31 ; +27 [label="27: Prune (true branch) \n n$1=*&b:int [line 27]\n PRUNE((n$1 != 0), true); [line 27]\n REMOVE_TEMPS(n$1); [line 27]\n " shape="invhouse"] - 27 -> 17 ; -26 [label="26: DeclStmt \n *&b:int =0 [line 27]\n " shape="box"] + 27 -> 30 ; +26 [label="26: + \n " ] - 26 -> 24 ; - 26 -> 25 ; -25 [label="25: Prune (false branch) \n n$1=*&b:int [line 27]\n PRUNE((n$1 == 0), false); [line 27]\n REMOVE_TEMPS(n$1); [line 27]\n " shape="invhouse"] + 26 -> 20 ; +25 [label="25: Return Stmt \n NULLIFY(&a,false); [line 26]\n *&return:int =1 [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] - 25 -> 28 ; -24 [label="24: Prune (true branch) \n n$1=*&b:int [line 27]\n PRUNE((n$1 != 0), true); [line 27]\n REMOVE_TEMPS(n$1); [line 27]\n " shape="invhouse"] + 25 -> 19 ; +24 [label="24: DeclStmt \n *&a:int =0 [line 25]\n " shape="box"] - 24 -> 27 ; -23 [label="23: + \n " ] + 24 -> 22 ; + 24 -> 23 ; +23 [label="23: Prune (false branch) \n n$0=*&a:int [line 25]\n PRUNE((n$0 == 0), false); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] - 23 -> 18 ; -22 [label="22: Return Stmt \n NULLIFY(&a,false); [line 26]\n *&return:int =1 [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] + 23 -> 29 ; +22 [label="22: Prune (true branch) \n n$0=*&a:int [line 25]\n PRUNE((n$0 != 0), true); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] - 22 -> 17 ; -21 [label="21: DeclStmt \n *&a:int =0 [line 25]\n " shape="box"] + 22 -> 25 ; +21 [label="21: between_join_and_exit \n NULLIFY(&a,false); [line 25]\n NULLIFY(&b,false); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] 21 -> 19 ; - 21 -> 20 ; -20 [label="20: Prune (false branch) \n n$0=*&a:int [line 25]\n PRUNE((n$0 == 0), false); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] +20 [label="20: + \n " ] - 20 -> 26 ; -19 [label="19: Prune (true branch) \n n$0=*&a:int [line 25]\n PRUNE((n$0 != 0), true); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] + 20 -> 21 ; +19 [label="19: Exit simple_inif_elseif_div0 \n " color=yellow style=filled] - 19 -> 22 ; -18 [label="18: + \n NULLIFY(&a,false); [line 25]\n NULLIFY(&b,false); [line 25]\n " ] +18 [label="18: Start simple_inif_elseif_div0\nFormals: \nLocals: a:int b:int \n DECLARE_LOCALS(&return,&a,&b); [line 24]\n NULLIFY(&a,false); [line 24]\n NULLIFY(&b,false); [line 24]\n " color=yellow style=filled] - 18 -> 17 ; -17 [label="17: Exit simple_inif_elseif_div0 \n " color=yellow style=filled] + 18 -> 24 ; +17 [label="17: Return Stmt \n n$2=*&a:int [line 20]\n *&return:int =(1 / n$2) [line 20]\n REMOVE_TEMPS(n$2); [line 20]\n NULLIFY(&a,false); [line 20]\n APPLY_ABSTRACTION; [line 20]\n " shape="box"] -16 [label="16: Start simple_inif_elseif_div0\nFormals: \nLocals: a:int b:int \n DECLARE_LOCALS(&return,&a,&b); [line 24]\n NULLIFY(&a,false); [line 24]\n NULLIFY(&b,false); [line 24]\n " color=yellow style=filled] + 17 -> 10 ; +16 [label="16: Return Stmt \n n$1=*&a:int [line 18]\n *&return:int =n$1 [line 18]\n REMOVE_TEMPS(n$1); [line 18]\n NULLIFY(&a,false); [line 18]\n APPLY_ABSTRACTION; [line 18]\n " shape="box"] - 16 -> 21 ; -15 [label="15: Return Stmt \n n$2=*&a:int [line 20]\n *&return:int =(1 / n$2) [line 20]\n REMOVE_TEMPS(n$2); [line 20]\n NULLIFY(&a,false); [line 20]\n APPLY_ABSTRACTION; [line 20]\n " shape="box"] + 16 -> 10 ; +15 [label="15: DeclStmt \n *&a:int =0 [line 17]\n " shape="box"] - 15 -> 9 ; -14 [label="14: Return Stmt \n n$1=*&a:int [line 18]\n *&return:int =n$1 [line 18]\n REMOVE_TEMPS(n$1); [line 18]\n NULLIFY(&a,false); [line 18]\n APPLY_ABSTRACTION; [line 18]\n " shape="box"] + 15 -> 13 ; + 15 -> 14 ; +14 [label="14: Prune (false branch) \n n$0=*&a:int [line 17]\n PRUNE((n$0 == 0), false); [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n " shape="invhouse"] - 14 -> 9 ; -13 [label="13: DeclStmt \n *&a:int =0 [line 17]\n " shape="box"] + 14 -> 17 ; +13 [label="13: Prune (true branch) \n n$0=*&a:int [line 17]\n PRUNE((n$0 != 0), true); [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n " shape="invhouse"] - 13 -> 11 ; - 13 -> 12 ; -12 [label="12: Prune (false branch) \n n$0=*&a:int [line 17]\n PRUNE((n$0 == 0), false); [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n " shape="invhouse"] + 13 -> 16 ; +12 [label="12: between_join_and_exit \n NULLIFY(&a,false); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"] - 12 -> 15 ; -11 [label="11: Prune (true branch) \n n$0=*&a:int [line 17]\n PRUNE((n$0 != 0), true); [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n " shape="invhouse"] + 12 -> 10 ; +11 [label="11: + \n " ] - 11 -> 14 ; -10 [label="10: + \n NULLIFY(&a,false); [line 17]\n " ] + 11 -> 12 ; +10 [label="10: Exit simple_init_div0 \n " color=yellow style=filled] - 10 -> 9 ; -9 [label="9: Exit simple_init_div0 \n " color=yellow style=filled] +9 [label="9: Start simple_init_div0\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 16]\n NULLIFY(&a,false); [line 16]\n " color=yellow style=filled] -8 [label="8: Start simple_init_div0\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 16]\n NULLIFY(&a,false); [line 16]\n " color=yellow style=filled] + 9 -> 15 ; +8 [label="8: Return Stmt \n n$1=*&a:int [line 12]\n *&return:int =(1 / n$1) [line 12]\n REMOVE_TEMPS(n$1); [line 12]\n NULLIFY(&a,false); [line 12]\n APPLY_ABSTRACTION; [line 12]\n " shape="box"] - 8 -> 13 ; -7 [label="7: Return Stmt \n n$1=*&a:int [line 12]\n *&return:int =(1 / n$1) [line 12]\n REMOVE_TEMPS(n$1); [line 12]\n NULLIFY(&a,false); [line 12]\n APPLY_ABSTRACTION; [line 12]\n " shape="box"] + 8 -> 2 ; +7 [label="7: DeclStmt \n *&a:int =1 [line 11]\n " shape="box"] - 7 -> 2 ; -6 [label="6: DeclStmt \n *&a:int =1 [line 11]\n " shape="box"] + 7 -> 5 ; + 7 -> 6 ; +6 [label="6: Prune (false branch) \n n$0=*&a:int [line 11]\n PRUNE((n$0 == 0), false); [line 11]\n REMOVE_TEMPS(n$0); [line 11]\n " shape="invhouse"] - 6 -> 4 ; - 6 -> 5 ; -5 [label="5: Prune (false branch) \n n$0=*&a:int [line 11]\n PRUNE((n$0 == 0), false); [line 11]\n REMOVE_TEMPS(n$0); [line 11]\n " shape="invhouse"] + 6 -> 3 ; +5 [label="5: Prune (true branch) \n n$0=*&a:int [line 11]\n PRUNE((n$0 != 0), true); [line 11]\n REMOVE_TEMPS(n$0); [line 11]\n " shape="invhouse"] - 5 -> 3 ; -4 [label="4: Prune (true branch) \n n$0=*&a:int [line 11]\n PRUNE((n$0 != 0), true); [line 11]\n REMOVE_TEMPS(n$0); [line 11]\n " shape="invhouse"] + 5 -> 8 ; +4 [label="4: between_join_and_exit \n NULLIFY(&a,false); [line 11]\n APPLY_ABSTRACTION; [line 11]\n " shape="box"] - 4 -> 7 ; -3 [label="3: + \n NULLIFY(&a,false); [line 11]\n " ] + 4 -> 2 ; +3 [label="3: + \n " ] - 3 -> 2 ; + 3 -> 4 ; 2 [label="2: Exit simple_init_div1 \n " color=yellow style=filled] 1 [label="1: Start simple_init_div1\nFormals: \nLocals: a:int \n DECLARE_LOCALS(&return,&a); [line 10]\n NULLIFY(&a,false); [line 10]\n " color=yellow style=filled] - 1 -> 6 ; + 1 -> 7 ; } diff --git a/infer/tests/codetoanalyze/cpp/frontend/reference/reference_struct_e2e.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/reference/reference_struct_e2e.cpp.dot index f11b10940..2125fd9de 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/reference/reference_struct_e2e.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/reference/reference_struct_e2e.cpp.dot @@ -1,328 +1,344 @@ digraph iCFG { -119 [label="119: Call _fun_X_zero \n n$4=_fun_get_global_ref() [line 124]\n n$5=*n$4:class X [line 124]\n _fun_X_zero(n$4:class X &) [line 124]\n REMOVE_TEMPS(n$4,n$5); [line 124]\n " shape="box"] +123 [label="123: Call _fun_X_zero \n n$4=_fun_get_global_ref() [line 124]\n n$5=*n$4:class X [line 124]\n _fun_X_zero(n$4:class X &) [line 124]\n REMOVE_TEMPS(n$4,n$5); [line 124]\n " shape="box"] - 119 -> 118 ; -118 [label="118: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ref() [line 125]\n *n$3.f:int =1 [line 125]\n REMOVE_TEMPS(n$3); [line 125]\n " shape="box"] + 123 -> 122 ; +122 [label="122: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ref() [line 125]\n *n$3.f:int =1 [line 125]\n REMOVE_TEMPS(n$3); [line 125]\n " shape="box"] + + + 122 -> 121 ; +121 [label="121: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 126]\n n$1=*n$0:class X [line 126]\n n$2=_fun_X_div(n$0:class X &) [line 126]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 126]\n APPLY_ABSTRACTION; [line 126]\n " shape="box"] + + + 121 -> 120 ; +120 [label="120: Exit get_global_ref_div1_field \n " color=yellow style=filled] + + +119 [label="119: Start get_global_ref_div1_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 123]\n " color=yellow style=filled] + + + 119 -> 123 ; +118 [label="118: Call _fun_X_nonzero \n n$4=_fun_get_global_ref() [line 118]\n n$5=*n$4:class X [line 118]\n _fun_X_nonzero(n$4:class X &) [line 118]\n REMOVE_TEMPS(n$4,n$5); [line 118]\n " shape="box"] 118 -> 117 ; -117 [label="117: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 126]\n n$1=*n$0:class X [line 126]\n n$2=_fun_X_div(n$0:class X &) [line 126]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 126]\n APPLY_ABSTRACTION; [line 126]\n " shape="box"] +117 [label="117: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ref() [line 119]\n *n$3.f:int =0 [line 119]\n REMOVE_TEMPS(n$3); [line 119]\n " shape="box"] 117 -> 116 ; -116 [label="116: Exit get_global_ref_div1_field \n " color=yellow style=filled] +116 [label="116: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 120]\n n$1=*n$0:class X [line 120]\n n$2=_fun_X_div(n$0:class X &) [line 120]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 120]\n APPLY_ABSTRACTION; [line 120]\n " shape="box"] -115 [label="115: Start get_global_ref_div1_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 123]\n " color=yellow style=filled] + 116 -> 115 ; +115 [label="115: Exit get_global_ref_div0_field \n " color=yellow style=filled] - 115 -> 119 ; -114 [label="114: Call _fun_X_nonzero \n n$4=_fun_get_global_ref() [line 118]\n n$5=*n$4:class X [line 118]\n _fun_X_nonzero(n$4:class X &) [line 118]\n REMOVE_TEMPS(n$4,n$5); [line 118]\n " shape="box"] +114 [label="114: Start get_global_ref_div0_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 117]\n " color=yellow style=filled] - 114 -> 113 ; -113 [label="113: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ref() [line 119]\n *n$3.f:int =0 [line 119]\n REMOVE_TEMPS(n$3); [line 119]\n " shape="box"] + 114 -> 118 ; +113 [label="113: BinaryOperatorStmt: Assign \n n$5=_fun_get_global_ref() [line 112]\n *n$5.f:int =0 [line 112]\n REMOVE_TEMPS(n$5); [line 112]\n " shape="box"] 113 -> 112 ; -112 [label="112: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 120]\n n$1=*n$0:class X [line 120]\n n$2=_fun_X_div(n$0:class X &) [line 120]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 120]\n APPLY_ABSTRACTION; [line 120]\n " shape="box"] +112 [label="112: Call _fun_X_nonzero \n n$3=_fun_get_global_ref() [line 113]\n n$4=*n$3:class X [line 113]\n _fun_X_nonzero(n$3:class X &) [line 113]\n REMOVE_TEMPS(n$3,n$4); [line 113]\n " shape="box"] 112 -> 111 ; -111 [label="111: Exit get_global_ref_div0_field \n " color=yellow style=filled] +111 [label="111: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 114]\n n$1=*n$0:class X [line 114]\n n$2=_fun_X_div(n$0:class X &) [line 114]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 114]\n APPLY_ABSTRACTION; [line 114]\n " shape="box"] -110 [label="110: Start get_global_ref_div0_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 117]\n " color=yellow style=filled] + 111 -> 110 ; +110 [label="110: Exit get_global_ref_div1_method \n " color=yellow style=filled] - 110 -> 114 ; -109 [label="109: BinaryOperatorStmt: Assign \n n$5=_fun_get_global_ref() [line 112]\n *n$5.f:int =0 [line 112]\n REMOVE_TEMPS(n$5); [line 112]\n " shape="box"] +109 [label="109: Start get_global_ref_div1_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 111]\n " color=yellow style=filled] - 109 -> 108 ; -108 [label="108: Call _fun_X_nonzero \n n$3=_fun_get_global_ref() [line 113]\n n$4=*n$3:class X [line 113]\n _fun_X_nonzero(n$3:class X &) [line 113]\n REMOVE_TEMPS(n$3,n$4); [line 113]\n " shape="box"] + 109 -> 113 ; +108 [label="108: BinaryOperatorStmt: Assign \n n$5=_fun_get_global_ref() [line 106]\n *n$5.f:int =1 [line 106]\n REMOVE_TEMPS(n$5); [line 106]\n " shape="box"] 108 -> 107 ; -107 [label="107: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 114]\n n$1=*n$0:class X [line 114]\n n$2=_fun_X_div(n$0:class X &) [line 114]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 114]\n APPLY_ABSTRACTION; [line 114]\n " shape="box"] +107 [label="107: Call _fun_X_zero \n n$3=_fun_get_global_ref() [line 107]\n n$4=*n$3:class X [line 107]\n _fun_X_zero(n$3:class X &) [line 107]\n REMOVE_TEMPS(n$3,n$4); [line 107]\n " shape="box"] 107 -> 106 ; -106 [label="106: Exit get_global_ref_div1_method \n " color=yellow style=filled] +106 [label="106: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 108]\n n$1=*n$0:class X [line 108]\n n$2=_fun_X_div(n$0:class X &) [line 108]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 108]\n APPLY_ABSTRACTION; [line 108]\n " shape="box"] -105 [label="105: Start get_global_ref_div1_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 111]\n " color=yellow style=filled] + 106 -> 105 ; +105 [label="105: Exit get_global_ref_div0_method \n " color=yellow style=filled] - 105 -> 109 ; -104 [label="104: BinaryOperatorStmt: Assign \n n$5=_fun_get_global_ref() [line 106]\n *n$5.f:int =1 [line 106]\n REMOVE_TEMPS(n$5); [line 106]\n " shape="box"] +104 [label="104: Start get_global_ref_div0_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 105]\n " color=yellow style=filled] - 104 -> 103 ; -103 [label="103: Call _fun_X_zero \n n$3=_fun_get_global_ref() [line 107]\n n$4=*n$3:class X [line 107]\n _fun_X_zero(n$3:class X &) [line 107]\n REMOVE_TEMPS(n$3,n$4); [line 107]\n " shape="box"] + 104 -> 108 ; +103 [label="103: Call _fun_set_field_ref \n n$3=*&x:class X & [line 101]\n _fun_set_field_ref(n$3:class X &,1:int ) [line 101]\n REMOVE_TEMPS(n$3); [line 101]\n " shape="box"] 103 -> 102 ; -102 [label="102: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 108]\n n$1=*n$0:class X [line 108]\n n$2=_fun_X_div(n$0:class X &) [line 108]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 108]\n APPLY_ABSTRACTION; [line 108]\n " shape="box"] +102 [label="102: Return Stmt \n n$0=*&x:class X & [line 102]\n n$1=*n$0:class X [line 102]\n n$2=_fun_X_div(n$0:class X &) [line 102]\n *&return:int =n$2 [line 102]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 102]\n NULLIFY(&x,false); [line 102]\n APPLY_ABSTRACTION; [line 102]\n " shape="box"] 102 -> 101 ; -101 [label="101: Exit get_global_ref_div0_method \n " color=yellow style=filled] +101 [label="101: Exit field_div1_ref \n " color=yellow style=filled] -100 [label="100: Start get_global_ref_div0_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 105]\n " color=yellow style=filled] +100 [label="100: Start field_div1_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 100]\n " color=yellow style=filled] - 100 -> 104 ; -99 [label="99: Call _fun_set_field_ref \n n$3=*&x:class X & [line 101]\n _fun_set_field_ref(n$3:class X &,1:int ) [line 101]\n REMOVE_TEMPS(n$3); [line 101]\n " shape="box"] + 100 -> 103 ; +99 [label="99: Call _fun_set_field_ref \n n$3=*&x:class X & [line 96]\n _fun_set_field_ref(n$3:class X &,0:int ) [line 96]\n REMOVE_TEMPS(n$3); [line 96]\n " shape="box"] 99 -> 98 ; -98 [label="98: Return Stmt \n n$0=*&x:class X & [line 102]\n n$1=*n$0:class X [line 102]\n n$2=_fun_X_div(n$0:class X &) [line 102]\n *&return:int =n$2 [line 102]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 102]\n NULLIFY(&x,false); [line 102]\n APPLY_ABSTRACTION; [line 102]\n " shape="box"] +98 [label="98: Return Stmt \n n$0=*&x:class X & [line 97]\n n$1=*n$0:class X [line 97]\n n$2=_fun_X_div(n$0:class X &) [line 97]\n *&return:int =n$2 [line 97]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 97]\n NULLIFY(&x,false); [line 97]\n APPLY_ABSTRACTION; [line 97]\n " shape="box"] 98 -> 97 ; -97 [label="97: Exit field_div1_ref \n " color=yellow style=filled] +97 [label="97: Exit field_div0_ref \n " color=yellow style=filled] -96 [label="96: Start field_div1_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 100]\n " color=yellow style=filled] +96 [label="96: Start field_div0_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 95]\n " color=yellow style=filled] 96 -> 99 ; -95 [label="95: Call _fun_set_field_ref \n n$3=*&x:class X & [line 96]\n _fun_set_field_ref(n$3:class X &,0:int ) [line 96]\n REMOVE_TEMPS(n$3); [line 96]\n " shape="box"] +95 [label="95: Call _fun_nonzero_ref \n n$3=*&x:class X & [line 91]\n _fun_nonzero_ref(n$3:class X &) [line 91]\n REMOVE_TEMPS(n$3); [line 91]\n " shape="box"] 95 -> 94 ; -94 [label="94: Return Stmt \n n$0=*&x:class X & [line 97]\n n$1=*n$0:class X [line 97]\n n$2=_fun_X_div(n$0:class X &) [line 97]\n *&return:int =n$2 [line 97]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 97]\n NULLIFY(&x,false); [line 97]\n APPLY_ABSTRACTION; [line 97]\n " shape="box"] +94 [label="94: Return Stmt \n n$0=*&x:class X & [line 92]\n n$1=*n$0:class X [line 92]\n n$2=_fun_X_div(n$0:class X &) [line 92]\n *&return:int =n$2 [line 92]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 92]\n NULLIFY(&x,false); [line 92]\n APPLY_ABSTRACTION; [line 92]\n " shape="box"] 94 -> 93 ; -93 [label="93: Exit field_div0_ref \n " color=yellow style=filled] +93 [label="93: Exit method_div1_ref \n " color=yellow style=filled] -92 [label="92: Start field_div0_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 95]\n " color=yellow style=filled] +92 [label="92: Start method_div1_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 90]\n " color=yellow style=filled] 92 -> 95 ; -91 [label="91: Call _fun_nonzero_ref \n n$3=*&x:class X & [line 91]\n _fun_nonzero_ref(n$3:class X &) [line 91]\n REMOVE_TEMPS(n$3); [line 91]\n " shape="box"] +91 [label="91: Call _fun_zero_ref \n n$3=*&x:class X & [line 86]\n _fun_zero_ref(n$3:class X &) [line 86]\n REMOVE_TEMPS(n$3); [line 86]\n " shape="box"] 91 -> 90 ; -90 [label="90: Return Stmt \n n$0=*&x:class X & [line 92]\n n$1=*n$0:class X [line 92]\n n$2=_fun_X_div(n$0:class X &) [line 92]\n *&return:int =n$2 [line 92]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 92]\n NULLIFY(&x,false); [line 92]\n APPLY_ABSTRACTION; [line 92]\n " shape="box"] +90 [label="90: Return Stmt \n n$0=*&x:class X & [line 87]\n n$1=*n$0:class X [line 87]\n n$2=_fun_X_div(n$0:class X &) [line 87]\n *&return:int =n$2 [line 87]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 87]\n NULLIFY(&x,false); [line 87]\n APPLY_ABSTRACTION; [line 87]\n " shape="box"] 90 -> 89 ; -89 [label="89: Exit method_div1_ref \n " color=yellow style=filled] +89 [label="89: Exit method_div0_ref \n " color=yellow style=filled] -88 [label="88: Start method_div1_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 90]\n " color=yellow style=filled] +88 [label="88: Start method_div0_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 85]\n " color=yellow style=filled] 88 -> 91 ; -87 [label="87: Call _fun_zero_ref \n n$3=*&x:class X & [line 86]\n _fun_zero_ref(n$3:class X &) [line 86]\n REMOVE_TEMPS(n$3); [line 86]\n " shape="box"] +87 [label="87: Call _fun_X_zero \n n$4=_fun_get_global_ptr() [line 80]\n n$5=*n$4:class X [line 80]\n _fun_X_zero(n$4:class X *) [line 80]\n REMOVE_TEMPS(n$4,n$5); [line 80]\n " shape="box"] 87 -> 86 ; -86 [label="86: Return Stmt \n n$0=*&x:class X & [line 87]\n n$1=*n$0:class X [line 87]\n n$2=_fun_X_div(n$0:class X &) [line 87]\n *&return:int =n$2 [line 87]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 87]\n NULLIFY(&x,false); [line 87]\n APPLY_ABSTRACTION; [line 87]\n " shape="box"] +86 [label="86: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ptr() [line 81]\n *n$3.f:int =1 [line 81]\n REMOVE_TEMPS(n$3); [line 81]\n " shape="box"] 86 -> 85 ; -85 [label="85: Exit method_div0_ref \n " color=yellow style=filled] +85 [label="85: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 82]\n n$1=*n$0:class X [line 82]\n n$2=_fun_X_div(n$0:class X *) [line 82]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 82]\n APPLY_ABSTRACTION; [line 82]\n " shape="box"] -84 [label="84: Start method_div0_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 85]\n " color=yellow style=filled] + 85 -> 84 ; +84 [label="84: Exit get_global_ptr_div1_field \n " color=yellow style=filled] - 84 -> 87 ; -83 [label="83: Call _fun_X_zero \n n$4=_fun_get_global_ptr() [line 80]\n n$5=*n$4:class X [line 80]\n _fun_X_zero(n$4:class X *) [line 80]\n REMOVE_TEMPS(n$4,n$5); [line 80]\n " shape="box"] +83 [label="83: Start get_global_ptr_div1_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 79]\n " color=yellow style=filled] - 83 -> 82 ; -82 [label="82: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ptr() [line 81]\n *n$3.f:int =1 [line 81]\n REMOVE_TEMPS(n$3); [line 81]\n " shape="box"] + 83 -> 87 ; +82 [label="82: Call _fun_X_nonzero \n n$4=_fun_get_global_ptr() [line 74]\n n$5=*n$4:class X [line 74]\n _fun_X_nonzero(n$4:class X *) [line 74]\n REMOVE_TEMPS(n$4,n$5); [line 74]\n " shape="box"] 82 -> 81 ; -81 [label="81: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 82]\n n$1=*n$0:class X [line 82]\n n$2=_fun_X_div(n$0:class X *) [line 82]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 82]\n APPLY_ABSTRACTION; [line 82]\n " shape="box"] +81 [label="81: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ptr() [line 75]\n *n$3.f:int =0 [line 75]\n REMOVE_TEMPS(n$3); [line 75]\n " shape="box"] 81 -> 80 ; -80 [label="80: Exit get_global_ptr_div1_field \n " color=yellow style=filled] +80 [label="80: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 76]\n n$1=*n$0:class X [line 76]\n n$2=_fun_X_div(n$0:class X *) [line 76]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 76]\n APPLY_ABSTRACTION; [line 76]\n " shape="box"] -79 [label="79: Start get_global_ptr_div1_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 79]\n " color=yellow style=filled] + 80 -> 79 ; +79 [label="79: Exit get_global_ptr_div0_field \n " color=yellow style=filled] - 79 -> 83 ; -78 [label="78: Call _fun_X_nonzero \n n$4=_fun_get_global_ptr() [line 74]\n n$5=*n$4:class X [line 74]\n _fun_X_nonzero(n$4:class X *) [line 74]\n REMOVE_TEMPS(n$4,n$5); [line 74]\n " shape="box"] +78 [label="78: Start get_global_ptr_div0_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 73]\n " color=yellow style=filled] - 78 -> 77 ; -77 [label="77: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ptr() [line 75]\n *n$3.f:int =0 [line 75]\n REMOVE_TEMPS(n$3); [line 75]\n " shape="box"] + 78 -> 82 ; +77 [label="77: BinaryOperatorStmt: Assign \n n$5=_fun_get_global_ptr() [line 68]\n *n$5.f:int =0 [line 68]\n REMOVE_TEMPS(n$5); [line 68]\n " shape="box"] 77 -> 76 ; -76 [label="76: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 76]\n n$1=*n$0:class X [line 76]\n n$2=_fun_X_div(n$0:class X *) [line 76]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 76]\n APPLY_ABSTRACTION; [line 76]\n " shape="box"] +76 [label="76: Call _fun_X_nonzero \n n$3=_fun_get_global_ptr() [line 69]\n n$4=*n$3:class X [line 69]\n _fun_X_nonzero(n$3:class X *) [line 69]\n REMOVE_TEMPS(n$3,n$4); [line 69]\n " shape="box"] 76 -> 75 ; -75 [label="75: Exit get_global_ptr_div0_field \n " color=yellow style=filled] +75 [label="75: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 70]\n n$1=*n$0:class X [line 70]\n n$2=_fun_X_div(n$0:class X *) [line 70]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 70]\n APPLY_ABSTRACTION; [line 70]\n " shape="box"] -74 [label="74: Start get_global_ptr_div0_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 73]\n " color=yellow style=filled] + 75 -> 74 ; +74 [label="74: Exit get_global_ptr_div1_method \n " color=yellow style=filled] - 74 -> 78 ; -73 [label="73: BinaryOperatorStmt: Assign \n n$5=_fun_get_global_ptr() [line 68]\n *n$5.f:int =0 [line 68]\n REMOVE_TEMPS(n$5); [line 68]\n " shape="box"] +73 [label="73: Start get_global_ptr_div1_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 67]\n " color=yellow style=filled] - 73 -> 72 ; -72 [label="72: Call _fun_X_nonzero \n n$3=_fun_get_global_ptr() [line 69]\n n$4=*n$3:class X [line 69]\n _fun_X_nonzero(n$3:class X *) [line 69]\n REMOVE_TEMPS(n$3,n$4); [line 69]\n " shape="box"] + 73 -> 77 ; +72 [label="72: BinaryOperatorStmt: Assign \n n$5=_fun_get_global_ptr() [line 62]\n *n$5.f:int =1 [line 62]\n REMOVE_TEMPS(n$5); [line 62]\n " shape="box"] 72 -> 71 ; -71 [label="71: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 70]\n n$1=*n$0:class X [line 70]\n n$2=_fun_X_div(n$0:class X *) [line 70]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 70]\n APPLY_ABSTRACTION; [line 70]\n " shape="box"] +71 [label="71: Call _fun_X_zero \n n$3=_fun_get_global_ptr() [line 63]\n n$4=*n$3:class X [line 63]\n _fun_X_zero(n$3:class X *) [line 63]\n REMOVE_TEMPS(n$3,n$4); [line 63]\n " shape="box"] 71 -> 70 ; -70 [label="70: Exit get_global_ptr_div1_method \n " color=yellow style=filled] +70 [label="70: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 64]\n n$1=*n$0:class X [line 64]\n n$2=_fun_X_div(n$0:class X *) [line 64]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 64]\n APPLY_ABSTRACTION; [line 64]\n " shape="box"] -69 [label="69: Start get_global_ptr_div1_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 67]\n " color=yellow style=filled] + 70 -> 69 ; +69 [label="69: Exit get_global_ptr_div0_method \n " color=yellow style=filled] - 69 -> 73 ; -68 [label="68: BinaryOperatorStmt: Assign \n n$5=_fun_get_global_ptr() [line 62]\n *n$5.f:int =1 [line 62]\n REMOVE_TEMPS(n$5); [line 62]\n " shape="box"] +68 [label="68: Start get_global_ptr_div0_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 61]\n " color=yellow style=filled] - 68 -> 67 ; -67 [label="67: Call _fun_X_zero \n n$3=_fun_get_global_ptr() [line 63]\n n$4=*n$3:class X [line 63]\n _fun_X_zero(n$3:class X *) [line 63]\n REMOVE_TEMPS(n$3,n$4); [line 63]\n " shape="box"] + 68 -> 72 ; +67 [label="67: Call _fun_set_field_ptr \n n$4=*&x:class X * [line 56]\n _fun_set_field_ptr(n$4:class X *,1:int ) [line 56]\n REMOVE_TEMPS(n$4); [line 56]\n " shape="box"] 67 -> 66 ; -66 [label="66: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 64]\n n$1=*n$0:class X [line 64]\n n$2=_fun_X_div(n$0:class X *) [line 64]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 64]\n APPLY_ABSTRACTION; [line 64]\n " shape="box"] +66 [label="66: Return Stmt \n n$1=*&x:class X * [line 57]\n n$2=*n$1:class X [line 57]\n n$3=_fun_X_div(n$1:class X *) [line 57]\n *&return:int =n$3 [line 57]\n REMOVE_TEMPS(n$1,n$2,n$3); [line 57]\n NULLIFY(&x,false); [line 57]\n APPLY_ABSTRACTION; [line 57]\n " shape="box"] - 66 -> 65 ; -65 [label="65: Exit get_global_ptr_div0_method \n " color=yellow style=filled] + 66 -> 61 ; +65 [label="65: Prune (false branch) \n n$0=*&x:class X * [line 55]\n PRUNE((n$0 == 0), false); [line 55]\n REMOVE_TEMPS(n$0); [line 55]\n " shape="invhouse"] -64 [label="64: Start get_global_ptr_div0_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 61]\n " color=yellow style=filled] + 65 -> 62 ; +64 [label="64: Prune (true branch) \n n$0=*&x:class X * [line 55]\n PRUNE((n$0 != 0), true); [line 55]\n REMOVE_TEMPS(n$0); [line 55]\n " shape="invhouse"] - 64 -> 68 ; -63 [label="63: Call _fun_set_field_ptr \n n$4=*&x:class X * [line 56]\n _fun_set_field_ptr(n$4:class X *,1:int ) [line 56]\n REMOVE_TEMPS(n$4); [line 56]\n " shape="box"] + 64 -> 67 ; +63 [label="63: between_join_and_exit \n NULLIFY(&x,false); [line 55]\n APPLY_ABSTRACTION; [line 55]\n " shape="box"] - 63 -> 62 ; -62 [label="62: Return Stmt \n n$1=*&x:class X * [line 57]\n n$2=*n$1:class X [line 57]\n n$3=_fun_X_div(n$1:class X *) [line 57]\n *&return:int =n$3 [line 57]\n REMOVE_TEMPS(n$1,n$2,n$3); [line 57]\n NULLIFY(&x,false); [line 57]\n APPLY_ABSTRACTION; [line 57]\n " shape="box"] + 63 -> 61 ; +62 [label="62: + \n " ] - 62 -> 58 ; -61 [label="61: Prune (false branch) \n n$0=*&x:class X * [line 55]\n PRUNE((n$0 == 0), false); [line 55]\n REMOVE_TEMPS(n$0); [line 55]\n " shape="invhouse"] + 62 -> 63 ; +61 [label="61: Exit field_div1_ptr \n " color=yellow style=filled] - 61 -> 59 ; -60 [label="60: Prune (true branch) \n n$0=*&x:class X * [line 55]\n PRUNE((n$0 != 0), true); [line 55]\n REMOVE_TEMPS(n$0); [line 55]\n " shape="invhouse"] +60 [label="60: Start field_div1_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 54]\n " color=yellow style=filled] - 60 -> 63 ; -59 [label="59: + \n NULLIFY(&x,false); [line 55]\n " ] + 60 -> 64 ; + 60 -> 65 ; +59 [label="59: Call _fun_set_field_ptr \n n$4=*&x:class X * [line 49]\n _fun_set_field_ptr(n$4:class X *,0:int ) [line 49]\n REMOVE_TEMPS(n$4); [line 49]\n " shape="box"] 59 -> 58 ; -58 [label="58: Exit field_div1_ptr \n " color=yellow style=filled] +58 [label="58: Return Stmt \n n$1=*&x:class X * [line 50]\n n$2=*n$1:class X [line 50]\n n$3=_fun_X_div(n$1:class X *) [line 50]\n *&return:int =n$3 [line 50]\n REMOVE_TEMPS(n$1,n$2,n$3); [line 50]\n NULLIFY(&x,false); [line 50]\n APPLY_ABSTRACTION; [line 50]\n " shape="box"] -57 [label="57: Start field_div1_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 54]\n " color=yellow style=filled] + 58 -> 53 ; +57 [label="57: Prune (false branch) \n n$0=*&x:class X * [line 48]\n PRUNE((n$0 == 0), false); [line 48]\n REMOVE_TEMPS(n$0); [line 48]\n " shape="invhouse"] - 57 -> 60 ; - 57 -> 61 ; -56 [label="56: Call _fun_set_field_ptr \n n$4=*&x:class X * [line 49]\n _fun_set_field_ptr(n$4:class X *,0:int ) [line 49]\n REMOVE_TEMPS(n$4); [line 49]\n " shape="box"] + 57 -> 54 ; +56 [label="56: Prune (true branch) \n n$0=*&x:class X * [line 48]\n PRUNE((n$0 != 0), true); [line 48]\n REMOVE_TEMPS(n$0); [line 48]\n " shape="invhouse"] - 56 -> 55 ; -55 [label="55: Return Stmt \n n$1=*&x:class X * [line 50]\n n$2=*n$1:class X [line 50]\n n$3=_fun_X_div(n$1:class X *) [line 50]\n *&return:int =n$3 [line 50]\n REMOVE_TEMPS(n$1,n$2,n$3); [line 50]\n NULLIFY(&x,false); [line 50]\n APPLY_ABSTRACTION; [line 50]\n " shape="box"] + 56 -> 59 ; +55 [label="55: between_join_and_exit \n NULLIFY(&x,false); [line 48]\n APPLY_ABSTRACTION; [line 48]\n " shape="box"] - 55 -> 51 ; -54 [label="54: Prune (false branch) \n n$0=*&x:class X * [line 48]\n PRUNE((n$0 == 0), false); [line 48]\n REMOVE_TEMPS(n$0); [line 48]\n " shape="invhouse"] + 55 -> 53 ; +54 [label="54: + \n " ] - 54 -> 52 ; -53 [label="53: Prune (true branch) \n n$0=*&x:class X * [line 48]\n PRUNE((n$0 != 0), true); [line 48]\n REMOVE_TEMPS(n$0); [line 48]\n " shape="invhouse"] + 54 -> 55 ; +53 [label="53: Exit field_div0_ptr \n " color=yellow style=filled] - 53 -> 56 ; -52 [label="52: + \n NULLIFY(&x,false); [line 48]\n " ] +52 [label="52: Start field_div0_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 47]\n " color=yellow style=filled] - 52 -> 51 ; -51 [label="51: Exit field_div0_ptr \n " color=yellow style=filled] + 52 -> 56 ; + 52 -> 57 ; +51 [label="51: Call _fun_nonzero_ptr \n n$4=*&x:class X * [line 42]\n _fun_nonzero_ptr(n$4:class X *) [line 42]\n REMOVE_TEMPS(n$4); [line 42]\n " shape="box"] -50 [label="50: Start field_div0_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 47]\n " color=yellow style=filled] + 51 -> 50 ; +50 [label="50: Return Stmt \n n$1=*&x:class X * [line 43]\n n$2=*n$1:class X [line 43]\n n$3=_fun_X_div(n$1:class X *) [line 43]\n *&return:int =n$3 [line 43]\n REMOVE_TEMPS(n$1,n$2,n$3); [line 43]\n NULLIFY(&x,false); [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] - 50 -> 53 ; - 50 -> 54 ; -49 [label="49: Call _fun_nonzero_ptr \n n$4=*&x:class X * [line 42]\n _fun_nonzero_ptr(n$4:class X *) [line 42]\n REMOVE_TEMPS(n$4); [line 42]\n " shape="box"] + 50 -> 45 ; +49 [label="49: Prune (false branch) \n n$0=*&x:class X * [line 41]\n PRUNE((n$0 == 0), false); [line 41]\n REMOVE_TEMPS(n$0); [line 41]\n " shape="invhouse"] - 49 -> 48 ; -48 [label="48: Return Stmt \n n$1=*&x:class X * [line 43]\n n$2=*n$1:class X [line 43]\n n$3=_fun_X_div(n$1:class X *) [line 43]\n *&return:int =n$3 [line 43]\n REMOVE_TEMPS(n$1,n$2,n$3); [line 43]\n NULLIFY(&x,false); [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] + 49 -> 46 ; +48 [label="48: Prune (true branch) \n n$0=*&x:class X * [line 41]\n PRUNE((n$0 != 0), true); [line 41]\n REMOVE_TEMPS(n$0); [line 41]\n " shape="invhouse"] - 48 -> 44 ; -47 [label="47: Prune (false branch) \n n$0=*&x:class X * [line 41]\n PRUNE((n$0 == 0), false); [line 41]\n REMOVE_TEMPS(n$0); [line 41]\n " shape="invhouse"] + 48 -> 51 ; +47 [label="47: between_join_and_exit \n NULLIFY(&x,false); [line 41]\n APPLY_ABSTRACTION; [line 41]\n " shape="box"] 47 -> 45 ; -46 [label="46: Prune (true branch) \n n$0=*&x:class X * [line 41]\n PRUNE((n$0 != 0), true); [line 41]\n REMOVE_TEMPS(n$0); [line 41]\n " shape="invhouse"] +46 [label="46: + \n " ] - 46 -> 49 ; -45 [label="45: + \n NULLIFY(&x,false); [line 41]\n " ] + 46 -> 47 ; +45 [label="45: Exit method_div1_ptr \n " color=yellow style=filled] - 45 -> 44 ; -44 [label="44: Exit method_div1_ptr \n " color=yellow style=filled] +44 [label="44: Start method_div1_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 40]\n " color=yellow style=filled] -43 [label="43: Start method_div1_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 40]\n " color=yellow style=filled] + 44 -> 48 ; + 44 -> 49 ; +43 [label="43: Call _fun_zero_ptr \n n$4=*&x:class X * [line 35]\n _fun_zero_ptr(n$4:class X *) [line 35]\n REMOVE_TEMPS(n$4); [line 35]\n " shape="box"] - 43 -> 46 ; - 43 -> 47 ; -42 [label="42: Call _fun_zero_ptr \n n$4=*&x:class X * [line 35]\n _fun_zero_ptr(n$4:class X *) [line 35]\n REMOVE_TEMPS(n$4); [line 35]\n " shape="box"] + 43 -> 42 ; +42 [label="42: Return Stmt \n n$1=*&x:class X * [line 36]\n n$2=*n$1:class X [line 36]\n n$3=_fun_X_div(n$1:class X *) [line 36]\n *&return:int =n$3 [line 36]\n REMOVE_TEMPS(n$1,n$2,n$3); [line 36]\n NULLIFY(&x,false); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] - 42 -> 41 ; -41 [label="41: Return Stmt \n n$1=*&x:class X * [line 36]\n n$2=*n$1:class X [line 36]\n n$3=_fun_X_div(n$1:class X *) [line 36]\n *&return:int =n$3 [line 36]\n REMOVE_TEMPS(n$1,n$2,n$3); [line 36]\n NULLIFY(&x,false); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] + 42 -> 37 ; +41 [label="41: Prune (false branch) \n n$0=*&x:class X * [line 34]\n PRUNE((n$0 == 0), false); [line 34]\n REMOVE_TEMPS(n$0); [line 34]\n " shape="invhouse"] - 41 -> 37 ; -40 [label="40: Prune (false branch) \n n$0=*&x:class X * [line 34]\n PRUNE((n$0 == 0), false); [line 34]\n REMOVE_TEMPS(n$0); [line 34]\n " shape="invhouse"] + 41 -> 38 ; +40 [label="40: Prune (true branch) \n n$0=*&x:class X * [line 34]\n PRUNE((n$0 != 0), true); [line 34]\n REMOVE_TEMPS(n$0); [line 34]\n " shape="invhouse"] - 40 -> 38 ; -39 [label="39: Prune (true branch) \n n$0=*&x:class X * [line 34]\n PRUNE((n$0 != 0), true); [line 34]\n REMOVE_TEMPS(n$0); [line 34]\n " shape="invhouse"] + 40 -> 43 ; +39 [label="39: between_join_and_exit \n NULLIFY(&x,false); [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] - 39 -> 42 ; -38 [label="38: + \n NULLIFY(&x,false); [line 34]\n " ] + 39 -> 37 ; +38 [label="38: + \n " ] - 38 -> 37 ; + 38 -> 39 ; 37 [label="37: Exit method_div0_ptr \n " color=yellow style=filled] 36 [label="36: Start method_div0_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 33]\n " color=yellow style=filled] - 36 -> 39 ; 36 -> 40 ; + 36 -> 41 ; 35 [label="35: Return Stmt \n *&return:class X &=&#GB$global [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/cpp/frontend/types/typeid_expr.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/types/typeid_expr.cpp.dot index 5aabf539c..79ac4d8d8 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/types/typeid_expr.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/types/typeid_expr.cpp.dot @@ -1,219 +1,239 @@ digraph iCFG { -65 [label="65: DeclStmt \n _fun_Person_Person(&person:class Person *) [line 63]\n " shape="box"] +70 [label="70: DeclStmt \n _fun_Person_Person(&person:class Person *) [line 63]\n " shape="box"] - 65 -> 60 ; -64 [label="64: Return Stmt \n *&return:int =(1 / 0) [line 67]\n NULLIFY(&person,false); [line 67]\n APPLY_ABSTRACTION; [line 67]\n " shape="box"] + 70 -> 65 ; +69 [label="69: Return Stmt \n *&return:int =(1 / 0) [line 67]\n NULLIFY(&person,false); [line 67]\n APPLY_ABSTRACTION; [line 67]\n " shape="box"] - 64 -> 58 ; -63 [label="63: Return Stmt \n *&return:int =1 [line 65]\n NULLIFY(&person,false); [line 65]\n APPLY_ABSTRACTION; [line 65]\n " shape="box"] + 69 -> 62 ; +68 [label="68: Return Stmt \n *&return:int =1 [line 65]\n NULLIFY(&person,false); [line 65]\n APPLY_ABSTRACTION; [line 65]\n " shape="box"] - 63 -> 58 ; -62 [label="62: Prune (false branch) \n PRUNE(((n$0 == n$3) == 0), false); [line 64]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 64]\n " shape="invhouse"] + 68 -> 62 ; +67 [label="67: Prune (false branch) \n PRUNE(((n$0 == n$3) == 0), false); [line 64]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 64]\n " shape="invhouse"] - 62 -> 64 ; -61 [label="61: Prune (true branch) \n PRUNE(((n$0 == n$3) != 0), true); [line 64]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 64]\n " shape="invhouse"] + 67 -> 69 ; +66 [label="66: Prune (true branch) \n PRUNE(((n$0 == n$3) != 0), true); [line 64]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 64]\n " shape="invhouse"] - 61 -> 63 ; -60 [label="60: BinaryOperatorStmt: EQ \n n$0=_fun_template_typeid(&person:class Person &) [line 64]\n n$1=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$1.__type_name:void ,&person:class Person ) [line 64]\n n$2=*n$1:class std::type_info [line 64]\n n$3=_fun_std::type_info_name(n$1:class std::type_info &) [line 64]\n " shape="box"] + 66 -> 68 ; +65 [label="65: BinaryOperatorStmt: EQ \n n$0=_fun_template_typeid(&person:class Person &) [line 64]\n n$1=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$1.__type_name:void ,&person:class Person ) [line 64]\n n$2=*n$1:class std::type_info [line 64]\n n$3=_fun_std::type_info_name(n$1:class std::type_info &) [line 64]\n " shape="box"] - 60 -> 61 ; - 60 -> 62 ; -59 [label="59: + \n NULLIFY(&person,false); [line 64]\n " ] + 65 -> 66 ; + 65 -> 67 ; +64 [label="64: between_join_and_exit \n NULLIFY(&person,false); [line 64]\n APPLY_ABSTRACTION; [line 64]\n " shape="box"] + + + 64 -> 62 ; +63 [label="63: + \n " ] + + + 63 -> 64 ; +62 [label="62: Exit template_type_id_person \n " color=yellow style=filled] + + +61 [label="61: Start template_type_id_person\nFormals: \nLocals: person:class Person \n DECLARE_LOCALS(&return,&person); [line 62]\n " color=yellow style=filled] + + + 61 -> 70 ; +60 [label="60: DeclStmt \n n$4=*&value:class Person & [line 58]\n _fun_Person_Person(&SIL_materialize_temp__n$3:class Person *,n$4:class Person &) [line 58]\n _fun_Person_Person(&result:class Person *,&SIL_materialize_temp__n$3:class Person &) [line 58]\n REMOVE_TEMPS(n$4); [line 58]\n NULLIFY(&value,false); [line 58]\n " shape="box"] + + + 60 -> 59 ; +59 [label="59: Return Stmt \n n$0=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$0.__type_name:void ) [line 59]\n n$1=*n$0:class std::type_info [line 59]\n n$2=_fun_std::type_info_name(n$0:class std::type_info &) [line 59]\n *&return:char *=n$2 [line 59]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 59]\n NULLIFY(&SIL_materialize_temp__n$3,false); [line 59]\n NULLIFY(&result,false); [line 59]\n APPLY_ABSTRACTION; [line 59]\n " shape="box"] 59 -> 58 ; -58 [label="58: Exit template_type_id_person \n " color=yellow style=filled] +58 [label="58: Exit template_typeid \n " color=yellow style=filled] -57 [label="57: Start template_type_id_person\nFormals: \nLocals: person:class Person \n DECLARE_LOCALS(&return,&person); [line 62]\n " color=yellow style=filled] +57 [label="57: Start template_typeid\nFormals: value:class Person &\nLocals: result:class Person SIL_materialize_temp__n$3:class Person \n DECLARE_LOCALS(&return,&result,&SIL_materialize_temp__n$3); [line 57]\n " color=yellow style=filled] - 57 -> 65 ; -56 [label="56: DeclStmt \n n$4=*&value:class Person & [line 58]\n _fun_Person_Person(&SIL_materialize_temp__n$3:class Person *,n$4:class Person &) [line 58]\n _fun_Person_Person(&result:class Person *,&SIL_materialize_temp__n$3:class Person &) [line 58]\n REMOVE_TEMPS(n$4); [line 58]\n NULLIFY(&value,false); [line 58]\n " shape="box"] + 57 -> 60 ; +56 [label="56: DeclStmt \n _fun_Person_Person(&person:class Person *) [line 49]\n " shape="box"] - 56 -> 55 ; -55 [label="55: Return Stmt \n n$0=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$0.__type_name:void ) [line 59]\n n$1=*n$0:class std::type_info [line 59]\n n$2=_fun_std::type_info_name(n$0:class std::type_info &) [line 59]\n *&return:char *=n$2 [line 59]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 59]\n NULLIFY(&SIL_materialize_temp__n$3,false); [line 59]\n NULLIFY(&result,false); [line 59]\n APPLY_ABSTRACTION; [line 59]\n " shape="box"] + 56 -> 51 ; +55 [label="55: Return Stmt \n *&return:int =0 [line 53]\n NULLIFY(&person,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"] - 55 -> 54 ; -54 [label="54: Exit template_typeid \n " color=yellow style=filled] + 55 -> 48 ; +54 [label="54: Return Stmt \n *&return:int =(1 / 0) [line 51]\n NULLIFY(&person,false); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"] -53 [label="53: Start template_typeid\nFormals: value:class Person &\nLocals: result:class Person SIL_materialize_temp__n$3:class Person \n DECLARE_LOCALS(&return,&result,&SIL_materialize_temp__n$3); [line 57]\n " color=yellow style=filled] + 54 -> 48 ; +53 [label="53: Prune (false branch) \n PRUNE(((n$3 == n$6) == 0), false); [line 50]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3,n$4,n$5,n$6); [line 50]\n " shape="invhouse"] - 53 -> 56 ; -52 [label="52: DeclStmt \n _fun_Person_Person(&person:class Person *) [line 49]\n " shape="box"] + 53 -> 55 ; +52 [label="52: Prune (true branch) \n PRUNE(((n$3 == n$6) != 0), true); [line 50]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3,n$4,n$5,n$6); [line 50]\n " shape="invhouse"] - 52 -> 47 ; -51 [label="51: Return Stmt \n *&return:int =0 [line 53]\n NULLIFY(&person,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"] + 52 -> 54 ; +51 [label="51: BinaryOperatorStmt: EQ \n n$0=*&ptr:class Person * [line 50]\n n$1=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$1.__type_name:void ,n$0:class Person ) [line 50]\n n$2=*n$1:class std::type_info [line 50]\n n$3=_fun_std::type_info_name(n$1:class std::type_info &) [line 50]\n n$4=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$4.__type_name:void ,&person:class Person ) [line 50]\n n$5=*n$4:class std::type_info [line 50]\n n$6=_fun_std::type_info_name(n$4:class std::type_info &) [line 50]\n NULLIFY(&ptr,false); [line 50]\n " shape="box"] - 51 -> 45 ; -50 [label="50: Return Stmt \n *&return:int =(1 / 0) [line 51]\n NULLIFY(&person,false); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"] + 51 -> 52 ; + 51 -> 53 ; +50 [label="50: between_join_and_exit \n NULLIFY(&ptr,false); [line 50]\n NULLIFY(&person,false); [line 50]\n APPLY_ABSTRACTION; [line 50]\n " shape="box"] - 50 -> 45 ; -49 [label="49: Prune (false branch) \n PRUNE(((n$3 == n$6) == 0), false); [line 50]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3,n$4,n$5,n$6); [line 50]\n " shape="invhouse"] + 50 -> 48 ; +49 [label="49: + \n " ] - 49 -> 51 ; -48 [label="48: Prune (true branch) \n PRUNE(((n$3 == n$6) != 0), true); [line 50]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3,n$4,n$5,n$6); [line 50]\n " shape="invhouse"] + 49 -> 50 ; +48 [label="48: Exit person_ptr_typeid \n " color=yellow style=filled] - 48 -> 50 ; -47 [label="47: BinaryOperatorStmt: EQ \n n$0=*&ptr:class Person * [line 50]\n n$1=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$1.__type_name:void ,n$0:class Person ) [line 50]\n n$2=*n$1:class std::type_info [line 50]\n n$3=_fun_std::type_info_name(n$1:class std::type_info &) [line 50]\n n$4=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$4.__type_name:void ,&person:class Person ) [line 50]\n n$5=*n$4:class std::type_info [line 50]\n n$6=_fun_std::type_info_name(n$4:class std::type_info &) [line 50]\n NULLIFY(&ptr,false); [line 50]\n " shape="box"] +47 [label="47: Start person_ptr_typeid\nFormals: ptr:class Person *\nLocals: person:class Person \n DECLARE_LOCALS(&return,&person); [line 48]\n " color=yellow style=filled] - 47 -> 48 ; - 47 -> 49 ; -46 [label="46: + \n NULLIFY(&ptr,false); [line 50]\n NULLIFY(&person,false); [line 50]\n " ] + 47 -> 56 ; +46 [label="46: DeclStmt \n _fun_Employee_Employee(&employee:class Employee *) [line 40]\n " shape="box"] 46 -> 45 ; -45 [label="45: Exit person_ptr_typeid \n " color=yellow style=filled] +45 [label="45: DeclStmt \n *&ptr:class Employee *=&employee [line 41]\n " shape="box"] -44 [label="44: Start person_ptr_typeid\nFormals: ptr:class Person *\nLocals: person:class Person \n DECLARE_LOCALS(&return,&person); [line 48]\n " color=yellow style=filled] + 45 -> 40 ; +44 [label="44: Return Stmt \n *&return:int =0 [line 45]\n NULLIFY(&employee,false); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"] - 44 -> 52 ; -43 [label="43: DeclStmt \n _fun_Employee_Employee(&employee:class Employee *) [line 40]\n " shape="box"] + 44 -> 37 ; +43 [label="43: Return Stmt \n *&return:int =(1 / 0) [line 43]\n NULLIFY(&employee,false); [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] - 43 -> 42 ; -42 [label="42: DeclStmt \n *&ptr:class Employee *=&employee [line 41]\n " shape="box"] + 43 -> 37 ; +42 [label="42: Prune (false branch) \n PRUNE((n$3 == 0), false); [line 42]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 42]\n " shape="invhouse"] - 42 -> 37 ; -41 [label="41: Return Stmt \n *&return:int =0 [line 45]\n NULLIFY(&employee,false); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"] + 42 -> 44 ; +41 [label="41: Prune (true branch) \n PRUNE((n$3 != 0), true); [line 42]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 42]\n " shape="invhouse"] - 41 -> 35 ; -40 [label="40: Return Stmt \n *&return:int =(1 / 0) [line 43]\n NULLIFY(&employee,false); [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] + 41 -> 43 ; +40 [label="40: Call _fun_std::type_info_operator== \n n$0=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$0.__type_name:void ,&employee:class Employee ) [line 42]\n n$1=*&ptr:class Person * [line 42]\n n$2=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$2.__type_name:void ,n$1:class Person ) [line 42]\n n$3=_fun_std::type_info_operator==(n$0:class std::type_info &,n$2:class std::type_info &) [line 42]\n NULLIFY(&ptr,false); [line 42]\n " shape="box"] - 40 -> 35 ; -39 [label="39: Prune (false branch) \n PRUNE((n$3 == 0), false); [line 42]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 42]\n " shape="invhouse"] + 40 -> 41 ; + 40 -> 42 ; +39 [label="39: between_join_and_exit \n NULLIFY(&ptr,false); [line 42]\n NULLIFY(&employee,false); [line 42]\n APPLY_ABSTRACTION; [line 42]\n " shape="box"] - 39 -> 41 ; -38 [label="38: Prune (true branch) \n PRUNE((n$3 != 0), true); [line 42]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 42]\n " shape="invhouse"] + 39 -> 37 ; +38 [label="38: + \n " ] - 38 -> 40 ; -37 [label="37: Call _fun_std::type_info_operator== \n n$0=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$0.__type_name:void ,&employee:class Employee ) [line 42]\n n$1=*&ptr:class Person * [line 42]\n n$2=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$2.__type_name:void ,n$1:class Person ) [line 42]\n n$3=_fun_std::type_info_operator==(n$0:class std::type_info &,n$2:class std::type_info &) [line 42]\n NULLIFY(&ptr,false); [line 42]\n " shape="box"] + 38 -> 39 ; +37 [label="37: Exit employee_typeid \n " color=yellow style=filled] - 37 -> 38 ; - 37 -> 39 ; -36 [label="36: + \n NULLIFY(&ptr,false); [line 42]\n NULLIFY(&employee,false); [line 42]\n " ] +36 [label="36: Start employee_typeid\nFormals: \nLocals: ptr:class Person * employee:class Employee \n DECLARE_LOCALS(&return,&ptr,&employee); [line 39]\n NULLIFY(&ptr,false); [line 39]\n " color=yellow style=filled] - 36 -> 35 ; -35 [label="35: Exit employee_typeid \n " color=yellow style=filled] + 36 -> 46 ; +35 [label="35: DeclStmt \n _fun_Person_Person(&person:class Person *) [line 29]\n " shape="box"] -34 [label="34: Start employee_typeid\nFormals: \nLocals: ptr:class Person * employee:class Employee \n DECLARE_LOCALS(&return,&ptr,&employee); [line 39]\n NULLIFY(&ptr,false); [line 39]\n " color=yellow style=filled] + 35 -> 34 ; +34 [label="34: DeclStmt \n *&t:int =3 [line 30]\n " shape="box"] - 34 -> 43 ; -33 [label="33: DeclStmt \n _fun_Person_Person(&person:class Person *) [line 29]\n " shape="box"] + 34 -> 33 ; +33 [label="33: DeclStmt \n n$5=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$5.__type_name:void ,&t:int ) [line 31]\n n$6=*n$5:class std::type_info [line 31]\n n$7=_fun_std::type_info_name(n$5:class std::type_info &) [line 31]\n *&t_type_info:char *=n$7 [line 31]\n REMOVE_TEMPS(n$5,n$6,n$7); [line 31]\n NULLIFY(&t,false); [line 31]\n " shape="box"] 33 -> 32 ; -32 [label="32: DeclStmt \n *&t:int =3 [line 30]\n " shape="box"] +32 [label="32: DeclStmt \n n$2=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$2.__type_name:void ,&person:class Person ) [line 32]\n n$3=*n$2:class std::type_info [line 32]\n n$4=_fun_std::type_info_name(n$2:class std::type_info &) [line 32]\n *&person_type_info:char *=n$4 [line 32]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 32]\n " shape="box"] - 32 -> 31 ; -31 [label="31: DeclStmt \n n$5=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$5.__type_name:void ,&t:int ) [line 31]\n n$6=*n$5:class std::type_info [line 31]\n n$7=_fun_std::type_info_name(n$5:class std::type_info &) [line 31]\n *&t_type_info:char *=n$7 [line 31]\n REMOVE_TEMPS(n$5,n$6,n$7); [line 31]\n NULLIFY(&t,false); [line 31]\n " shape="box"] + 32 -> 27 ; +31 [label="31: Return Stmt \n *&return:int =(1 / 0) [line 36]\n NULLIFY(&person,false); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] - 31 -> 30 ; -30 [label="30: DeclStmt \n n$2=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$2.__type_name:void ,&person:class Person ) [line 32]\n n$3=*n$2:class std::type_info [line 32]\n n$4=_fun_std::type_info_name(n$2:class std::type_info &) [line 32]\n *&person_type_info:char *=n$4 [line 32]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 32]\n " shape="box"] + 31 -> 24 ; +30 [label="30: Return Stmt \n *&return:int =0 [line 34]\n NULLIFY(&person,false); [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] - 30 -> 25 ; -29 [label="29: Return Stmt \n *&return:int =(1 / 0) [line 36]\n NULLIFY(&person,false); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] + 30 -> 24 ; +29 [label="29: Prune (false branch) \n PRUNE(((n$0 == n$1) == 0), false); [line 33]\n REMOVE_TEMPS(n$0,n$1); [line 33]\n " shape="invhouse"] - 29 -> 23 ; -28 [label="28: Return Stmt \n *&return:int =0 [line 34]\n NULLIFY(&person,false); [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] + 29 -> 31 ; +28 [label="28: Prune (true branch) \n PRUNE(((n$0 == n$1) != 0), true); [line 33]\n REMOVE_TEMPS(n$0,n$1); [line 33]\n " shape="invhouse"] - 28 -> 23 ; -27 [label="27: Prune (false branch) \n PRUNE(((n$0 == n$1) == 0), false); [line 33]\n REMOVE_TEMPS(n$0,n$1); [line 33]\n " shape="invhouse"] + 28 -> 30 ; +27 [label="27: BinaryOperatorStmt: EQ \n n$0=*&t_type_info:char * [line 33]\n n$1=*&person_type_info:char * [line 33]\n NULLIFY(&person_type_info,false); [line 33]\n NULLIFY(&t_type_info,false); [line 33]\n " shape="box"] + 27 -> 28 ; 27 -> 29 ; -26 [label="26: Prune (true branch) \n PRUNE(((n$0 == n$1) != 0), true); [line 33]\n REMOVE_TEMPS(n$0,n$1); [line 33]\n " shape="invhouse"] +26 [label="26: between_join_and_exit \n NULLIFY(&person_type_info,false); [line 33]\n NULLIFY(&t,false); [line 33]\n NULLIFY(&t_type_info,false); [line 33]\n NULLIFY(&person,false); [line 33]\n APPLY_ABSTRACTION; [line 33]\n " shape="box"] - 26 -> 28 ; -25 [label="25: BinaryOperatorStmt: EQ \n n$0=*&t_type_info:char * [line 33]\n n$1=*&person_type_info:char * [line 33]\n NULLIFY(&person_type_info,false); [line 33]\n NULLIFY(&t_type_info,false); [line 33]\n " shape="box"] + 26 -> 24 ; +25 [label="25: + \n " ] 25 -> 26 ; - 25 -> 27 ; -24 [label="24: + \n NULLIFY(&person_type_info,false); [line 33]\n NULLIFY(&t,false); [line 33]\n NULLIFY(&t_type_info,false); [line 33]\n NULLIFY(&person,false); [line 33]\n " ] +24 [label="24: Exit person_typeid_name \n " color=yellow style=filled] - 24 -> 23 ; -23 [label="23: Exit person_typeid_name \n " color=yellow style=filled] +23 [label="23: Start person_typeid_name\nFormals: \nLocals: person_type_info:char * t_type_info:char * t:int person:class Person \n DECLARE_LOCALS(&return,&person_type_info,&t_type_info,&t,&person); [line 28]\n NULLIFY(&person_type_info,false); [line 28]\n NULLIFY(&t,false); [line 28]\n NULLIFY(&t_type_info,false); [line 28]\n " color=yellow style=filled] -22 [label="22: Start person_typeid_name\nFormals: \nLocals: person_type_info:char * t_type_info:char * t:int person:class Person \n DECLARE_LOCALS(&return,&person_type_info,&t_type_info,&t,&person); [line 28]\n NULLIFY(&person_type_info,false); [line 28]\n NULLIFY(&t,false); [line 28]\n NULLIFY(&t_type_info,false); [line 28]\n " color=yellow style=filled] + 23 -> 35 ; +22 [label="22: DeclStmt \n _fun_Person_Person(&person:class Person *) [line 20]\n " shape="box"] - 22 -> 33 ; -21 [label="21: DeclStmt \n _fun_Person_Person(&person:class Person *) [line 20]\n " shape="box"] + 22 -> 21 ; +21 [label="21: DeclStmt \n *&t:int =3 [line 21]\n " shape="box"] - 21 -> 20 ; -20 [label="20: DeclStmt \n *&t:int =3 [line 21]\n " shape="box"] + 21 -> 16 ; +20 [label="20: Return Stmt \n *&return:int =(1 / 0) [line 25]\n NULLIFY(&person,false); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] - 20 -> 15 ; -19 [label="19: Return Stmt \n *&return:int =(1 / 0) [line 25]\n NULLIFY(&person,false); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] + 20 -> 13 ; +19 [label="19: Return Stmt \n *&return:int =1 [line 23]\n NULLIFY(&person,false); [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"] 19 -> 13 ; -18 [label="18: Return Stmt \n *&return:int =1 [line 23]\n NULLIFY(&person,false); [line 23]\n APPLY_ABSTRACTION; [line 23]\n " shape="box"] +18 [label="18: Prune (false branch) \n PRUNE((n$2 == 0), false); [line 22]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 22]\n " shape="invhouse"] - 18 -> 13 ; -17 [label="17: Prune (false branch) \n PRUNE((n$2 == 0), false); [line 22]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 22]\n " shape="invhouse"] + 18 -> 20 ; +17 [label="17: Prune (true branch) \n PRUNE((n$2 != 0), true); [line 22]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 22]\n " shape="invhouse"] 17 -> 19 ; -16 [label="16: Prune (true branch) \n PRUNE((n$2 != 0), true); [line 22]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 22]\n " shape="invhouse"] +16 [label="16: Call _fun_std::type_info_operator== \n n$0=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$0.__type_name:void ,&t:int ) [line 22]\n n$1=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$1.__type_name:void ,&person:class Person ) [line 22]\n n$2=_fun_std::type_info_operator==(n$0:class std::type_info &,n$1:class std::type_info &) [line 22]\n NULLIFY(&t,false); [line 22]\n " shape="box"] + 16 -> 17 ; 16 -> 18 ; -15 [label="15: Call _fun_std::type_info_operator== \n n$0=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$0.__type_name:void ,&t:int ) [line 22]\n n$1=_fun___cxx_typeid(sizeof(class std::type_info ):void ,n$1.__type_name:void ,&person:class Person ) [line 22]\n n$2=_fun_std::type_info_operator==(n$0:class std::type_info &,n$1:class std::type_info &) [line 22]\n NULLIFY(&t,false); [line 22]\n " shape="box"] +15 [label="15: between_join_and_exit \n NULLIFY(&t,false); [line 22]\n NULLIFY(&person,false); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 15 -> 16 ; - 15 -> 17 ; -14 [label="14: + \n NULLIFY(&t,false); [line 22]\n NULLIFY(&person,false); [line 22]\n " ] + 15 -> 13 ; +14 [label="14: + \n " ] - 14 -> 13 ; + 14 -> 15 ; 13 [label="13: Exit person_typeid \n " color=yellow style=filled] 12 [label="12: Start person_typeid\nFormals: \nLocals: t:int person:class Person \n DECLARE_LOCALS(&return,&t,&person); [line 19]\n NULLIFY(&t,false); [line 19]\n " color=yellow style=filled] - 12 -> 21 ; + 12 -> 22 ; 11 [label="11: Constructor Init \n n$0=*&this:class Employee * [line 17]\n _fun_Person_Person(n$0:class Employee *) [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n NULLIFY(&this,false); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.dot b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.dot index 7e4af8274..32c1fd55c 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.dot +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainReleaseExample2.dot @@ -1,28 +1,32 @@ digraph iCFG { -32 [label="32: Call _fun___objc_release \n n$1=*&a:class A * [line 65]\n _fun___objc_release(n$1:class A *) [line 65]\n REMOVE_TEMPS(n$1); [line 65]\n NULLIFY(&a,false); [line 65]\n APPLY_ABSTRACTION; [line 65]\n " shape="box"] +33 [label="33: Call _fun___objc_release \n n$1=*&a:class A * [line 65]\n _fun___objc_release(n$1:class A *) [line 65]\n REMOVE_TEMPS(n$1); [line 65]\n NULLIFY(&a,false); [line 65]\n APPLY_ABSTRACTION; [line 65]\n " shape="box"] + + + 33 -> 29 ; +32 [label="32: Prune (false branch) \n n$0=*&a:class A * [line 64]\n PRUNE((n$0 == 0), false); [line 64]\n REMOVE_TEMPS(n$0); [line 64]\n APPLY_ABSTRACTION; [line 64]\n " shape="invhouse"] 32 -> 29 ; -31 [label="31: Prune (false branch) \n n$0=*&a:class A * [line 64]\n PRUNE((n$0 == 0), false); [line 64]\n REMOVE_TEMPS(n$0); [line 64]\n APPLY_ABSTRACTION; [line 64]\n " shape="invhouse"] +31 [label="31: Prune (true branch) \n n$0=*&a:class A * [line 64]\n PRUNE((n$0 != 0), true); [line 64]\n REMOVE_TEMPS(n$0); [line 64]\n " shape="invhouse"] - 31 -> 29 ; -30 [label="30: Prune (true branch) \n n$0=*&a:class A * [line 64]\n PRUNE((n$0 != 0), true); [line 64]\n REMOVE_TEMPS(n$0); [line 64]\n " shape="invhouse"] + 31 -> 33 ; +30 [label="30: between_join_and_exit \n NULLIFY(&a,false); [line 64]\n APPLY_ABSTRACTION; [line 64]\n " shape="box"] - 30 -> 32 ; -29 [label="29: + \n NULLIFY(&a,false); [line 64]\n " ] + 30 -> 28 ; +29 [label="29: + \n " ] - 29 -> 28 ; + 29 -> 30 ; 28 [label="28: Exit test7 \n " color=yellow style=filled] 27 [label="27: Start test7\nFormals: a:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 63]\n " color=yellow style=filled] - 27 -> 30 ; 27 -> 31 ; + 27 -> 32 ; 26 [label="26: DeclStmt \n n$3=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 57]\n n$4=_fun_NSObject_init(n$3:class A *) virtual [line 57]\n *&a:class A *=n$4 [line 57]\n REMOVE_TEMPS(n$3,n$4); [line 57]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.dot b/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.dot index 4ca3a4dec..72ebd123f 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/BlockVar.dot @@ -1,195 +1,199 @@ digraph iCFG { -53 [label="53: DeclStmt \n *&i:int =5 [line 57]\n " shape="box"] +54 [label="54: DeclStmt \n *&i:int =5 [line 57]\n " shape="box"] + + + 54 -> 53 ; +53 [label="53: DeclStmt \n *&x:int *=&i [line 58]\n " shape="box"] 53 -> 52 ; -52 [label="52: DeclStmt \n *&x:int *=&i [line 58]\n " shape="box"] +52 [label="52: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_capturedNoNullDeref______5); [line 59]\n n$37=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_capturedNoNullDeref______5 ):unsigned long ) [line 59]\n *&__objc_anonymous_block_BlockVar_capturedNoNullDeref______5:class __objc_anonymous_block_BlockVar_capturedNoNullDeref______5 =n$37 [line 59]\n n$38=*&x:int * [line 59]\n *n$37.x:int *=n$38 [line 59]\n n$34=*&x:int * [line 59]\n *&my_block:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_capturedNoNullDeref______5,n$34) [line 59]\n REMOVE_TEMPS(n$37,n$38,n$34); [line 59]\n NULLIFY(&x,false); [line 59]\n " shape="box"] - 52 -> 51 ; -51 [label="51: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_capturedNoNullDeref______5); [line 59]\n n$37=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_capturedNoNullDeref______5 ):unsigned long ) [line 59]\n *&__objc_anonymous_block_BlockVar_capturedNoNullDeref______5:class __objc_anonymous_block_BlockVar_capturedNoNullDeref______5 =n$37 [line 59]\n n$38=*&x:int * [line 59]\n *n$37.x:int *=n$38 [line 59]\n n$34=*&x:int * [line 59]\n *&my_block:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_capturedNoNullDeref______5,n$34) [line 59]\n REMOVE_TEMPS(n$37,n$38,n$34); [line 59]\n NULLIFY(&x,false); [line 59]\n " shape="box"] + 52 -> 48 ; +51 [label="51: Return Stmt \n n$35=*&x:int * [line 60]\n n$36=*n$35:int [line 60]\n *&return:int =n$36 [line 60]\n REMOVE_TEMPS(n$35,n$36); [line 60]\n NULLIFY(&x,false); [line 60]\n APPLY_ABSTRACTION; [line 60]\n " shape="box"] - 51 -> 47 ; -50 [label="50: Return Stmt \n n$35=*&x:int * [line 60]\n n$36=*n$35:int [line 60]\n *&return:int =n$36 [line 60]\n REMOVE_TEMPS(n$35,n$36); [line 60]\n NULLIFY(&x,false); [line 60]\n APPLY_ABSTRACTION; [line 60]\n " shape="box"] + 51 -> 50 ; +50 [label="50: Exit __objc_anonymous_block_BlockVar_capturedNoNullDeref______5 \n " color=yellow style=filled] - 50 -> 49 ; -49 [label="49: Exit __objc_anonymous_block_BlockVar_capturedNoNullDeref______5 \n " color=yellow style=filled] +49 [label="49: Start __objc_anonymous_block_BlockVar_capturedNoNullDeref______5\nFormals: x:int *\nLocals: \nCaptured: x:int * \n DECLARE_LOCALS(&return); [line 59]\n " color=yellow style=filled] -48 [label="48: Start __objc_anonymous_block_BlockVar_capturedNoNullDeref______5\nFormals: x:int *\nLocals: \nCaptured: x:int * \n DECLARE_LOCALS(&return); [line 59]\n " color=yellow style=filled] + 49 -> 51 ; +48 [label="48: BinaryOperatorStmt: Assign \n *&x:int *=0 [line 62]\n NULLIFY(&x,false); [line 62]\n " shape="box"] - 48 -> 50 ; -47 [label="47: BinaryOperatorStmt: Assign \n *&x:int *=0 [line 62]\n NULLIFY(&x,false); [line 62]\n " shape="box"] + 48 -> 47 ; +47 [label="47: Return Stmt \n n$32=*&my_block:_fn_ (*) [line 63]\n n$33=n$32() [line 63]\n *&return:int =n$33 [line 63]\n REMOVE_TEMPS(n$32,n$33); [line 63]\n NULLIFY(&__objc_anonymous_block_BlockVar_capturedNoNullDeref______5,true); [line 63]\n NULLIFY(&my_block,false); [line 63]\n NULLIFY(&i,false); [line 63]\n APPLY_ABSTRACTION; [line 63]\n " shape="box"] 47 -> 46 ; -46 [label="46: Return Stmt \n n$32=*&my_block:_fn_ (*) [line 63]\n n$33=n$32() [line 63]\n *&return:int =n$33 [line 63]\n REMOVE_TEMPS(n$32,n$33); [line 63]\n NULLIFY(&__objc_anonymous_block_BlockVar_capturedNoNullDeref______5,true); [line 63]\n NULLIFY(&my_block,false); [line 63]\n NULLIFY(&i,false); [line 63]\n APPLY_ABSTRACTION; [line 63]\n " shape="box"] +46 [label="46: Exit BlockVar_capturedNoNullDeref \n " color=yellow style=filled] - 46 -> 45 ; -45 [label="45: Exit BlockVar_capturedNoNullDeref \n " color=yellow style=filled] +45 [label="45: Start BlockVar_capturedNoNullDeref\nFormals: self:class BlockVar *\nLocals: my_block:_fn_ (*) x:int * i:int \n DECLARE_LOCALS(&return,&my_block,&x,&i); [line 56]\n NULLIFY(&my_block,false); [line 56]\n NULLIFY(&self,false); [line 56]\n NULLIFY(&x,false); [line 56]\n " color=yellow style=filled] -44 [label="44: Start BlockVar_capturedNoNullDeref\nFormals: self:class BlockVar *\nLocals: my_block:_fn_ (*) x:int * i:int \n DECLARE_LOCALS(&return,&my_block,&x,&i); [line 56]\n NULLIFY(&my_block,false); [line 56]\n NULLIFY(&self,false); [line 56]\n NULLIFY(&x,false); [line 56]\n " color=yellow style=filled] + 45 -> 54 ; +44 [label="44: DeclStmt \n *&x:int *=0 [line 49]\n " shape="box"] - 44 -> 53 ; -43 [label="43: DeclStmt \n *&x:int *=0 [line 49]\n " shape="box"] + 44 -> 43 ; +43 [label="43: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_capturedNullDeref______4); [line 50]\n n$30=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_capturedNullDeref______4 ):unsigned long ) [line 50]\n *&__objc_anonymous_block_BlockVar_capturedNullDeref______4:class __objc_anonymous_block_BlockVar_capturedNullDeref______4 =n$30 [line 50]\n n$31=*&x:int * [line 50]\n *n$30.x:int *=n$31 [line 50]\n n$27=*&x:int * [line 50]\n *&my_block:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_capturedNullDeref______4,n$27) [line 50]\n REMOVE_TEMPS(n$30,n$31,n$27); [line 50]\n NULLIFY(&x,false); [line 50]\n " shape="box"] - 43 -> 42 ; -42 [label="42: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_capturedNullDeref______4); [line 50]\n n$30=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_capturedNullDeref______4 ):unsigned long ) [line 50]\n *&__objc_anonymous_block_BlockVar_capturedNullDeref______4:class __objc_anonymous_block_BlockVar_capturedNullDeref______4 =n$30 [line 50]\n n$31=*&x:int * [line 50]\n *n$30.x:int *=n$31 [line 50]\n n$27=*&x:int * [line 50]\n *&my_block:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_capturedNullDeref______4,n$27) [line 50]\n REMOVE_TEMPS(n$30,n$31,n$27); [line 50]\n NULLIFY(&x,false); [line 50]\n " shape="box"] + 43 -> 39 ; +42 [label="42: Return Stmt \n n$28=*&x:int * [line 51]\n n$29=*n$28:int [line 51]\n *&return:int =n$29 [line 51]\n REMOVE_TEMPS(n$28,n$29); [line 51]\n NULLIFY(&x,false); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"] - 42 -> 38 ; -41 [label="41: Return Stmt \n n$28=*&x:int * [line 51]\n n$29=*n$28:int [line 51]\n *&return:int =n$29 [line 51]\n REMOVE_TEMPS(n$28,n$29); [line 51]\n NULLIFY(&x,false); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"] + 42 -> 41 ; +41 [label="41: Exit __objc_anonymous_block_BlockVar_capturedNullDeref______4 \n " color=yellow style=filled] - 41 -> 40 ; -40 [label="40: Exit __objc_anonymous_block_BlockVar_capturedNullDeref______4 \n " color=yellow style=filled] +40 [label="40: Start __objc_anonymous_block_BlockVar_capturedNullDeref______4\nFormals: x:int *\nLocals: \nCaptured: x:int * \n DECLARE_LOCALS(&return); [line 50]\n " color=yellow style=filled] -39 [label="39: Start __objc_anonymous_block_BlockVar_capturedNullDeref______4\nFormals: x:int *\nLocals: \nCaptured: x:int * \n DECLARE_LOCALS(&return); [line 50]\n " color=yellow style=filled] + 40 -> 42 ; +39 [label="39: Return Stmt \n n$25=*&my_block:_fn_ (*) [line 53]\n n$26=n$25() [line 53]\n *&return:int =n$26 [line 53]\n REMOVE_TEMPS(n$25,n$26); [line 53]\n NULLIFY(&__objc_anonymous_block_BlockVar_capturedNullDeref______4,true); [line 53]\n NULLIFY(&my_block,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"] - 39 -> 41 ; -38 [label="38: Return Stmt \n n$25=*&my_block:_fn_ (*) [line 53]\n n$26=n$25() [line 53]\n *&return:int =n$26 [line 53]\n REMOVE_TEMPS(n$25,n$26); [line 53]\n NULLIFY(&__objc_anonymous_block_BlockVar_capturedNullDeref______4,true); [line 53]\n NULLIFY(&my_block,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"] + 39 -> 38 ; +38 [label="38: Exit BlockVar_capturedNullDeref \n " color=yellow style=filled] - 38 -> 37 ; -37 [label="37: Exit BlockVar_capturedNullDeref \n " color=yellow style=filled] +37 [label="37: Start BlockVar_capturedNullDeref\nFormals: self:class BlockVar *\nLocals: my_block:_fn_ (*) x:int * \n DECLARE_LOCALS(&return,&my_block,&x); [line 48]\n NULLIFY(&my_block,false); [line 48]\n NULLIFY(&self,false); [line 48]\n NULLIFY(&x,false); [line 48]\n " color=yellow style=filled] -36 [label="36: Start BlockVar_capturedNullDeref\nFormals: self:class BlockVar *\nLocals: my_block:_fn_ (*) x:int * \n DECLARE_LOCALS(&return,&my_block,&x); [line 48]\n NULLIFY(&my_block,false); [line 48]\n NULLIFY(&self,false); [line 48]\n NULLIFY(&x,false); [line 48]\n " color=yellow style=filled] + 37 -> 44 ; +36 [label="36: DeclStmt \n *&i:int =7 [line 40]\n " shape="box"] - 36 -> 43 ; -35 [label="35: DeclStmt \n *&i:int =7 [line 40]\n " shape="box"] + 36 -> 35 ; +35 [label="35: DeclStmt \n *&x:int *=&i [line 41]\n " shape="box"] 35 -> 34 ; -34 [label="34: DeclStmt \n *&x:int *=&i [line 41]\n " shape="box"] +34 [label="34: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_blockPostOk______3); [line 42]\n n$23=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_blockPostOk______3 ):unsigned long ) [line 42]\n *&__objc_anonymous_block_BlockVar_blockPostOk______3:class __objc_anonymous_block_BlockVar_blockPostOk______3 =n$23 [line 42]\n n$24=*&x:int * [line 42]\n *n$23.x:int *=n$24 [line 42]\n n$21=*&x:int * [line 42]\n *&my_block:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_blockPostOk______3,n$21) [line 42]\n REMOVE_TEMPS(n$23,n$24,n$21); [line 42]\n NULLIFY(&x,false); [line 42]\n " shape="box"] - 34 -> 33 ; -33 [label="33: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_blockPostOk______3); [line 42]\n n$23=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_blockPostOk______3 ):unsigned long ) [line 42]\n *&__objc_anonymous_block_BlockVar_blockPostOk______3:class __objc_anonymous_block_BlockVar_blockPostOk______3 =n$23 [line 42]\n n$24=*&x:int * [line 42]\n *n$23.x:int *=n$24 [line 42]\n n$21=*&x:int * [line 42]\n *&my_block:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_blockPostOk______3,n$21) [line 42]\n REMOVE_TEMPS(n$23,n$24,n$21); [line 42]\n NULLIFY(&x,false); [line 42]\n " shape="box"] + 34 -> 30 ; +33 [label="33: Return Stmt \n n$22=*&x:int * [line 43]\n *&return:int *=n$22 [line 43]\n REMOVE_TEMPS(n$22); [line 43]\n NULLIFY(&x,false); [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] - 33 -> 29 ; -32 [label="32: Return Stmt \n n$22=*&x:int * [line 43]\n *&return:int *=n$22 [line 43]\n REMOVE_TEMPS(n$22); [line 43]\n NULLIFY(&x,false); [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] + 33 -> 32 ; +32 [label="32: Exit __objc_anonymous_block_BlockVar_blockPostOk______3 \n " color=yellow style=filled] - 32 -> 31 ; -31 [label="31: Exit __objc_anonymous_block_BlockVar_blockPostOk______3 \n " color=yellow style=filled] +31 [label="31: Start __objc_anonymous_block_BlockVar_blockPostOk______3\nFormals: x:int *\nLocals: \nCaptured: x:int * \n DECLARE_LOCALS(&return); [line 42]\n " color=yellow style=filled] -30 [label="30: Start __objc_anonymous_block_BlockVar_blockPostOk______3\nFormals: x:int *\nLocals: \nCaptured: x:int * \n DECLARE_LOCALS(&return); [line 42]\n " color=yellow style=filled] + 31 -> 33 ; +30 [label="30: Return Stmt \n n$18=*&my_block:_fn_ (*) [line 45]\n n$19=n$18() [line 45]\n n$20=*n$19:int [line 45]\n *&return:int =n$20 [line 45]\n REMOVE_TEMPS(n$18,n$19,n$20); [line 45]\n NULLIFY(&__objc_anonymous_block_BlockVar_blockPostOk______3,true); [line 45]\n NULLIFY(&my_block,false); [line 45]\n NULLIFY(&i,false); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"] - 30 -> 32 ; -29 [label="29: Return Stmt \n n$18=*&my_block:_fn_ (*) [line 45]\n n$19=n$18() [line 45]\n n$20=*n$19:int [line 45]\n *&return:int =n$20 [line 45]\n REMOVE_TEMPS(n$18,n$19,n$20); [line 45]\n NULLIFY(&__objc_anonymous_block_BlockVar_blockPostOk______3,true); [line 45]\n NULLIFY(&my_block,false); [line 45]\n NULLIFY(&i,false); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"] + 30 -> 29 ; +29 [label="29: Exit BlockVar_blockPostOk \n " color=yellow style=filled] - 29 -> 28 ; -28 [label="28: Exit BlockVar_blockPostOk \n " color=yellow style=filled] +28 [label="28: Start BlockVar_blockPostOk\nFormals: self:class BlockVar *\nLocals: my_block:_fn_ (*) x:int * i:int \n DECLARE_LOCALS(&return,&my_block,&x,&i); [line 39]\n NULLIFY(&my_block,false); [line 39]\n NULLIFY(&self,false); [line 39]\n NULLIFY(&x,false); [line 39]\n " color=yellow style=filled] -27 [label="27: Start BlockVar_blockPostOk\nFormals: self:class BlockVar *\nLocals: my_block:_fn_ (*) x:int * i:int \n DECLARE_LOCALS(&return,&my_block,&x,&i); [line 39]\n NULLIFY(&my_block,false); [line 39]\n NULLIFY(&self,false); [line 39]\n NULLIFY(&x,false); [line 39]\n " color=yellow style=filled] + 28 -> 36 ; +27 [label="27: DeclStmt \n *&x:int *=0 [line 32]\n " shape="box"] - 27 -> 35 ; -26 [label="26: DeclStmt \n *&x:int *=0 [line 32]\n " shape="box"] + 27 -> 26 ; +26 [label="26: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_blockPostBad______2); [line 33]\n n$16=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_blockPostBad______2 ):unsigned long ) [line 33]\n *&__objc_anonymous_block_BlockVar_blockPostBad______2:class __objc_anonymous_block_BlockVar_blockPostBad______2 =n$16 [line 33]\n n$17=*&x:int * [line 33]\n *n$16.x:int *=n$17 [line 33]\n n$14=*&x:int * [line 33]\n *&my_block:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_blockPostBad______2,n$14) [line 33]\n REMOVE_TEMPS(n$16,n$17,n$14); [line 33]\n NULLIFY(&x,false); [line 33]\n " shape="box"] - 26 -> 25 ; -25 [label="25: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_blockPostBad______2); [line 33]\n n$16=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_blockPostBad______2 ):unsigned long ) [line 33]\n *&__objc_anonymous_block_BlockVar_blockPostBad______2:class __objc_anonymous_block_BlockVar_blockPostBad______2 =n$16 [line 33]\n n$17=*&x:int * [line 33]\n *n$16.x:int *=n$17 [line 33]\n n$14=*&x:int * [line 33]\n *&my_block:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_blockPostBad______2,n$14) [line 33]\n REMOVE_TEMPS(n$16,n$17,n$14); [line 33]\n NULLIFY(&x,false); [line 33]\n " shape="box"] + 26 -> 22 ; +25 [label="25: Return Stmt \n n$15=*&x:int * [line 34]\n *&return:int *=n$15 [line 34]\n REMOVE_TEMPS(n$15); [line 34]\n NULLIFY(&x,false); [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] - 25 -> 21 ; -24 [label="24: Return Stmt \n n$15=*&x:int * [line 34]\n *&return:int *=n$15 [line 34]\n REMOVE_TEMPS(n$15); [line 34]\n NULLIFY(&x,false); [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] + 25 -> 24 ; +24 [label="24: Exit __objc_anonymous_block_BlockVar_blockPostBad______2 \n " color=yellow style=filled] - 24 -> 23 ; -23 [label="23: Exit __objc_anonymous_block_BlockVar_blockPostBad______2 \n " color=yellow style=filled] +23 [label="23: Start __objc_anonymous_block_BlockVar_blockPostBad______2\nFormals: x:int *\nLocals: \nCaptured: x:int * \n DECLARE_LOCALS(&return); [line 33]\n " color=yellow style=filled] -22 [label="22: Start __objc_anonymous_block_BlockVar_blockPostBad______2\nFormals: x:int *\nLocals: \nCaptured: x:int * \n DECLARE_LOCALS(&return); [line 33]\n " color=yellow style=filled] + 23 -> 25 ; +22 [label="22: Return Stmt \n n$11=*&my_block:_fn_ (*) [line 36]\n n$12=n$11() [line 36]\n n$13=*n$12:int [line 36]\n *&return:int =n$13 [line 36]\n REMOVE_TEMPS(n$11,n$12,n$13); [line 36]\n NULLIFY(&__objc_anonymous_block_BlockVar_blockPostBad______2,true); [line 36]\n NULLIFY(&my_block,false); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] - 22 -> 24 ; -21 [label="21: Return Stmt \n n$11=*&my_block:_fn_ (*) [line 36]\n n$12=n$11() [line 36]\n n$13=*n$12:int [line 36]\n *&return:int =n$13 [line 36]\n REMOVE_TEMPS(n$11,n$12,n$13); [line 36]\n NULLIFY(&__objc_anonymous_block_BlockVar_blockPostBad______2,true); [line 36]\n NULLIFY(&my_block,false); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"] + 22 -> 21 ; +21 [label="21: Exit BlockVar_blockPostBad \n " color=yellow style=filled] - 21 -> 20 ; -20 [label="20: Exit BlockVar_blockPostBad \n " color=yellow style=filled] +20 [label="20: Start BlockVar_blockPostBad\nFormals: self:class BlockVar *\nLocals: my_block:_fn_ (*) x:int * \n DECLARE_LOCALS(&return,&my_block,&x); [line 31]\n NULLIFY(&my_block,false); [line 31]\n NULLIFY(&self,false); [line 31]\n NULLIFY(&x,false); [line 31]\n " color=yellow style=filled] -19 [label="19: Start BlockVar_blockPostBad\nFormals: self:class BlockVar *\nLocals: my_block:_fn_ (*) x:int * \n DECLARE_LOCALS(&return,&my_block,&x); [line 31]\n NULLIFY(&my_block,false); [line 31]\n NULLIFY(&self,false); [line 31]\n NULLIFY(&x,false); [line 31]\n " color=yellow style=filled] + 20 -> 27 ; +19 [label="19: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1); [line 19]\n n$10=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_navigateToURLInBackground______1 ):unsigned long ) [line 19]\n *&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1:class __objc_anonymous_block_BlockVar_navigateToURLInBackground______1 =n$10 [line 19]\n *&addBlock:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_navigateToURLInBackground______1) [line 19]\n REMOVE_TEMPS(n$10); [line 19]\n " shape="box"] - 19 -> 26 ; -18 [label="18: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1); [line 19]\n n$10=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_BlockVar_navigateToURLInBackground______1 ):unsigned long ) [line 19]\n *&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1:class __objc_anonymous_block_BlockVar_navigateToURLInBackground______1 =n$10 [line 19]\n *&addBlock:_fn_ (*)=(_fun___objc_anonymous_block_BlockVar_navigateToURLInBackground______1) [line 19]\n REMOVE_TEMPS(n$10); [line 19]\n " shape="box"] + 19 -> 14 ; +18 [label="18: DeclStmt \n n$9=_fun_BlockVar_test() [line 20]\n *&res:int =n$9 [line 20]\n REMOVE_TEMPS(n$9); [line 20]\n " shape="box"] - 18 -> 13 ; -17 [label="17: DeclStmt \n n$9=_fun_BlockVar_test() [line 20]\n *&res:int =n$9 [line 20]\n REMOVE_TEMPS(n$9); [line 20]\n " shape="box"] + 18 -> 17 ; +17 [label="17: Return Stmt \n n$6=*&a:int [line 21]\n n$7=*&b:int [line 21]\n n$8=*&res:int [line 21]\n *&return:int =((n$6 + n$7) + n$8) [line 21]\n REMOVE_TEMPS(n$6,n$7,n$8); [line 21]\n NULLIFY(&a,false); [line 21]\n NULLIFY(&b,false); [line 21]\n NULLIFY(&res,false); [line 21]\n APPLY_ABSTRACTION; [line 21]\n " shape="box"] 17 -> 16 ; -16 [label="16: Return Stmt \n n$6=*&a:int [line 21]\n n$7=*&b:int [line 21]\n n$8=*&res:int [line 21]\n *&return:int =((n$6 + n$7) + n$8) [line 21]\n REMOVE_TEMPS(n$6,n$7,n$8); [line 21]\n NULLIFY(&a,false); [line 21]\n NULLIFY(&b,false); [line 21]\n NULLIFY(&res,false); [line 21]\n APPLY_ABSTRACTION; [line 21]\n " shape="box"] +16 [label="16: Exit __objc_anonymous_block_BlockVar_navigateToURLInBackground______1 \n " color=yellow style=filled] - 16 -> 15 ; -15 [label="15: Exit __objc_anonymous_block_BlockVar_navigateToURLInBackground______1 \n " color=yellow style=filled] +15 [label="15: Start __objc_anonymous_block_BlockVar_navigateToURLInBackground______1\nFormals: a:int b:int \nLocals: res:int \n DECLARE_LOCALS(&return,&res); [line 19]\n NULLIFY(&res,false); [line 19]\n " color=yellow style=filled] -14 [label="14: Start __objc_anonymous_block_BlockVar_navigateToURLInBackground______1\nFormals: a:int b:int \nLocals: res:int \n DECLARE_LOCALS(&return,&res); [line 19]\n NULLIFY(&res,false); [line 19]\n " color=yellow style=filled] + 15 -> 18 ; +14 [label="14: DeclStmt \n n$4=*&addBlock:_fn_ (*) [line 23]\n n$5=n$4(1:int ,2:int ) [line 23]\n *&x:int =n$5 [line 23]\n REMOVE_TEMPS(n$4,n$5); [line 23]\n NULLIFY(&addBlock,false); [line 23]\n " shape="box"] - 14 -> 17 ; -13 [label="13: DeclStmt \n n$4=*&addBlock:_fn_ (*) [line 23]\n n$5=n$4(1:int ,2:int ) [line 23]\n *&x:int =n$5 [line 23]\n REMOVE_TEMPS(n$4,n$5); [line 23]\n NULLIFY(&addBlock,false); [line 23]\n " shape="box"] + 14 -> 13 ; +13 [label="13: DeclStmt \n *&p:int *=0 [line 24]\n " shape="box"] - 13 -> 12 ; -12 [label="12: DeclStmt \n *&p:int *=0 [line 24]\n " shape="box"] + 13 -> 8 ; +12 [label="12: Return Stmt \n NULLIFY(&p,false); [line 28]\n n$3=*&x:int [line 28]\n *&return:int =n$3 [line 28]\n REMOVE_TEMPS(n$3); [line 28]\n NULLIFY(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1,true); [line 28]\n NULLIFY(&x,false); [line 28]\n APPLY_ABSTRACTION; [line 28]\n " shape="box"] - 12 -> 7 ; -11 [label="11: Return Stmt \n NULLIFY(&p,false); [line 28]\n n$3=*&x:int [line 28]\n *&return:int =n$3 [line 28]\n REMOVE_TEMPS(n$3); [line 28]\n NULLIFY(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1,true); [line 28]\n NULLIFY(&x,false); [line 28]\n APPLY_ABSTRACTION; [line 28]\n " shape="box"] + 12 -> 5 ; +11 [label="11: Return Stmt \n NULLIFY(&x,false); [line 26]\n n$1=*&p:int * [line 26]\n n$2=*n$1:int [line 26]\n *&return:int =n$2 [line 26]\n REMOVE_TEMPS(n$1,n$2); [line 26]\n NULLIFY(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1,true); [line 26]\n NULLIFY(&p,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] 11 -> 5 ; -10 [label="10: Return Stmt \n NULLIFY(&x,false); [line 26]\n n$1=*&p:int * [line 26]\n n$2=*n$1:int [line 26]\n *&return:int =n$2 [line 26]\n REMOVE_TEMPS(n$1,n$2); [line 26]\n NULLIFY(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1,true); [line 26]\n NULLIFY(&p,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] +10 [label="10: Prune (false branch) \n PRUNE(((n$0 == 8) == 0), false); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] - 10 -> 5 ; -9 [label="9: Prune (false branch) \n PRUNE(((n$0 == 8) == 0), false); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] + 10 -> 12 ; +9 [label="9: Prune (true branch) \n PRUNE(((n$0 == 8) != 0), true); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] 9 -> 11 ; -8 [label="8: Prune (true branch) \n PRUNE(((n$0 == 8) != 0), true); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] +8 [label="8: BinaryOperatorStmt: EQ \n n$0=*&x:int [line 25]\n " shape="box"] + 8 -> 9 ; 8 -> 10 ; -7 [label="7: BinaryOperatorStmt: EQ \n n$0=*&x:int [line 25]\n " shape="box"] +7 [label="7: between_join_and_exit \n NULLIFY(&addBlock,false); [line 25]\n NULLIFY(&p,false); [line 25]\n NULLIFY(&x,false); [line 25]\n NULLIFY(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1,true); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] - 7 -> 8 ; - 7 -> 9 ; -6 [label="6: + \n NULLIFY(&__objc_anonymous_block_BlockVar_navigateToURLInBackground______1,true); [line 25]\n NULLIFY(&addBlock,false); [line 25]\n NULLIFY(&p,false); [line 25]\n NULLIFY(&x,false); [line 25]\n " ] + 7 -> 5 ; +6 [label="6: + \n " ] - 6 -> 5 ; + 6 -> 7 ; 5 [label="5: Exit BlockVar_navigateToURLInBackground \n " color=yellow style=filled] 4 [label="4: Start BlockVar_navigateToURLInBackground\nFormals: \nLocals: p:int * x:int addBlock:_fn_ (*) \n DECLARE_LOCALS(&return,&p,&x,&addBlock); [line 18]\n NULLIFY(&addBlock,false); [line 18]\n NULLIFY(&p,false); [line 18]\n NULLIFY(&x,false); [line 18]\n " color=yellow style=filled] - 4 -> 18 ; + 4 -> 19 ; 3 [label="3: Return Stmt \n *&return:int =5 [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/objc/frontend/block/block-it.dot b/infer/tests/codetoanalyze/objc/frontend/block/block-it.dot index 323c1e751..5756e7113 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/block-it.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/block-it.dot @@ -1,145 +1,153 @@ digraph iCFG { -52 [label="52: DeclStmt \n n$44=_fun___objc_alloc_no_fail(sizeof(class NSArray ):unsigned long ) [line 34]\n n$45=_fun_NSArray_init(n$44:class NSArray *) virtual [line 34]\n *&a:class NSArray *=n$45 [line 34]\n REMOVE_TEMPS(n$44,n$45); [line 34]\n " shape="box"] +54 [label="54: DeclStmt \n n$44=_fun___objc_alloc_no_fail(sizeof(class NSArray ):unsigned long ) [line 34]\n n$45=_fun_NSArray_init(n$44:class NSArray *) virtual [line 34]\n *&a:class NSArray *=n$45 [line 34]\n REMOVE_TEMPS(n$44,n$45); [line 34]\n " shape="box"] - 52 -> 51 ; -51 [label="51: DeclStmt \n n$43=*&a:class NSArray * [line 36]\n *&objects:class NSArray *=n$43 [line 36]\n REMOVE_TEMPS(n$43); [line 36]\n NULLIFY(&a,false); [line 36]\n " shape="box"] + 54 -> 53 ; +53 [label="53: DeclStmt \n n$43=*&a:class NSArray * [line 36]\n *&objects:class NSArray *=n$43 [line 36]\n REMOVE_TEMPS(n$43); [line 36]\n NULLIFY(&a,false); [line 36]\n " shape="box"] - 51 -> 50 ; -50 [label="50: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_MyBlock_array_trans______2); [line 40]\n n$42=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_MyBlock_array_trans______2 ):unsigned long ) [line 40]\n *&__objc_anonymous_block_MyBlock_array_trans______2:class __objc_anonymous_block_MyBlock_array_trans______2 =n$42 [line 40]\n *&enumerateObjectsUsingBlock:_fn_ (*)=(_fun___objc_anonymous_block_MyBlock_array_trans______2) [line 39]\n REMOVE_TEMPS(n$42); [line 39]\n " shape="box"] + 53 -> 52 ; +52 [label="52: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_MyBlock_array_trans______2); [line 40]\n n$42=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_MyBlock_array_trans______2 ):unsigned long ) [line 40]\n *&__objc_anonymous_block_MyBlock_array_trans______2:class __objc_anonymous_block_MyBlock_array_trans______2 =n$42 [line 40]\n *&enumerateObjectsUsingBlock:_fn_ (*)=(_fun___objc_anonymous_block_MyBlock_array_trans______2) [line 39]\n REMOVE_TEMPS(n$42); [line 39]\n " shape="box"] - 50 -> 43 ; -49 [label="49: BinaryOperatorStmt: Assign \n NULLIFY(&ShouldStop,false); [line 45]\n n$41=*&stop:_Bool * [line 45]\n *n$41:_Bool =1 [line 45]\n REMOVE_TEMPS(n$41); [line 45]\n NULLIFY(&stop,false); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"] + 52 -> 44 ; +51 [label="51: BinaryOperatorStmt: Assign \n NULLIFY(&ShouldStop,false); [line 45]\n n$41=*&stop:_Bool * [line 45]\n *n$41:_Bool =1 [line 45]\n REMOVE_TEMPS(n$41); [line 45]\n NULLIFY(&stop,false); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"] - 49 -> 46 ; -48 [label="48: Prune (false branch) \n n$40=*&ShouldStop:int [line 44]\n PRUNE((n$40 == 0), false); [line 44]\n REMOVE_TEMPS(n$40); [line 44]\n APPLY_ABSTRACTION; [line 44]\n " shape="invhouse"] + 51 -> 47 ; +50 [label="50: Prune (false branch) \n n$40=*&ShouldStop:int [line 44]\n PRUNE((n$40 == 0), false); [line 44]\n REMOVE_TEMPS(n$40); [line 44]\n APPLY_ABSTRACTION; [line 44]\n " shape="invhouse"] + + + 50 -> 47 ; +49 [label="49: Prune (true branch) \n n$40=*&ShouldStop:int [line 44]\n PRUNE((n$40 != 0), true); [line 44]\n REMOVE_TEMPS(n$40); [line 44]\n " shape="invhouse"] + + + 49 -> 51 ; +48 [label="48: between_join_and_exit \n NULLIFY(&ShouldStop,false); [line 44]\n NULLIFY(&stop,false); [line 44]\n APPLY_ABSTRACTION; [line 44]\n " shape="box"] 48 -> 46 ; -47 [label="47: Prune (true branch) \n n$40=*&ShouldStop:int [line 44]\n PRUNE((n$40 != 0), true); [line 44]\n REMOVE_TEMPS(n$40); [line 44]\n " shape="invhouse"] +47 [label="47: + \n " ] - 47 -> 49 ; -46 [label="46: + \n NULLIFY(&ShouldStop,false); [line 44]\n NULLIFY(&stop,false); [line 44]\n " ] + 47 -> 48 ; +46 [label="46: Exit __objc_anonymous_block_MyBlock_array_trans______2 \n " color=yellow style=filled] - 46 -> 45 ; -45 [label="45: Exit __objc_anonymous_block_MyBlock_array_trans______2 \n " color=yellow style=filled] +45 [label="45: Start __objc_anonymous_block_MyBlock_array_trans______2\nFormals: object:struct objc_object * idx:unsigned long stop:_Bool *\nLocals: ShouldStop:int \n DECLARE_LOCALS(&return,&ShouldStop); [line 40]\n NULLIFY(&idx,false); [line 40]\n NULLIFY(&object,false); [line 40]\n " color=yellow style=filled] -44 [label="44: Start __objc_anonymous_block_MyBlock_array_trans______2\nFormals: object:struct objc_object * idx:unsigned long stop:_Bool *\nLocals: ShouldStop:int \n DECLARE_LOCALS(&return,&ShouldStop); [line 40]\n NULLIFY(&idx,false); [line 40]\n NULLIFY(&object,false); [line 40]\n " color=yellow style=filled] + 45 -> 49 ; + 45 -> 50 ; +44 [label="44: DeclStmt \n n$39=_fun_malloc_no_fail(sizeof(_Bool ):_Bool ) [line 48]\n *&stop:_Bool *=n$39 [line 48]\n REMOVE_TEMPS(n$39); [line 48]\n " shape="box"] - 44 -> 47 ; - 44 -> 48 ; -43 [label="43: DeclStmt \n n$39=_fun_malloc_no_fail(sizeof(_Bool ):_Bool ) [line 48]\n *&stop:_Bool *=n$39 [line 48]\n REMOVE_TEMPS(n$39); [line 48]\n " shape="box"] + 44 -> 43 ; +43 [label="43: BinaryOperatorStmt: Assign \n n$38=*&stop:_Bool * [line 49]\n *n$38:_Bool =0 [line 49]\n REMOVE_TEMPS(n$38); [line 49]\n " shape="box"] - 43 -> 42 ; -42 [label="42: BinaryOperatorStmt: Assign \n n$38=*&stop:_Bool * [line 49]\n *n$38:_Bool =0 [line 49]\n REMOVE_TEMPS(n$38); [line 49]\n " shape="box"] + 43 -> 32 ; +42 [label="42: DeclStmt \n n$35=*&objects:class NSArray * [line 53]\n n$36=*&idx:unsigned long [line 53]\n n$37=_fun_NSArray_objectAtIndexedSubscript:(n$35:class NSArray *,n$36:unsigned long ) virtual [line 53]\n *&object:struct objc_object *=n$37 [line 53]\n REMOVE_TEMPS(n$35,n$36,n$37); [line 53]\n " shape="box"] - 42 -> 31 ; -41 [label="41: DeclStmt \n n$35=*&objects:class NSArray * [line 53]\n n$36=*&idx:unsigned long [line 53]\n n$37=_fun_NSArray_objectAtIndexedSubscript:(n$35:class NSArray *,n$36:unsigned long ) virtual [line 53]\n *&object:struct objc_object *=n$37 [line 53]\n REMOVE_TEMPS(n$35,n$36,n$37); [line 53]\n " shape="box"] + 42 -> 41 ; +41 [label="41: Call n$31 \n n$31=*&enumerateObjectsUsingBlock:_fn_ (*) [line 54]\n n$32=*&object:struct objc_object * [line 54]\n n$33=*&idx:unsigned long [line 54]\n n$34=*&stop:_Bool * [line 54]\n n$31(n$32:struct objc_object *,n$33:unsigned long ,n$34:_Bool *) [line 54]\n REMOVE_TEMPS(n$31,n$32,n$33,n$34); [line 54]\n NULLIFY(&object,false); [line 54]\n " shape="box"] - 41 -> 40 ; -40 [label="40: Call n$31 \n n$31=*&enumerateObjectsUsingBlock:_fn_ (*) [line 54]\n n$32=*&object:struct objc_object * [line 54]\n n$33=*&idx:unsigned long [line 54]\n n$34=*&stop:_Bool * [line 54]\n n$31(n$32:struct objc_object *,n$33:unsigned long ,n$34:_Bool *) [line 54]\n REMOVE_TEMPS(n$31,n$32,n$33,n$34); [line 54]\n NULLIFY(&object,false); [line 54]\n " shape="box"] + 41 -> 38 ; +40 [label="40: Prune (false branch) \n PRUNE(((n$30 == 1) == 0), false); [line 55]\n REMOVE_TEMPS(n$29,n$30); [line 55]\n " shape="invhouse"] 40 -> 37 ; -39 [label="39: Prune (false branch) \n PRUNE(((n$30 == 1) == 0), false); [line 55]\n REMOVE_TEMPS(n$29,n$30); [line 55]\n " shape="invhouse"] +39 [label="39: Prune (true branch) \n PRUNE(((n$30 == 1) != 0), true); [line 55]\n REMOVE_TEMPS(n$29,n$30); [line 55]\n APPLY_ABSTRACTION; [line 55]\n " shape="invhouse"] - 39 -> 36 ; -38 [label="38: Prune (true branch) \n PRUNE(((n$30 == 1) != 0), true); [line 55]\n REMOVE_TEMPS(n$29,n$30); [line 55]\n APPLY_ABSTRACTION; [line 55]\n " shape="invhouse"] + 39 -> 30 ; +38 [label="38: BinaryOperatorStmt: EQ \n n$29=*&stop:_Bool * [line 55]\n n$30=*n$29:_Bool [line 55]\n " shape="box"] - 38 -> 29 ; -37 [label="37: BinaryOperatorStmt: EQ \n n$29=*&stop:_Bool * [line 55]\n n$30=*n$29:_Bool [line 55]\n " shape="box"] + 38 -> 39 ; + 38 -> 40 ; +37 [label="37: + \n " ] - 37 -> 38 ; - 37 -> 39 ; -36 [label="36: + \n " ] + 37 -> 33 ; +36 [label="36: Prune (false branch) \n PRUNE(((n$26 < n$28) == 0), false); [line 51]\n REMOVE_TEMPS(n$26,n$27,n$28); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="invhouse"] - 36 -> 32 ; -35 [label="35: Prune (false branch) \n PRUNE(((n$26 < n$28) == 0), false); [line 51]\n REMOVE_TEMPS(n$26,n$27,n$28); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="invhouse"] + 36 -> 30 ; +35 [label="35: Prune (true branch) \n PRUNE(((n$26 < n$28) != 0), true); [line 51]\n REMOVE_TEMPS(n$26,n$27,n$28); [line 51]\n " shape="invhouse"] - 35 -> 29 ; -34 [label="34: Prune (true branch) \n PRUNE(((n$26 < n$28) != 0), true); [line 51]\n REMOVE_TEMPS(n$26,n$27,n$28); [line 51]\n " shape="invhouse"] + 35 -> 42 ; +34 [label="34: BinaryOperatorStmt: LT \n n$26=*&idx:unsigned long [line 51]\n n$27=*&objects:class NSArray * [line 51]\n n$28=_fun_NSArray_count(n$27:class NSArray *) [line 51]\n " shape="box"] - 34 -> 41 ; -33 [label="33: BinaryOperatorStmt: LT \n n$26=*&idx:unsigned long [line 51]\n n$27=*&objects:class NSArray * [line 51]\n n$28=_fun_NSArray_count(n$27:class NSArray *) [line 51]\n " shape="box"] + 34 -> 35 ; + 34 -> 36 ; +33 [label="33: UnaryOperator \n n$25=*&idx:unsigned long [line 51]\n *&idx:unsigned long =(n$25 + 1) [line 51]\n REMOVE_TEMPS(n$25); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"] - 33 -> 34 ; - 33 -> 35 ; -32 [label="32: UnaryOperator \n n$25=*&idx:unsigned long [line 51]\n *&idx:unsigned long =(n$25 + 1) [line 51]\n REMOVE_TEMPS(n$25); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"] + 33 -> 31 ; +32 [label="32: DeclStmt \n *&idx:unsigned long =0 [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"] - 32 -> 30 ; -31 [label="31: DeclStmt \n *&idx:unsigned long =0 [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"] + 32 -> 31 ; +31 [label="31: + \n " ] - 31 -> 30 ; -30 [label="30: + \n " ] + 31 -> 34 ; +30 [label="30: Call _fun_free \n NULLIFY(&enumerateObjectsUsingBlock,false); [line 58]\n NULLIFY(&idx,false); [line 58]\n NULLIFY(&objects,false); [line 58]\n n$24=*&stop:_Bool * [line 58]\n _fun_free(n$24:void *) [line 58]\n REMOVE_TEMPS(n$24); [line 58]\n NULLIFY(&__objc_anonymous_block_MyBlock_array_trans______2,true); [line 58]\n NULLIFY(&stop,false); [line 58]\n APPLY_ABSTRACTION; [line 58]\n " shape="box"] - 30 -> 33 ; -29 [label="29: Call _fun_free \n NULLIFY(&enumerateObjectsUsingBlock,false); [line 58]\n NULLIFY(&idx,false); [line 58]\n NULLIFY(&objects,false); [line 58]\n n$24=*&stop:_Bool * [line 58]\n _fun_free(n$24:void *) [line 58]\n REMOVE_TEMPS(n$24); [line 58]\n NULLIFY(&__objc_anonymous_block_MyBlock_array_trans______2,true); [line 58]\n NULLIFY(&stop,false); [line 58]\n APPLY_ABSTRACTION; [line 58]\n " shape="box"] + 30 -> 29 ; +29 [label="29: Exit MyBlock_array_trans \n " color=yellow style=filled] - 29 -> 28 ; -28 [label="28: Exit MyBlock_array_trans \n " color=yellow style=filled] +28 [label="28: Start MyBlock_array_trans\nFormals: self:class MyBlock *\nLocals: idx:unsigned long object:struct objc_object * stop:_Bool * enumerateObjectsUsingBlock:_fn_ (*) objects:class NSArray * a:class NSArray * \n DECLARE_LOCALS(&return,&idx,&object,&stop,&enumerateObjectsUsingBlock,&objects,&a); [line 32]\n NULLIFY(&a,false); [line 32]\n NULLIFY(&enumerateObjectsUsingBlock,false); [line 32]\n NULLIFY(&idx,false); [line 32]\n NULLIFY(&object,false); [line 32]\n NULLIFY(&objects,false); [line 32]\n NULLIFY(&self,false); [line 32]\n NULLIFY(&stop,false); [line 32]\n " color=yellow style=filled] -27 [label="27: Start MyBlock_array_trans\nFormals: self:class MyBlock *\nLocals: idx:unsigned long object:struct objc_object * stop:_Bool * enumerateObjectsUsingBlock:_fn_ (*) objects:class NSArray * a:class NSArray * \n DECLARE_LOCALS(&return,&idx,&object,&stop,&enumerateObjectsUsingBlock,&objects,&a); [line 32]\n NULLIFY(&a,false); [line 32]\n NULLIFY(&enumerateObjectsUsingBlock,false); [line 32]\n NULLIFY(&idx,false); [line 32]\n NULLIFY(&object,false); [line 32]\n NULLIFY(&objects,false); [line 32]\n NULLIFY(&self,false); [line 32]\n NULLIFY(&stop,false); [line 32]\n " color=yellow style=filled] + 28 -> 54 ; +27 [label="27: DeclStmt \n n$22=_fun___objc_alloc_no_fail(sizeof(class NSArray ):unsigned long ) [line 20]\n n$23=_fun_NSArray_init(n$22:class NSArray *) virtual [line 20]\n *&a:class NSArray *=n$23 [line 20]\n REMOVE_TEMPS(n$22,n$23); [line 20]\n " shape="box"] - 27 -> 52 ; -26 [label="26: DeclStmt \n n$22=_fun___objc_alloc_no_fail(sizeof(class NSArray ):unsigned long ) [line 20]\n n$23=_fun_NSArray_init(n$22:class NSArray *) virtual [line 20]\n *&a:class NSArray *=n$23 [line 20]\n REMOVE_TEMPS(n$22,n$23); [line 20]\n " shape="box"] + 27 -> 26 ; +26 [label="26: DeclStmt \n n$21=*&a:class NSArray * [line 21]\n *&objects:class NSArray *=n$21 [line 21]\n REMOVE_TEMPS(n$21); [line 21]\n NULLIFY(&a,false); [line 21]\n " shape="box"] 26 -> 25 ; -25 [label="25: DeclStmt \n n$21=*&a:class NSArray * [line 21]\n *&objects:class NSArray *=n$21 [line 21]\n REMOVE_TEMPS(n$21); [line 21]\n NULLIFY(&a,false); [line 21]\n " shape="box"] +25 [label="25: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_MyBlock_array______1); [line 21]\n n$20=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_MyBlock_array______1 ):unsigned long ) [line 21]\n *&__objc_anonymous_block_MyBlock_array______1:class __objc_anonymous_block_MyBlock_array______1 =n$20 [line 21]\n *&infer___objc_anonymous_block_MyBlock_array______1:_fn_ (*)=(_fun___objc_anonymous_block_MyBlock_array______1) [line 21]\n REMOVE_TEMPS(n$20); [line 21]\n " shape="box"] - 25 -> 24 ; -24 [label="24: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_MyBlock_array______1); [line 21]\n n$20=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_MyBlock_array______1 ):unsigned long ) [line 21]\n *&__objc_anonymous_block_MyBlock_array______1:class __objc_anonymous_block_MyBlock_array______1 =n$20 [line 21]\n *&infer___objc_anonymous_block_MyBlock_array______1:_fn_ (*)=(_fun___objc_anonymous_block_MyBlock_array______1) [line 21]\n REMOVE_TEMPS(n$20); [line 21]\n " shape="box"] + 25 -> 17 ; +24 [label="24: BinaryOperatorStmt: Assign \n NULLIFY(&ShouldStop,false); [line 27]\n n$19=*&stop:_Bool * [line 27]\n *n$19:_Bool =1 [line 27]\n REMOVE_TEMPS(n$19); [line 27]\n NULLIFY(&stop,false); [line 27]\n APPLY_ABSTRACTION; [line 27]\n " shape="box"] - 24 -> 17 ; -23 [label="23: BinaryOperatorStmt: Assign \n NULLIFY(&ShouldStop,false); [line 27]\n n$19=*&stop:_Bool * [line 27]\n *n$19:_Bool =1 [line 27]\n REMOVE_TEMPS(n$19); [line 27]\n NULLIFY(&stop,false); [line 27]\n APPLY_ABSTRACTION; [line 27]\n " shape="box"] + 24 -> 20 ; +23 [label="23: Prune (false branch) \n n$18=*&ShouldStop:int [line 26]\n PRUNE((n$18 == 0), false); [line 26]\n REMOVE_TEMPS(n$18); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="invhouse"] 23 -> 20 ; -22 [label="22: Prune (false branch) \n n$18=*&ShouldStop:int [line 26]\n PRUNE((n$18 == 0), false); [line 26]\n REMOVE_TEMPS(n$18); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="invhouse"] +22 [label="22: Prune (true branch) \n n$18=*&ShouldStop:int [line 26]\n PRUNE((n$18 != 0), true); [line 26]\n REMOVE_TEMPS(n$18); [line 26]\n " shape="invhouse"] - 22 -> 20 ; -21 [label="21: Prune (true branch) \n n$18=*&ShouldStop:int [line 26]\n PRUNE((n$18 != 0), true); [line 26]\n REMOVE_TEMPS(n$18); [line 26]\n " shape="invhouse"] + 22 -> 24 ; +21 [label="21: between_join_and_exit \n NULLIFY(&ShouldStop,false); [line 26]\n NULLIFY(&stop,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] - 21 -> 23 ; -20 [label="20: + \n NULLIFY(&ShouldStop,false); [line 26]\n NULLIFY(&stop,false); [line 26]\n " ] + 21 -> 19 ; +20 [label="20: + \n " ] - 20 -> 19 ; + 20 -> 21 ; 19 [label="19: Exit __objc_anonymous_block_MyBlock_array______1 \n " color=yellow style=filled] 18 [label="18: Start __objc_anonymous_block_MyBlock_array______1\nFormals: object:struct objc_object * idx:unsigned long stop:_Bool *\nLocals: ShouldStop:int \n DECLARE_LOCALS(&return,&ShouldStop); [line 21]\n NULLIFY(&idx,false); [line 21]\n NULLIFY(&object,false); [line 21]\n " color=yellow style=filled] - 18 -> 21 ; 18 -> 22 ; + 18 -> 23 ; 17 [label="17: DeclStmt \n n$17=_fun_malloc_no_fail(sizeof(signed char ):signed char ) [line 21]\n *&stop:_Bool *=n$17 [line 21]\n REMOVE_TEMPS(n$17); [line 21]\n " shape="box"] @@ -208,5 +216,5 @@ digraph iCFG { 1 [label="1: Start MyBlock_array\nFormals: self:class MyBlock *\nLocals: idx:unsigned long object:struct objc_object * stop:_Bool * infer___objc_anonymous_block_MyBlock_array______1:_fn_ (*) objects:class NSArray * a:class NSArray * \n DECLARE_LOCALS(&return,&idx,&object,&stop,&infer___objc_anonymous_block_MyBlock_array______1,&objects,&a); [line 18]\n NULLIFY(&a,false); [line 18]\n NULLIFY(&idx,false); [line 18]\n NULLIFY(&infer___objc_anonymous_block_MyBlock_array______1,false); [line 18]\n NULLIFY(&object,false); [line 18]\n NULLIFY(&objects,false); [line 18]\n NULLIFY(&self,false); [line 18]\n NULLIFY(&stop,false); [line 18]\n " color=yellow style=filled] - 1 -> 26 ; + 1 -> 27 ; } diff --git a/infer/tests/codetoanalyze/objc/frontend/block/block_no_args.dot b/infer/tests/codetoanalyze/objc/frontend/block/block_no_args.dot index ed5118b4e..064295179 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/block_no_args.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/block_no_args.dot @@ -1,65 +1,69 @@ digraph iCFG { -16 [label="16: BinaryOperatorStmt: Assign \n *&#GB$g:int =7 [line 22]\n " shape="box"] +17 [label="17: BinaryOperatorStmt: Assign \n *&#GB$g:int =7 [line 22]\n " shape="box"] + + + 17 -> 16 ; +16 [label="16: DeclStmt \n *&z:int =3 [line 24]\n " shape="box"] 16 -> 15 ; -15 [label="15: DeclStmt \n *&z:int =3 [line 24]\n " shape="box"] +15 [label="15: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block_My_manager_m______1); [line 25]\n n$7=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_My_manager_m______1 ):unsigned long ) [line 25]\n *&__objc_anonymous_block_My_manager_m______1:class __objc_anonymous_block_My_manager_m______1 =n$7 [line 25]\n n$8=*&z:int [line 25]\n n$9=*&#GB$g:int [line 25]\n *n$7.z:int =n$8 [line 25]\n *n$7.g:int =n$9 [line 25]\n n$5=*&z:int [line 25]\n *&b:_fn_ (*)=(_fun___objc_anonymous_block_My_manager_m______1,n$5) [line 25]\n REMOVE_TEMPS(n$7,n$8,n$9,n$5); [line 25]\n " shape="box"] - 15 -> 14 ; -14 [label="14: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block_My_manager_m______1); [line 25]\n n$7=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_My_manager_m______1 ):unsigned long ) [line 25]\n *&__objc_anonymous_block_My_manager_m______1:class __objc_anonymous_block_My_manager_m______1 =n$7 [line 25]\n n$8=*&z:int [line 25]\n n$9=*&#GB$g:int [line 25]\n *n$7.z:int =n$8 [line 25]\n *n$7.g:int =n$9 [line 25]\n n$5=*&z:int [line 25]\n *&b:_fn_ (*)=(_fun___objc_anonymous_block_My_manager_m______1,n$5) [line 25]\n REMOVE_TEMPS(n$7,n$8,n$9,n$5); [line 25]\n " shape="box"] + 15 -> 11 ; +14 [label="14: BinaryOperatorStmt: Assign \n n$6=*&z:int [line 26]\n *&#GB$g:int =(n$6 + 3) [line 26]\n REMOVE_TEMPS(n$6); [line 26]\n NULLIFY(&z,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] - 14 -> 10 ; -13 [label="13: BinaryOperatorStmt: Assign \n n$6=*&z:int [line 26]\n *&#GB$g:int =(n$6 + 3) [line 26]\n REMOVE_TEMPS(n$6); [line 26]\n NULLIFY(&z,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] + 14 -> 13 ; +13 [label="13: Exit __objc_anonymous_block_My_manager_m______1 \n " color=yellow style=filled] - 13 -> 12 ; -12 [label="12: Exit __objc_anonymous_block_My_manager_m______1 \n " color=yellow style=filled] +12 [label="12: Start __objc_anonymous_block_My_manager_m______1\nFormals: z:int \nLocals: \nCaptured: z:int \n DECLARE_LOCALS(&return); [line 25]\n " color=yellow style=filled] -11 [label="11: Start __objc_anonymous_block_My_manager_m______1\nFormals: z:int \nLocals: \nCaptured: z:int \n DECLARE_LOCALS(&return); [line 25]\n " color=yellow style=filled] + 12 -> 14 ; +11 [label="11: Call n$4 \n n$4=*&b:_fn_ (*) [line 28]\n n$4() [line 28]\n REMOVE_TEMPS(n$4); [line 28]\n NULLIFY(&b,false); [line 28]\n " shape="box"] - 11 -> 13 ; -10 [label="10: Call n$4 \n n$4=*&b:_fn_ (*) [line 28]\n n$4() [line 28]\n REMOVE_TEMPS(n$4); [line 28]\n NULLIFY(&b,false); [line 28]\n " shape="box"] + 11 -> 10 ; +10 [label="10: DeclStmt \n *&p:int *=0 [line 29]\n " shape="box"] - 10 -> 9 ; -9 [label="9: DeclStmt \n *&p:int *=0 [line 29]\n " shape="box"] + 10 -> 5 ; +9 [label="9: Return Stmt \n NULLIFY(&p,false); [line 33]\n n$3=*&z:int [line 33]\n *&return:int =n$3 [line 33]\n REMOVE_TEMPS(n$3); [line 33]\n NULLIFY(&__objc_anonymous_block_My_manager_m______1,true); [line 33]\n NULLIFY(&z,false); [line 33]\n APPLY_ABSTRACTION; [line 33]\n " shape="box"] - 9 -> 4 ; -8 [label="8: Return Stmt \n NULLIFY(&p,false); [line 33]\n n$3=*&z:int [line 33]\n *&return:int =n$3 [line 33]\n REMOVE_TEMPS(n$3); [line 33]\n NULLIFY(&__objc_anonymous_block_My_manager_m______1,true); [line 33]\n NULLIFY(&z,false); [line 33]\n APPLY_ABSTRACTION; [line 33]\n " shape="box"] + 9 -> 2 ; +8 [label="8: Return Stmt \n NULLIFY(&z,false); [line 31]\n n$1=*&p:int * [line 31]\n n$2=*n$1:int [line 31]\n *&return:int =n$2 [line 31]\n REMOVE_TEMPS(n$1,n$2); [line 31]\n NULLIFY(&__objc_anonymous_block_My_manager_m______1,true); [line 31]\n NULLIFY(&p,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"] 8 -> 2 ; -7 [label="7: Return Stmt \n NULLIFY(&z,false); [line 31]\n n$1=*&p:int * [line 31]\n n$2=*n$1:int [line 31]\n *&return:int =n$2 [line 31]\n REMOVE_TEMPS(n$1,n$2); [line 31]\n NULLIFY(&__objc_anonymous_block_My_manager_m______1,true); [line 31]\n NULLIFY(&p,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"] +7 [label="7: Prune (false branch) \n PRUNE(((n$0 == 6) == 0), false); [line 30]\n REMOVE_TEMPS(n$0); [line 30]\n " shape="invhouse"] - 7 -> 2 ; -6 [label="6: Prune (false branch) \n PRUNE(((n$0 == 6) == 0), false); [line 30]\n REMOVE_TEMPS(n$0); [line 30]\n " shape="invhouse"] + 7 -> 9 ; +6 [label="6: Prune (true branch) \n PRUNE(((n$0 == 6) != 0), true); [line 30]\n REMOVE_TEMPS(n$0); [line 30]\n " shape="invhouse"] 6 -> 8 ; -5 [label="5: Prune (true branch) \n PRUNE(((n$0 == 6) != 0), true); [line 30]\n REMOVE_TEMPS(n$0); [line 30]\n " shape="invhouse"] +5 [label="5: BinaryOperatorStmt: EQ \n n$0=*&#GB$g:int [line 30]\n " shape="box"] + 5 -> 6 ; 5 -> 7 ; -4 [label="4: BinaryOperatorStmt: EQ \n n$0=*&#GB$g:int [line 30]\n " shape="box"] +4 [label="4: between_join_and_exit \n NULLIFY(&b,false); [line 30]\n NULLIFY(&p,false); [line 30]\n NULLIFY(&self,false); [line 30]\n NULLIFY(&z,false); [line 30]\n NULLIFY(&__objc_anonymous_block_My_manager_m______1,true); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"] - 4 -> 5 ; - 4 -> 6 ; -3 [label="3: + \n NULLIFY(&__objc_anonymous_block_My_manager_m______1,true); [line 30]\n NULLIFY(&b,false); [line 30]\n NULLIFY(&p,false); [line 30]\n NULLIFY(&self,false); [line 30]\n NULLIFY(&z,false); [line 30]\n " ] + 4 -> 2 ; +3 [label="3: + \n " ] - 3 -> 2 ; + 3 -> 4 ; 2 [label="2: Exit My_manager_m \n " color=yellow style=filled] 1 [label="1: Start My_manager_m\nFormals: self:class My_manager *\nLocals: p:int * z:int b:_fn_ (*) \n DECLARE_LOCALS(&return,&p,&z,&b); [line 21]\n NULLIFY(&b,false); [line 21]\n NULLIFY(&p,false); [line 21]\n NULLIFY(&self,false); [line 21]\n NULLIFY(&z,false); [line 21]\n " color=yellow style=filled] - 1 -> 16 ; + 1 -> 17 ; } diff --git a/infer/tests/codetoanalyze/objc/frontend/block/block_release.dot b/infer/tests/codetoanalyze/objc/frontend/block/block_release.dot index 33bcc199e..7563685ee 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/block_release.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/block_release.dot @@ -1,44 +1,48 @@ digraph iCFG { -18 [label="18: DeclStmt \n *&z:int =3 [line 22]\n " shape="box"] +19 [label="19: DeclStmt \n *&z:int =3 [line 22]\n " shape="box"] + + + 19 -> 18 ; +18 [label="18: DeclStmt \n n$12=_fun_CGBitmapContextCreate(0:void *,0:unsigned long ,0:unsigned long ,8:unsigned long ,0:unsigned long ,0:struct CGColorSpace *,0:unsigned int ) [line 23]\n *&context:struct CGContext *=n$12 [line 23]\n REMOVE_TEMPS(n$12); [line 23]\n " shape="box"] 18 -> 17 ; -17 [label="17: DeclStmt \n n$12=_fun_CGBitmapContextCreate(0:void *,0:unsigned long ,0:unsigned long ,8:unsigned long ,0:unsigned long ,0:struct CGColorSpace *,0:unsigned int ) [line 23]\n *&context:struct CGContext *=n$12 [line 23]\n REMOVE_TEMPS(n$12); [line 23]\n " shape="box"] +17 [label="17: DeclStmt \n n$10=*&context:struct CGContext * [line 24]\n n$11=_fun_CGBitmapContextCreateImage(n$10:struct CGContext *) [line 24]\n *&newImage:struct CGImage *=n$11 [line 24]\n REMOVE_TEMPS(n$10,n$11); [line 24]\n " shape="box"] 17 -> 16 ; -16 [label="16: DeclStmt \n n$10=*&context:struct CGContext * [line 24]\n n$11=_fun_CGBitmapContextCreateImage(n$10:struct CGContext *) [line 24]\n *&newImage:struct CGImage *=n$11 [line 24]\n REMOVE_TEMPS(n$10,n$11); [line 24]\n " shape="box"] +16 [label="16: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block_My_manager_blockReleaseTODO______1); [line 25]\n n$8=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_My_manager_blockReleaseTODO______1 ):unsigned long ) [line 25]\n *&__objc_anonymous_block_My_manager_blockReleaseTODO______1:class __objc_anonymous_block_My_manager_blockReleaseTODO______1 =n$8 [line 25]\n n$9=*&newImage:struct CGImage * [line 25]\n *n$8.newImage:struct CGImage *=n$9 [line 25]\n n$5=*&newImage:struct CGImage * [line 25]\n *&b:_fn_ (*)=(_fun___objc_anonymous_block_My_manager_blockReleaseTODO______1,n$5) [line 25]\n REMOVE_TEMPS(n$8,n$9,n$5); [line 25]\n NULLIFY(&newImage,false); [line 25]\n " shape="box"] - 16 -> 15 ; -15 [label="15: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block_My_manager_blockReleaseTODO______1); [line 25]\n n$8=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_My_manager_blockReleaseTODO______1 ):unsigned long ) [line 25]\n *&__objc_anonymous_block_My_manager_blockReleaseTODO______1:class __objc_anonymous_block_My_manager_blockReleaseTODO______1 =n$8 [line 25]\n n$9=*&newImage:struct CGImage * [line 25]\n *n$8.newImage:struct CGImage *=n$9 [line 25]\n n$5=*&newImage:struct CGImage * [line 25]\n *&b:_fn_ (*)=(_fun___objc_anonymous_block_My_manager_blockReleaseTODO______1,n$5) [line 25]\n REMOVE_TEMPS(n$8,n$9,n$5); [line 25]\n NULLIFY(&newImage,false); [line 25]\n " shape="box"] + 16 -> 8 ; +15 [label="15: Call _fun_CGImageRelease \n n$7=*&newImage:struct CGImage * [line 27]\n _fun_CGImageRelease(n$7:struct CGImage *) [line 27]\n REMOVE_TEMPS(n$7); [line 27]\n NULLIFY(&newImage,false); [line 27]\n APPLY_ABSTRACTION; [line 27]\n " shape="box"] - 15 -> 8 ; -14 [label="14: Call _fun_CGImageRelease \n n$7=*&newImage:struct CGImage * [line 27]\n _fun_CGImageRelease(n$7:struct CGImage *) [line 27]\n REMOVE_TEMPS(n$7); [line 27]\n NULLIFY(&newImage,false); [line 27]\n APPLY_ABSTRACTION; [line 27]\n " shape="box"] + 15 -> 11 ; +14 [label="14: Prune (false branch) \n n$6=*&newImage:struct CGImage * [line 26]\n PRUNE((n$6 == 0), false); [line 26]\n REMOVE_TEMPS(n$6); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="invhouse"] 14 -> 11 ; -13 [label="13: Prune (false branch) \n n$6=*&newImage:struct CGImage * [line 26]\n PRUNE((n$6 == 0), false); [line 26]\n REMOVE_TEMPS(n$6); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="invhouse"] +13 [label="13: Prune (true branch) \n n$6=*&newImage:struct CGImage * [line 26]\n PRUNE((n$6 != 0), true); [line 26]\n REMOVE_TEMPS(n$6); [line 26]\n " shape="invhouse"] - 13 -> 11 ; -12 [label="12: Prune (true branch) \n n$6=*&newImage:struct CGImage * [line 26]\n PRUNE((n$6 != 0), true); [line 26]\n REMOVE_TEMPS(n$6); [line 26]\n " shape="invhouse"] + 13 -> 15 ; +12 [label="12: between_join_and_exit \n NULLIFY(&newImage,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] - 12 -> 14 ; -11 [label="11: + \n NULLIFY(&newImage,false); [line 26]\n " ] + 12 -> 10 ; +11 [label="11: + \n " ] - 11 -> 10 ; + 11 -> 12 ; 10 [label="10: Exit __objc_anonymous_block_My_manager_blockReleaseTODO______1 \n " color=yellow style=filled] 9 [label="9: Start __objc_anonymous_block_My_manager_blockReleaseTODO______1\nFormals: newImage:struct CGImage * a:int \nLocals: \nCaptured: newImage:struct CGImage * \n DECLARE_LOCALS(&return); [line 25]\n NULLIFY(&a,false); [line 25]\n " color=yellow style=filled] - 9 -> 12 ; 9 -> 13 ; + 9 -> 14 ; 8 [label="8: Call n$3 \n n$3=*&b:_fn_ (*) [line 29]\n n$4=*&z:int [line 29]\n n$3(n$4:int ) [line 29]\n REMOVE_TEMPS(n$3,n$4); [line 29]\n NULLIFY(&b,false); [line 29]\n " shape="box"] @@ -70,5 +74,5 @@ digraph iCFG { 1 [label="1: Start My_manager_blockReleaseTODO\nFormals: self:class My_manager *\nLocals: newImage:struct CGImage * context:struct CGContext * z:int b:_fn_ (*) \n DECLARE_LOCALS(&return,&newImage,&context,&z,&b); [line 20]\n NULLIFY(&b,false); [line 20]\n NULLIFY(&context,false); [line 20]\n NULLIFY(&newImage,false); [line 20]\n NULLIFY(&self,false); [line 20]\n NULLIFY(&z,false); [line 20]\n " color=yellow style=filled] - 1 -> 18 ; + 1 -> 19 ; } diff --git a/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot b/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot index 5535ea56a..fbf4d600d 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot @@ -1,44 +1,48 @@ digraph iCFG { -26 [label="26: DeclStmt \n n$3=_fun_A_sharedInstance() [line 43]\n *&b:class A *=n$3 [line 43]\n REMOVE_TEMPS(n$3); [line 43]\n " shape="box"] +27 [label="27: DeclStmt \n n$3=_fun_A_sharedInstance() [line 43]\n *&b:class A *=n$3 [line 43]\n REMOVE_TEMPS(n$3); [line 43]\n " shape="box"] - 26 -> 25 ; -25 [label="25: DeclStmt \n *&p:int *=0 [line 44]\n " shape="box"] + 27 -> 26 ; +26 [label="26: DeclStmt \n *&p:int *=0 [line 44]\n " shape="box"] - 25 -> 20 ; -24 [label="24: Return Stmt \n NULLIFY(&p,false); [line 48]\n *&return:int =0 [line 48]\n APPLY_ABSTRACTION; [line 48]\n " shape="box"] + 26 -> 21 ; +25 [label="25: Return Stmt \n NULLIFY(&p,false); [line 48]\n *&return:int =0 [line 48]\n APPLY_ABSTRACTION; [line 48]\n " shape="box"] + + + 25 -> 18 ; +24 [label="24: Return Stmt \n n$1=*&p:int * [line 46]\n n$2=*n$1:int [line 46]\n *&return:int =n$2 [line 46]\n REMOVE_TEMPS(n$1,n$2); [line 46]\n NULLIFY(&p,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"] 24 -> 18 ; -23 [label="23: Return Stmt \n n$1=*&p:int * [line 46]\n n$2=*n$1:int [line 46]\n *&return:int =n$2 [line 46]\n REMOVE_TEMPS(n$1,n$2); [line 46]\n NULLIFY(&p,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"] +23 [label="23: Prune (false branch) \n PRUNE(((n$0 == 0) == 0), false); [line 45]\n REMOVE_TEMPS(n$0); [line 45]\n " shape="invhouse"] - 23 -> 18 ; -22 [label="22: Prune (false branch) \n PRUNE(((n$0 == 0) == 0), false); [line 45]\n REMOVE_TEMPS(n$0); [line 45]\n " shape="invhouse"] + 23 -> 25 ; +22 [label="22: Prune (true branch) \n PRUNE(((n$0 == 0) != 0), true); [line 45]\n REMOVE_TEMPS(n$0); [line 45]\n " shape="invhouse"] 22 -> 24 ; -21 [label="21: Prune (true branch) \n PRUNE(((n$0 == 0) != 0), true); [line 45]\n REMOVE_TEMPS(n$0); [line 45]\n " shape="invhouse"] +21 [label="21: BinaryOperatorStmt: EQ \n n$0=*&b:class A * [line 45]\n NULLIFY(&b,false); [line 45]\n " shape="box"] + 21 -> 22 ; 21 -> 23 ; -20 [label="20: BinaryOperatorStmt: EQ \n n$0=*&b:class A * [line 45]\n NULLIFY(&b,false); [line 45]\n " shape="box"] +20 [label="20: between_join_and_exit \n NULLIFY(&b,false); [line 45]\n NULLIFY(&p,false); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"] - 20 -> 21 ; - 20 -> 22 ; -19 [label="19: + \n NULLIFY(&b,false); [line 45]\n NULLIFY(&p,false); [line 45]\n " ] + 20 -> 18 ; +19 [label="19: + \n " ] - 19 -> 18 ; + 19 -> 20 ; 18 [label="18: Exit main \n " color=yellow style=filled] 17 [label="17: Start main\nFormals: \nLocals: p:int * b:class A * \n DECLARE_LOCALS(&return,&p,&b); [line 42]\n NULLIFY(&b,false); [line 42]\n NULLIFY(&p,false); [line 42]\n " color=yellow style=filled] - 17 -> 26 ; + 17 -> 27 ; 16 [label="16: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_trans______2); [line 34]\n n$11=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_trans______2 ):unsigned long ) [line 34]\n *&__objc_anonymous_block_A_trans______2:class __objc_anonymous_block_A_trans______2 =n$11 [line 34]\n n$12=*&#GB$A_trans_sharedInstance:struct objc_object * [line 34]\n *n$11.A_trans_sharedInstance:struct objc_object *=n$12 [line 34]\n *&dummy_block:_fn_ (*)=(_fun___objc_anonymous_block_A_trans______2) [line 34]\n REMOVE_TEMPS(n$11,n$12); [line 34]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/objc/frontend/exceptions/ExceptionExample.dot b/infer/tests/codetoanalyze/objc/frontend/exceptions/ExceptionExample.dot index e15622739..fd76f4b90 100644 --- a/infer/tests/codetoanalyze/objc/frontend/exceptions/ExceptionExample.dot +++ b/infer/tests/codetoanalyze/objc/frontend/exceptions/ExceptionExample.dot @@ -1,32 +1,36 @@ digraph iCFG { -11 [label="11: DeclStmt \n n$7=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 28]\n *&s:class NSString *=n$7 [line 28]\n REMOVE_TEMPS(n$7); [line 28]\n " shape="box"] +12 [label="12: DeclStmt \n n$7=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 28]\n *&s:class NSString *=n$7 [line 28]\n REMOVE_TEMPS(n$7); [line 28]\n " shape="box"] - 11 -> 8 ; - 11 -> 9 ; -10 [label="10: Return Stmt \n NULLIFY(&s,false); [line 30]\n n$4=_fun_NSString_stringWithUTF8String:(\"Something is not right exception\":char *) [line 31]\n n$5=_fun_NSString_stringWithUTF8String:(\"Can't perform this operation because of this or that\":char *) [line 33]\n n$6=_fun_NSException_exceptionWithName:reason:userInfo:(n$4:class NSString *,n$5:class NSString *,0:class NSDictionary *) [line 30]\n *&return:void =n$6 [line 30]\n REMOVE_TEMPS(n$4,n$5,n$6); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"] + 12 -> 9 ; + 12 -> 10 ; +11 [label="11: Return Stmt \n NULLIFY(&s,false); [line 30]\n n$4=_fun_NSString_stringWithUTF8String:(\"Something is not right exception\":char *) [line 31]\n n$5=_fun_NSString_stringWithUTF8String:(\"Can't perform this operation because of this or that\":char *) [line 33]\n n$6=_fun_NSException_exceptionWithName:reason:userInfo:(n$4:class NSString *,n$5:class NSString *,0:class NSDictionary *) [line 30]\n *&return:void =n$6 [line 30]\n REMOVE_TEMPS(n$4,n$5,n$6); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"] - 10 -> 6 ; -9 [label="9: Prune (false branch) \n n$3=*&s:class NSString * [line 29]\n PRUNE((n$3 == 0), false); [line 29]\n REMOVE_TEMPS(n$3); [line 29]\n " shape="invhouse"] + 11 -> 6 ; +10 [label="10: Prune (false branch) \n n$3=*&s:class NSString * [line 29]\n PRUNE((n$3 == 0), false); [line 29]\n REMOVE_TEMPS(n$3); [line 29]\n " shape="invhouse"] - 9 -> 7 ; -8 [label="8: Prune (true branch) \n n$3=*&s:class NSString * [line 29]\n PRUNE((n$3 != 0), true); [line 29]\n REMOVE_TEMPS(n$3); [line 29]\n " shape="invhouse"] + 10 -> 7 ; +9 [label="9: Prune (true branch) \n n$3=*&s:class NSString * [line 29]\n PRUNE((n$3 != 0), true); [line 29]\n REMOVE_TEMPS(n$3); [line 29]\n " shape="invhouse"] - 8 -> 10 ; -7 [label="7: + \n NULLIFY(&s,false); [line 29]\n " ] + 9 -> 11 ; +8 [label="8: between_join_and_exit \n NULLIFY(&s,false); [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] - 7 -> 6 ; + 8 -> 6 ; +7 [label="7: + \n " ] + + + 7 -> 8 ; 6 [label="6: Exit ExceptionExample_test1 \n " color=yellow style=filled] 5 [label="5: Start ExceptionExample_test1\nFormals: self:class ExceptionExample *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 27]\n NULLIFY(&s,false); [line 27]\n NULLIFY(&self,false); [line 27]\n " color=yellow style=filled] - 5 -> 11 ; + 5 -> 12 ; 4 [label="4: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 20]\n *&s:class NSString *=n$2 [line 20]\n REMOVE_TEMPS(n$2); [line 20]\n NULLIFY(&s,false); [line 20]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/objc/frontend/protocol/protocol.dot b/infer/tests/codetoanalyze/objc/frontend/protocol/protocol.dot index 3e8646cac..f01e235b5 100644 --- a/infer/tests/codetoanalyze/objc/frontend/protocol/protocol.dot +++ b/infer/tests/codetoanalyze/objc/frontend/protocol/protocol.dot @@ -1,30 +1,34 @@ digraph iCFG { -7 [label="7: Return Stmt \n APPLY_ABSTRACTION; [line 26]\n " shape="box"] +8 [label="8: Return Stmt \n APPLY_ABSTRACTION; [line 26]\n " shape="box"] - 7 -> 2 ; -6 [label="6: Prune (false branch) \n PRUNE((n$1 == 0), false); [line 25]\n REMOVE_TEMPS(n$0,n$1); [line 25]\n " shape="invhouse"] + 8 -> 2 ; +7 [label="7: Prune (false branch) \n PRUNE((n$1 == 0), false); [line 25]\n REMOVE_TEMPS(n$0,n$1); [line 25]\n " shape="invhouse"] - 6 -> 3 ; -5 [label="5: Prune (true branch) \n PRUNE((n$1 != 0), true); [line 25]\n REMOVE_TEMPS(n$0,n$1); [line 25]\n " shape="invhouse"] + 7 -> 3 ; +6 [label="6: Prune (true branch) \n PRUNE((n$1 != 0), true); [line 25]\n REMOVE_TEMPS(n$0,n$1); [line 25]\n " shape="invhouse"] + 6 -> 8 ; +5 [label="5: Message Call: conformsToProtocol: \n n$0=*&self:class Bla * [line 25]\n n$1=_fun_Bla_conformsToProtocol:(n$0:class Bla *,\"Foo\":class Protocol *) virtual [line 25]\n NULLIFY(&self,false); [line 25]\n " shape="box"] + + + 5 -> 6 ; 5 -> 7 ; -4 [label="4: Message Call: conformsToProtocol: \n n$0=*&self:class Bla * [line 25]\n n$1=_fun_Bla_conformsToProtocol:(n$0:class Bla *,\"Foo\":class Protocol *) virtual [line 25]\n NULLIFY(&self,false); [line 25]\n " shape="box"] +4 [label="4: between_join_and_exit \n APPLY_ABSTRACTION; [line 25]\n " shape="box"] - 4 -> 5 ; - 4 -> 6 ; + 4 -> 2 ; 3 [label="3: + \n " ] - 3 -> 2 ; + 3 -> 4 ; 2 [label="2: Exit Bla_fooMethod \n " color=yellow style=filled] 1 [label="1: Start Bla_fooMethod\nFormals: self:class Bla *\nLocals: \n DECLARE_LOCALS(&return); [line 24]\n " color=yellow style=filled] - 1 -> 4 ; + 1 -> 5 ; } diff --git a/infer/tests/codetoanalyze/objc/frontend/returnstmt/void_return.dot b/infer/tests/codetoanalyze/objc/frontend/returnstmt/void_return.dot index ac7392229..0e6bacdfa 100644 --- a/infer/tests/codetoanalyze/objc/frontend/returnstmt/void_return.dot +++ b/infer/tests/codetoanalyze/objc/frontend/returnstmt/void_return.dot @@ -1,59 +1,63 @@ digraph iCFG { -14 [label="14: DeclStmt \n *&i:int =0 [line 19]\n " shape="box"] +15 [label="15: DeclStmt \n *&i:int =0 [line 19]\n " shape="box"] - 14 -> 13 ; -13 [label="13: DeclStmt \n *&j:int =0 [line 20]\n " shape="box"] + 15 -> 14 ; +14 [label="14: DeclStmt \n *&j:int =0 [line 20]\n " shape="box"] - 13 -> 9 ; -12 [label="12: Return Stmt \n NULLIFY(&i,false); [line 22]\n NULLIFY(&j,false); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] + 14 -> 10 ; +13 [label="13: Return Stmt \n NULLIFY(&i,false); [line 22]\n NULLIFY(&j,false); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] - 12 -> 2 ; -11 [label="11: Prune (false branch) \n PRUNE(((n$2 == 0) == 0), false); [line 21]\n REMOVE_TEMPS(n$2); [line 21]\n " shape="invhouse"] + 13 -> 2 ; +12 [label="12: Prune (false branch) \n PRUNE(((n$2 == 0) == 0), false); [line 21]\n REMOVE_TEMPS(n$2); [line 21]\n " shape="invhouse"] - 11 -> 8 ; -10 [label="10: Prune (true branch) \n PRUNE(((n$2 == 0) != 0), true); [line 21]\n REMOVE_TEMPS(n$2); [line 21]\n " shape="invhouse"] + 12 -> 9 ; +11 [label="11: Prune (true branch) \n PRUNE(((n$2 == 0) != 0), true); [line 21]\n REMOVE_TEMPS(n$2); [line 21]\n " shape="invhouse"] + 11 -> 13 ; +10 [label="10: BinaryOperatorStmt: EQ \n n$2=*&i:int [line 21]\n " shape="box"] + + + 10 -> 11 ; 10 -> 12 ; -9 [label="9: BinaryOperatorStmt: EQ \n n$2=*&i:int [line 21]\n " shape="box"] +9 [label="9: + \n " ] - 9 -> 10 ; - 9 -> 11 ; -8 [label="8: + \n " ] + 9 -> 5 ; +8 [label="8: UnaryOperator \n n$1=*&i:int [line 26]\n *&i:int =(n$1 + 1) [line 26]\n REMOVE_TEMPS(n$1); [line 26]\n NULLIFY(&i,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] - 8 -> 4 ; -7 [label="7: UnaryOperator \n n$1=*&i:int [line 26]\n *&i:int =(n$1 + 1) [line 26]\n REMOVE_TEMPS(n$1); [line 26]\n NULLIFY(&i,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] + 8 -> 3 ; +7 [label="7: Prune (false branch) \n PRUNE(((n$0 == 0) == 0), false); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="invhouse"] 7 -> 3 ; -6 [label="6: Prune (false branch) \n PRUNE(((n$0 == 0) == 0), false); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="invhouse"] +6 [label="6: Prune (true branch) \n PRUNE(((n$0 == 0) != 0), true); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] - 6 -> 3 ; -5 [label="5: Prune (true branch) \n PRUNE(((n$0 == 0) != 0), true); [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n " shape="invhouse"] + 6 -> 8 ; +5 [label="5: BinaryOperatorStmt: EQ \n n$0=*&j:int [line 25]\n NULLIFY(&j,false); [line 25]\n " shape="box"] + 5 -> 6 ; 5 -> 7 ; -4 [label="4: BinaryOperatorStmt: EQ \n n$0=*&j:int [line 25]\n NULLIFY(&j,false); [line 25]\n " shape="box"] +4 [label="4: between_join_and_exit \n NULLIFY(&i,false); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] - 4 -> 5 ; - 4 -> 6 ; -3 [label="3: + \n NULLIFY(&i,false); [line 25]\n " ] + 4 -> 2 ; +3 [label="3: + \n " ] - 3 -> 2 ; + 3 -> 4 ; 2 [label="2: Exit MyClass_aMethod \n " color=yellow style=filled] 1 [label="1: Start MyClass_aMethod\nFormals: self:class MyClass *\nLocals: j:int i:int \n DECLARE_LOCALS(&return,&j,&i); [line 18]\n NULLIFY(&i,false); [line 18]\n NULLIFY(&j,false); [line 18]\n NULLIFY(&self,false); [line 18]\n " color=yellow style=filled] - 1 -> 14 ; + 1 -> 15 ; } diff --git a/infer/tests/codetoanalyze/objc/frontend/self_static/Self.dot b/infer/tests/codetoanalyze/objc/frontend/self_static/Self.dot index 4a786f36d..b4f159e35 100644 --- a/infer/tests/codetoanalyze/objc/frontend/self_static/Self.dot +++ b/infer/tests/codetoanalyze/objc/frontend/self_static/Self.dot @@ -1,36 +1,40 @@ digraph iCFG { -51 [label="51: Return Stmt \n *&return:int =0 [line 98]\n APPLY_ABSTRACTION; [line 98]\n " shape="box"] +52 [label="52: Return Stmt \n *&return:int =0 [line 98]\n APPLY_ABSTRACTION; [line 98]\n " shape="box"] + + + 52 -> 45 ; +51 [label="51: Return Stmt \n *&return:int =1 [line 96]\n APPLY_ABSTRACTION; [line 96]\n " shape="box"] 51 -> 45 ; -50 [label="50: Return Stmt \n *&return:int =1 [line 96]\n APPLY_ABSTRACTION; [line 96]\n " shape="box"] +50 [label="50: Prune (false branch) \n PRUNE(((sizeof(class A ) != n$15) == 0), false); [line 95]\n REMOVE_TEMPS(n$15); [line 95]\n " shape="invhouse"] - 50 -> 45 ; -49 [label="49: Prune (false branch) \n PRUNE(((sizeof(class A ) != n$15) == 0), false); [line 95]\n REMOVE_TEMPS(n$15); [line 95]\n " shape="invhouse"] + 50 -> 52 ; +49 [label="49: Prune (true branch) \n PRUNE(((sizeof(class A ) != n$15) != 0), true); [line 95]\n REMOVE_TEMPS(n$15); [line 95]\n " shape="invhouse"] 49 -> 51 ; -48 [label="48: Prune (true branch) \n PRUNE(((sizeof(class A ) != n$15) != 0), true); [line 95]\n REMOVE_TEMPS(n$15); [line 95]\n " shape="invhouse"] +48 [label="48: BinaryOperatorStmt: NE \n n$15=*&c:struct objc_class * [line 95]\n NULLIFY(&c,false); [line 95]\n " shape="box"] + 48 -> 49 ; 48 -> 50 ; -47 [label="47: BinaryOperatorStmt: NE \n n$15=*&c:struct objc_class * [line 95]\n NULLIFY(&c,false); [line 95]\n " shape="box"] +47 [label="47: between_join_and_exit \n NULLIFY(&c,false); [line 95]\n APPLY_ABSTRACTION; [line 95]\n " shape="box"] - 47 -> 48 ; - 47 -> 49 ; -46 [label="46: + \n NULLIFY(&c,false); [line 95]\n " ] + 47 -> 45 ; +46 [label="46: + \n " ] - 46 -> 45 ; + 46 -> 47 ; 45 [label="45: Exit A_used_in_binary_op: \n " color=yellow style=filled] 44 [label="44: Start A_used_in_binary_op:\nFormals: c:struct objc_class *\nLocals: \n DECLARE_LOCALS(&return); [line 94]\n " color=yellow style=filled] - 44 -> 47 ; + 44 -> 48 ; 43 [label="43: Return Stmt \n n$14=_fun_NSStringFromClass(sizeof(class A ):unsigned long ) [line 91]\n *&return:class NSString *=n$14 [line 91]\n REMOVE_TEMPS(n$14); [line 91]\n APPLY_ABSTRACTION; [line 91]\n " shape="box"] diff --git a/infer/tests/endtoend/c/MemoryLeakTest.java b/infer/tests/endtoend/c/MemoryLeakTest.java index 802a14d98..b769c5fbf 100644 --- a/infer/tests/endtoend/c/MemoryLeakTest.java +++ b/infer/tests/endtoend/c/MemoryLeakTest.java @@ -41,6 +41,7 @@ public class MemoryLeakTest { "simple_leak", "uses_allocator", "common_realloc_leak", + "conditional_last_instruction", }; assertThat( "Results should contain the expected memory leak errors",