diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 53cf3e602..3f8a485e3 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -568,7 +568,8 @@ struct leaf_nodes = leaf_nodes; ids = res_trans_idx.ids @ res_trans_a.ids; instrs = res_trans_a.instrs @ res_trans_idx.instrs; - exps = [(array_exp, typ)]} + exps = [(array_exp, typ)]; + initd_exps = res_trans_idx.initd_exps @ res_trans_a.initd_exps; } and binaryOperator_trans trans_state binary_operator_info stmt_info expr_info stmt_list = let open Clang_ast_t in @@ -783,7 +784,7 @@ struct cxx_method_construct_call_trans trans_state_pri result_trans_callee params_stmt si function_type - and cxxConstructExpr_trans trans_state var_exp expr = + and cxxConstructExpr_trans trans_state expr = match expr with | Clang_ast_t.CXXConstructExpr (si, params_stmt, ei, cxx_constr_info) -> let context = trans_state.context in @@ -791,7 +792,11 @@ struct let decl_ref = cxx_constr_info.Clang_ast_t.xcei_decl_ref in let class_type = CTypes_decl.get_type_from_expr_info ei context.CContext.tenv in let this_type = Sil.Tptr (class_type, Sil.Pk_pointer) in - let this_res_trans = { empty_res_trans with exps = [(var_exp, this_type)]} in + let var_exp = match trans_state.var_exp with Some e -> e | None -> assert false in + let this_res_trans = { empty_res_trans with + exps = [(var_exp, this_type)]; + initd_exps = [var_exp]; + } in let res_trans_callee = decl_ref_trans trans_state this_res_trans si ei decl_ref in let params_stmt' = assign_default_params params_stmt expr in cxx_method_construct_call_trans trans_state_pri res_trans_callee params_stmt' si @@ -979,7 +984,8 @@ struct leaf_nodes = [join_node]; ids = [id]; instrs = instrs; - exps = [(Sil.Var id, typ)] + exps = [(Sil.Var id, typ)]; + initd_exps = []; (* TODO we should get exps from branches+cond *) } | _ -> assert false) @@ -1012,7 +1018,13 @@ struct let rnodes = if (IList.length res_trans_cond.root_nodes) = 0 then [prune_t; prune_f] else res_trans_cond.root_nodes in - { root_nodes = rnodes; leaf_nodes =[prune_t; prune_f]; ids = res_trans_cond.ids; instrs = instrs'; exps = e' } in + { root_nodes = rnodes; + leaf_nodes = [prune_t; prune_f]; + ids = res_trans_cond.ids; + instrs = instrs'; + exps = e'; + initd_exps = []; + } in (* This function translate (s1 binop s2) doing shortcircuit for '&&' and '||' *) (* At the high level it does cond_trans s1; cond_trans s2; glue_nodes *) @@ -1043,7 +1055,9 @@ struct leaf_nodes = prune_to_short_c@res_trans_s2.leaf_nodes; ids = res_trans_s1.ids@res_trans_s2.ids; instrs = res_trans_s1.instrs@res_trans_s2.instrs; - exps = [(e_cond, typ1)] } in + exps = [(e_cond, typ1)]; + initd_exps = []; + } in Printing.log_out "Translating Condition for Conditional/Loop \n"; let open Clang_ast_t in match cond with @@ -1100,7 +1114,8 @@ struct leaf_nodes = [join_node]; ids = res_trans_decl.ids @ res_trans_cond.ids @ ids_t @ ids_f; instrs = []; - exps = [] + exps = []; + initd_exps = []; } | _ -> assert false) @@ -1226,7 +1241,7 @@ struct Cfg.Node.set_succs_exn 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; (* succ_nodes will remove the temps *) - { root_nodes = top_nodes; leaf_nodes = succ_nodes; ids = []; instrs = []; exps =[]} + { empty_res_trans with root_nodes = top_nodes; leaf_nodes = succ_nodes } | _ -> assert false and stmtExpr_trans trans_state stmt_info stmt_list expr_info = @@ -1243,11 +1258,11 @@ struct let id = Ident.create_fresh Ident.knormal in let loc = CLocation.get_sil_location stmt_info context in let instr' = Sil.Letderef (id, last, typ, loc) in - { root_nodes = res_trans_stmt.root_nodes; - leaf_nodes = res_trans_stmt.leaf_nodes; + { res_trans_stmt with ids = id :: idl; instrs = res_trans_stmt.instrs @ [instr']; - exps = [(Sil.Var id, typ)]} + exps = [(Sil.Var id, typ)]; + } | _ -> assert false and loop_instruction trans_state loop_kind stmt_info = @@ -1435,6 +1450,7 @@ struct ids = rh_ids; instrs = instructions; exps = [(var_exp, var_type)]; + initd_exps = [var_exp]; } ) else { root_nodes = []; @@ -1442,6 +1458,7 @@ struct ids = rh_ids; instrs = instructions; exps = [(var_exp, var_type)]; + initd_exps = [var_exp]; } ) @@ -1460,8 +1477,6 @@ struct | Some (ImplicitCastExpr (_, [CompoundLiteralExpr (_, [InitListExpr (stmt_info , stmts , expr_info)], _)], _, _)) | Some (ExprWithCleanups (_, [InitListExpr (stmt_info , stmts , expr_info)], _, _)) -> initListExpr_trans trans_state var_exp stmt_info expr_info stmts - | Some (CXXConstructExpr _ as expr) -> - cxxConstructExpr_trans trans_state var_exp expr | Some ie -> (*For init expr, translate how to compute it and assign to the var*) let stmt_info, _ = Clang_ast_proj.get_stmt_tuple ie in let context = trans_state.context in @@ -1469,7 +1484,7 @@ struct let trans_state_pri = PriorityNode.try_claim_priority_node trans_state var_stmt_info in (* if ie is a block the translation need to be done with the block special cases by exec_with_block_priority*) let res_trans_ie = - let trans_state' = { trans_state_pri with succ_nodes = [] } in + let trans_state' = { trans_state_pri with succ_nodes = []; var_exp = Some var_exp } in let instruction' = exec_with_self_exception (exec_with_lvalue_as_reference instruction) in exec_with_block_priority_exception instruction' trans_state' ie var_stmt_info in @@ -1477,7 +1492,9 @@ struct "WARNING: In DeclStmt we expect only one expression returned in recursive call\n" in let rhs_owning_method = CTrans_utils.is_owning_method ie in let _, instrs_assign, ids_assign = - if !Config.arc_mode && + (* variable might be initialized already - do nothing in that case*) + if IList.exists (Sil.exp_equal var_exp) res_trans_ie.initd_exps then ([], [], []) + else if !Config.arc_mode && (CTrans_utils.is_method_call ie || ObjcInterface_decl.is_pointer_to_objc_class context.CContext.tenv ie_typ) then (* In arc mode, if it's a method call or we are initializing with a pointer to objc class *) (* we need to add retain/release *) @@ -1515,7 +1532,8 @@ struct { root_nodes = res_trans_tmp.root_nodes; leaf_nodes = []; ids = res_trans_tmp.ids @ res_trans_vd.ids; instrs = res_trans_tmp.instrs @ res_trans_vd.instrs; - exps = res_trans_tmp.exps @ res_trans_vd.exps } + exps = res_trans_tmp.exps @ res_trans_vd.exps; + initd_exps = res_trans_tmp.initd_exps @ res_trans_vd.initd_exps; } | CXXRecordDecl _ :: var_decls' (*C++/C record decl treated in the same way *) | RecordDecl _ :: var_decls' -> (* Record declaration is done in the beginning when procdesc is defined.*) @@ -1595,11 +1613,11 @@ struct let cast_kind = cast_expr_info.Clang_ast_t.cei_cast_kind in (* This gives the differnece among cast operations kind*) let cast_ids, cast_inst, cast_exp = cast_operation context cast_kind res_trans_stmt.exps typ sil_loc is_objc_bridged in - { root_nodes = res_trans_stmt.root_nodes; - leaf_nodes = res_trans_stmt.leaf_nodes; + { res_trans_stmt with ids = res_trans_stmt.ids @ cast_ids; instrs = res_trans_stmt.instrs @ cast_inst; - exps = [cast_exp] } + exps = [cast_exp]; + } (* function used in the computation for both Member_Expr and ObjCIVarRefExpr *) and do_memb_ivar_ref_exp trans_state expr_info stmt_info stmt_list decl_ref = @@ -1867,6 +1885,9 @@ struct | CXXOperatorCallExpr(stmt_info, stmt_list, ei) -> callExpr_trans trans_state stmt_info stmt_list ei + | CXXConstructExpr _ -> + cxxConstructExpr_trans trans_state instr + | ObjCMessageExpr(stmt_info, stmt_list, expr_info, obj_c_message_expr_info) -> if is_block_enumerate_function obj_c_message_expr_info then block_enumeration_trans trans_state stmt_info stmt_list expr_info @@ -2069,7 +2090,8 @@ struct leaf_nodes = []; ids = res_trans_s.ids @ res_trans_tail.ids; instrs = res_trans_tail.instrs @ res_trans_s.instrs; - exps = res_trans_tail.exps @ res_trans_s.exps } + exps = res_trans_tail.exps @ res_trans_s.exps; + initd_exps = res_trans_tail.initd_exps @ res_trans_s.initd_exps; } and get_clang_stmt_trans stmt_list = let instruction' = fun stmt -> fun trans_state -> instruction trans_state stmt in @@ -2093,6 +2115,7 @@ struct succ_nodes = []; continuation = None; priority = Free; + var_exp = None; } in let res_trans_stmt = instruction trans_state stmt in fst (CTrans_utils.extract_exp_from_list res_trans_stmt.exps warning) @@ -2103,6 +2126,7 @@ struct succ_nodes = [exit_node]; continuation = None; priority = Free; + var_exp = None; } in let clang_ast_trans = get_clang_stmt_trans clang_stmt_list in let extra_stmt_trans = get_custom_stmt_trans extra_instrs in diff --git a/infer/src/clang/cTrans_utils.ml b/infer/src/clang/cTrans_utils.ml index 8ae9a01bf..9d35ff22a 100644 --- a/infer/src/clang/cTrans_utils.ml +++ b/infer/src/clang/cTrans_utils.ml @@ -136,6 +136,7 @@ type trans_state = { succ_nodes: Cfg.Node.t list; (* successor nodes in the cfg *) continuation: continuation option; (* current continuation *) priority: priority_node; + var_exp: Sil.exp option; } (* A translation result. It is returned by the translation function. *) @@ -145,10 +146,18 @@ type trans_result = { ids: Ident.t list; (* list of temp identifiers created that need to be removed by the caller *) instrs: Sil.instr list; (* list of SIL instruction that need to be placed in cfg nodes of the parent*) exps: (Sil.exp * Sil.typ) list; (* SIL expressions resulting from the translation of the clang stmt *) + initd_exps: Sil.exp list; } (* Empty result translation *) -let empty_res_trans = { root_nodes =[]; leaf_nodes =[]; ids =[]; instrs =[]; exps =[]} +let empty_res_trans = { + root_nodes = []; + leaf_nodes = []; + ids = []; + instrs = []; + exps = []; + initd_exps = []; +} (** Collect the results of translating a list of instructions, and link up the nodes created. *) let collect_res_trans l = @@ -169,7 +178,8 @@ let collect_res_trans l = leaf_nodes = leaf_nodes; ids = rt.ids@rt'.ids; instrs = rt.instrs@rt'.instrs; - exps = rt.exps@rt'.exps } in + exps = rt.exps@rt'.exps; + initd_exps = rt.initd_exps@rt'.initd_exps; } in collect l empty_res_trans (* priority_node is used to enforce some kind of policy for creating nodes *) @@ -232,11 +242,13 @@ struct (* 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 - { root_nodes = root_nodes; + { res_state with + root_nodes = root_nodes; leaf_nodes = [node]; ids = ids_parent; instrs = []; - exps = []} + exps = []; + } else (* The node is created by the parent. We just pass back nodes/leafs params *) { res_state with exps = []} @@ -421,21 +433,13 @@ let trans_assertion_failure sil_loc 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] []; - { root_nodes = [failure_node]; - leaf_nodes = []; - ids = []; - instrs =[]; - exps = [] } + { 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 []; - { root_nodes = [prune_node]; - leaf_nodes = [prune_node]; - ids = []; - instrs = []; - exps = [] } + { empty_res_trans with root_nodes = [prune_node]; leaf_nodes = [prune_node] } let define_condition_side_effects context e_cond instrs_cond sil_loc = let (e', typ) = extract_exp_from_list e_cond "\nWARNING: Missing expression in IfStmt. Need to be fixed\n" in diff --git a/infer/src/clang/cTrans_utils.mli b/infer/src/clang/cTrans_utils.mli index 5ce94f559..ac1c0f83f 100644 --- a/infer/src/clang/cTrans_utils.mli +++ b/infer/src/clang/cTrans_utils.mli @@ -24,6 +24,7 @@ type trans_state = { succ_nodes: Cfg.Node.t list; continuation: continuation option; priority: priority_node; + var_exp: Sil.exp option; } type trans_result = { @@ -32,6 +33,7 @@ type trans_result = { ids: Ident.t list; instrs: Sil.instr list; exps: (Sil.exp * Sil.typ) list; + initd_exps: Sil.exp list; } val empty_res_trans: trans_result diff --git a/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_default_arg.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_default_arg.cpp.dot index 92c724766..434e7b092 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_default_arg.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_default_arg.cpp.dot @@ -1,13 +1,13 @@ digraph iCFG { -11 [label="11: Call _fun_X_X \n _fun_X_X(&x1:class X *,0:int ,0:int ) [line 22]\n " shape="box"] +11 [label="11: DeclStmt \n _fun_X_X(&x1:class X *,0:int ,0:int ) [line 22]\n " shape="box"] 11 -> 10 ; -10 [label="10: Call _fun_X_X \n _fun_X_X(&x2:class X *,1:int ,0:int ) [line 23]\n " shape="box"] +10 [label="10: DeclStmt \n _fun_X_X(&x2:class X *,1:int ,0:int ) [line 23]\n " shape="box"] 10 -> 9 ; -9 [label="9: Call _fun_X_X \n _fun_X_X(&x3:class X *,0:int ,1:int ) [line 24]\n NULLIFY(&x1,false); [line 24]\n NULLIFY(&x2,false); [line 24]\n NULLIFY(&x3,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"] +9 [label="9: DeclStmt \n _fun_X_X(&x3:class X *,0:int ,1:int ) [line 24]\n NULLIFY(&x1,false); [line 24]\n NULLIFY(&x2,false); [line 24]\n NULLIFY(&x3,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"] 9 -> 8 ; diff --git a/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp.dot index ccb3a206d..13b6764bc 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp.dot @@ -1,5 +1,5 @@ digraph iCFG { -26 [label="26: Call _fun_X_X \n _fun_X_X(&x:class X *,0:int ,1:int ) [line 40]\n " shape="box"] +26 [label="26: DeclStmt \n _fun_X_X(&x:class X *,0:int ,1:int ) [line 40]\n " shape="box"] 26 -> 25 ; @@ -14,7 +14,7 @@ digraph iCFG { 23 -> 26 ; -22 [label="22: Call _fun_X_X \n _fun_X_X(&x:class X *) [line 35]\n " shape="box"] +22 [label="22: DeclStmt \n _fun_X_X(&x:class X *) [line 35]\n " shape="box"] 22 -> 21 ; @@ -29,7 +29,7 @@ digraph iCFG { 19 -> 22 ; -18 [label="18: Call _fun_X_X \n _fun_X_X(&x:class X *,-2:int ,2:int ) [line 30]\n " shape="box"] +18 [label="18: DeclStmt \n _fun_X_X(&x:class X *,-2:int ,2:int ) [line 30]\n " shape="box"] 18 -> 17 ; diff --git a/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot index 585ea4664..6c4a5b6f1 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot @@ -1,9 +1,9 @@ digraph iCFG { -24 [label="24: Call _fun_foo::my_record_ \n _fun_foo::my_record_(&x:struct foo::my_record *) [line 45]\n " shape="box"] +24 [label="24: DeclStmt \n _fun_foo::my_record_(&x:struct foo::my_record *) [line 45]\n " shape="box"] 24 -> 23 ; -23 [label="23: Call _fun_bar::Rectangle_Rectangle \n _fun_bar::Rectangle_Rectangle(&rect1:class bar::Rectangle *) [line 47]\n " shape="box"] +23 [label="23: DeclStmt \n _fun_bar::Rectangle_Rectangle(&rect1:class bar::Rectangle *) [line 47]\n " shape="box"] 23 -> 22 ; @@ -11,7 +11,7 @@ digraph iCFG { 22 -> 21 ; -21 [label="21: Call _fun_foo::Rectangle_Rectangle \n _fun_foo::Rectangle_Rectangle(&rect2:class foo::Rectangle *) [line 50]\n " shape="box"] +21 [label="21: DeclStmt \n _fun_foo::Rectangle_Rectangle(&rect2:class foo::Rectangle *) [line 50]\n " shape="box"] 21 -> 20 ; diff --git a/infer/tests/codetoanalyze/cpp/frontend/templates/function.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/templates/function.cpp.dot index 9e3711dcd..5a4cfa9c0 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/templates/function.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/templates/function.cpp.dot @@ -21,11 +21,11 @@ digraph iCFG { 44 -> 46 ; -43 [label="43: Call _fun_X1_X1 \n _fun_X1_X1(&x1:class X1 *) [line 62]\n " shape="box"] +43 [label="43: DeclStmt \n _fun_X1_X1(&x1:class X1 *) [line 62]\n " shape="box"] 43 -> 42 ; -42 [label="42: Call _fun_X3_X3 \n _fun_X3_X3(&x3:class X3 *) [line 63]\n " shape="box"] +42 [label="42: DeclStmt \n _fun_X3_X3(&x3:class X3 *) [line 63]\n " shape="box"] 42 -> 41 ; @@ -40,11 +40,11 @@ digraph iCFG { 39 -> 43 ; -38 [label="38: Call _fun_X1_X1 \n _fun_X1_X1(&x1:class X1 *) [line 56]\n " shape="box"] +38 [label="38: DeclStmt \n _fun_X1_X1(&x1:class X1 *) [line 56]\n " shape="box"] 38 -> 37 ; -37 [label="37: Call _fun_X3_X3 \n _fun_X3_X3(&x3:class X3 *) [line 57]\n " shape="box"] +37 [label="37: DeclStmt \n _fun_X3_X3(&x3:class X3 *) [line 57]\n " shape="box"] 37 -> 36 ; @@ -81,7 +81,7 @@ digraph iCFG { 28 -> 30 ; -27 [label="27: Call _fun_X1_X1 \n _fun_X1_X1(&x:class X1 *) [line 35]\n " shape="box"] +27 [label="27: DeclStmt \n _fun_X1_X1(&x:class X1 *) [line 35]\n " shape="box"] 27 -> 26 ; @@ -96,7 +96,7 @@ digraph iCFG { 24 -> 27 ; -23 [label="23: Call _fun_X3_X3 \n _fun_X3_X3(&x:class X3 *) [line 35]\n " shape="box"] +23 [label="23: DeclStmt \n _fun_X3_X3(&x:class X3 *) [line 35]\n " shape="box"] 23 -> 22 ; diff --git a/infer/tests/codetoanalyze/cpp/frontend/templates/method.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/templates/method.cpp.dot index fdffe2b80..cb3af7ba7 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/templates/method.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/templates/method.cpp.dot @@ -1,9 +1,9 @@ digraph iCFG { -73 [label="73: Call _fun_X1_X1 \n _fun_X1_X1(&x1:class X1 *) [line 66]\n " shape="box"] +73 [label="73: DeclStmt \n _fun_X1_X1(&x1:class X1 *) [line 66]\n " shape="box"] 73 -> 72 ; -72 [label="72: Call _fun_GetterTempl_GetterTempl \n _fun_GetterTempl_GetterTempl(&g:class GetterTempl *) [line 67]\n " shape="box"] +72 [label="72: DeclStmt \n _fun_GetterTempl_GetterTempl(&g:class GetterTempl *) [line 67]\n " shape="box"] 72 -> 71 ; @@ -18,15 +18,15 @@ digraph iCFG { 69 -> 73 ; -68 [label="68: Call _fun_X1_X1 \n _fun_X1_X1(&x1:class X1 *) [line 59]\n " shape="box"] +68 [label="68: DeclStmt \n _fun_X1_X1(&x1:class X1 *) [line 59]\n " shape="box"] 68 -> 67 ; -67 [label="67: Call _fun_X2_X2 \n _fun_X2_X2(&x2:class X2 *) [line 60]\n " shape="box"] +67 [label="67: DeclStmt \n _fun_X2_X2(&x2:class X2 *) [line 60]\n " shape="box"] 67 -> 66 ; -66 [label="66: Call _fun_GetterTempl_GetterTempl \n _fun_GetterTempl_GetterTempl(&g:class GetterTempl *) [line 61]\n " shape="box"] +66 [label="66: DeclStmt \n _fun_GetterTempl_GetterTempl(&g:class GetterTempl *) [line 61]\n " shape="box"] 66 -> 65 ; @@ -41,11 +41,11 @@ digraph iCFG { 63 -> 68 ; -62 [label="62: Call _fun_X2_X2 \n _fun_X2_X2(&x2:class X2 *) [line 53]\n " shape="box"] +62 [label="62: DeclStmt \n _fun_X2_X2(&x2:class X2 *) [line 53]\n " shape="box"] 62 -> 61 ; -61 [label="61: Call _fun_GetterTempl_GetterTempl \n _fun_GetterTempl_GetterTempl(&g:class GetterTempl *) [line 54]\n " shape="box"] +61 [label="61: DeclStmt \n _fun_GetterTempl_GetterTempl(&g:class GetterTempl *) [line 54]\n " shape="box"] 61 -> 60 ; @@ -60,15 +60,15 @@ digraph iCFG { 58 -> 62 ; -57 [label="57: Call _fun_X2_X2 \n _fun_X2_X2(&x2:class X2 *) [line 46]\n " shape="box"] +57 [label="57: DeclStmt \n _fun_X2_X2(&x2:class X2 *) [line 46]\n " shape="box"] 57 -> 56 ; -56 [label="56: Call _fun_X3_X3 \n _fun_X3_X3(&x3:class X3 *) [line 47]\n " shape="box"] +56 [label="56: DeclStmt \n _fun_X3_X3(&x3:class X3 *) [line 47]\n " shape="box"] 56 -> 55 ; -55 [label="55: Call _fun_GetterTempl_GetterTempl \n _fun_GetterTempl_GetterTempl(&g:class GetterTempl *) [line 48]\n " shape="box"] +55 [label="55: DeclStmt \n _fun_GetterTempl_GetterTempl(&g:class GetterTempl *) [line 48]\n " shape="box"] 55 -> 54 ; @@ -83,11 +83,11 @@ digraph iCFG { 52 -> 57 ; -51 [label="51: Call _fun_X1_X1 \n _fun_X1_X1(&x1:class X1 *) [line 40]\n " shape="box"] +51 [label="51: DeclStmt \n _fun_X1_X1(&x1:class X1 *) [line 40]\n " shape="box"] 51 -> 50 ; -50 [label="50: Call _fun_Getter_Getter \n _fun_Getter_Getter(&g:class Getter *) [line 41]\n " shape="box"] +50 [label="50: DeclStmt \n _fun_Getter_Getter(&g:class Getter *) [line 41]\n " shape="box"] 50 -> 49 ; @@ -102,11 +102,11 @@ digraph iCFG { 47 -> 51 ; -46 [label="46: Call _fun_X2_X2 \n _fun_X2_X2(&x2:class X2 *) [line 34]\n " shape="box"] +46 [label="46: DeclStmt \n _fun_X2_X2(&x2:class X2 *) [line 34]\n " shape="box"] 46 -> 45 ; -45 [label="45: Call _fun_Getter_Getter \n _fun_Getter_Getter(&g:class Getter *) [line 35]\n " shape="box"] +45 [label="45: DeclStmt \n _fun_Getter_Getter(&g:class Getter *) [line 35]\n " shape="box"] 45 -> 44 ;