[pdesc][refactor] ability to set normal and exceptional succs independently

Summary:
- more flexible API
- less error-prone thanks to named parameters
- also takes care of adjusting predecessors of the previous successors!
This fixes some (probably harmless) bugs in the frontends.

Reviewed By: dulmarod

Differential Revision: D18573923

fbshipit-source-id: ad97b3607
master
Jules Villard 5 years ago committed by Facebook Github Bot
parent 883044763e
commit b03ca78bf3

@ -590,13 +590,17 @@ let set_start_node pdesc node = pdesc.start_node <- node
(** Append the locals to the list of local variables *)
let append_locals pdesc new_locals = pdesc.attributes.locals <- pdesc.attributes.locals @ new_locals
let set_succs_exn_only (node : Node.t) exn = node.exn <- exn
(** Set the successor nodes and exception nodes, and build predecessor links *)
let set_succs_exn_base (node : Node.t) succs exn =
node.succs <- succs ;
node.exn <- exn ;
List.iter ~f:(fun (n : Node.t) -> n.preds <- node :: n.preds) succs
let set_succs (node : Node.t) ~normal:succs_opt ~exn:exn_opt =
let remove_pred pred_node (from_node : Node.t) =
from_node.preds <- List.filter from_node.preds ~f:(fun pred -> not (Node.equal pred pred_node))
in
let add_pred pred_node (to_node : Node.t) = to_node.preds <- pred_node :: to_node.preds in
Option.iter succs_opt ~f:(fun new_succs ->
List.iter node.succs ~f:(remove_pred node) ;
List.iter new_succs ~f:(add_pred node) ;
node.succs <- new_succs ) ;
Option.iter exn_opt ~f:(fun exn -> node.exn <- exn)
(** Create a new cfg node *)
@ -626,15 +630,15 @@ let create_node pdesc loc kind instrs =
(** 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 node_set_succs_exn pdesc (node : Node.t) succs exn =
let node_set_succs pdesc (node : Node.t) ~normal:succs ~exn =
match (node.kind, succs) with
| Join_node, [({Node.kind= Exit_node} as exit_node)] ->
let kind = Node.Stmt_node BetweenJoinAndExit in
let node' = create_node_from_not_reversed pdesc node.loc kind node.instrs in
set_succs_exn_base node [node'] exn ;
set_succs_exn_base node' [exit_node] exn
set_succs node ~normal:(Some [node']) ~exn:(Some exn) ;
set_succs node' ~normal:(Some [exit_node]) ~exn:(Some exn)
| _ ->
set_succs_exn_base node succs exn
set_succs node ~normal:(Some succs) ~exn:(Some exn)
module PreProcCfg = struct

@ -285,10 +285,11 @@ val fold_nodes : t -> init:'accum -> f:('accum -> Node.t -> 'accum) -> 'accum
val fold_slope_range : Node.t -> Node.t -> init:'accum -> f:('accum -> Node.t -> 'accum) -> 'accum
(** fold between two nodes or until we reach a branching structure *)
val set_succs_exn_only : Node.t -> Node.t list -> unit
val set_succs : Node.t -> normal:Node.t list option -> exn:Node.t list option -> unit
(** Set the successor nodes and exception nodes, if given, and update predecessor links *)
val node_set_succs_exn : t -> Node.t -> Node.t list -> Node.t list -> unit
(** Set the successor nodes and exception nodes, and build predecessor links *)
val node_set_succs : t -> Node.t -> normal:Node.t list -> exn:Node.t list -> unit
(** Set the successor nodes and exception nodes, and update predecessor links *)
val set_exit_node : t -> Node.t -> unit
(** Set the exit node of the procedure *)

@ -33,7 +33,8 @@ let convert_cfg ~callee_pdesc ~resolved_pdesc ~f_instr_list =
Procdesc.set_start_node resolved_pdesc new_node ;
if Procdesc.Node.equal node callee_exit_node then
Procdesc.set_exit_node resolved_pdesc new_node ;
Procdesc.node_set_succs_exn callee_pdesc new_node (loop successors) (loop exn_nodes) ;
Procdesc.node_set_succs callee_pdesc new_node ~normal:(loop successors)
~exn:(loop exn_nodes) ;
new_node
in
converted_node :: loop other_node

@ -49,7 +49,7 @@ module CFrontend_decl_funct (T : CModule_type.CTranslation) : CModule_type.CFron
let meth_body_nodes =
T.instructions_trans context body extra_instrs exit_node ~is_destructor_wrapper
in
Procdesc.node_set_succs_exn procdesc start_node meth_body_nodes [] ;
Procdesc.node_set_succs procdesc start_node ~normal:meth_body_nodes ~exn:[] ;
match Procdesc.is_connected procdesc with
| Ok () ->
()

@ -739,7 +739,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
CLocation.location_of_stmt_info context.translation_unit_context.source_file stmt_info
in
let root_node' = GotoLabel.find_goto_label trans_state.context label_name sil_loc in
Procdesc.node_set_succs_exn context.procdesc root_node' res_trans.control.root_nodes [] ;
Procdesc.node_set_succs context.procdesc root_node' ~normal:res_trans.control.root_nodes ~exn:[] ;
mk_trans_result (mk_fresh_void_exp_typ ())
{empty_control with root_nodes= [root_node']; leaf_nodes= trans_state.succ_nodes}
@ -892,7 +892,8 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
if res_trans_idx.control.root_nodes <> [] then
List.iter
~f:(fun n ->
Procdesc.node_set_succs_exn context.procdesc n res_trans_idx.control.root_nodes [] )
Procdesc.node_set_succs context.procdesc n ~normal:res_trans_idx.control.root_nodes
~exn:[] )
res_trans_a.control.leaf_nodes ;
(* Note the order of res_trans_idx.ids @ res_trans_a.ids is important. *)
(* We expect to use only res_trans_idx.ids in construction of other operation. *)
@ -1507,7 +1508,8 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let prune_nodes_t, prune_nodes_f = List.partition_tf ~f:is_true_prune_node prune_nodes in
let prune_nodes' = if branch then prune_nodes_t else prune_nodes_f in
List.iter
~f:(fun n -> Procdesc.node_set_succs_exn context.procdesc n res_trans.control.root_nodes [])
~f:(fun n ->
Procdesc.node_set_succs context.procdesc n ~normal:res_trans.control.root_nodes ~exn:[] )
prune_nodes' ;
res_trans
in
@ -1521,7 +1523,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
Procdesc.create_node trans_state.context.CContext.procdesc sil_loc Procdesc.Node.Join_node
[]
in
Procdesc.node_set_succs_exn context.procdesc join_node succ_nodes [] ;
Procdesc.node_set_succs context.procdesc join_node ~normal:succ_nodes ~exn:[] ;
let pvar = CVar_decl.mk_temp_sil_var procdesc ~name:"SIL_temp_conditional___" in
let var_data =
ProcAttributes.
@ -1631,7 +1633,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let prune_t = mk_prune_node ~branch:true ~negate_cond e' instrs' in
let prune_f = mk_prune_node ~branch:false ~negate_cond:(not negate_cond) e' instrs' in
List.iter
~f:(fun n' -> Procdesc.node_set_succs_exn context.procdesc n' [prune_t; prune_f] [])
~f:(fun n' -> Procdesc.node_set_succs context.procdesc n' ~normal:[prune_t; prune_f] ~exn:[])
res_trans_cond.control.leaf_nodes ;
let root_nodes =
if List.is_empty res_trans_cond.control.root_nodes then [prune_t; prune_f]
@ -1668,7 +1670,8 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
in
List.iter
~f:(fun n ->
Procdesc.node_set_succs_exn context.procdesc n res_trans_s2.control.root_nodes [] )
Procdesc.node_set_succs context.procdesc n ~normal:res_trans_s2.control.root_nodes ~exn:[]
)
prune_to_s2 ;
let root_nodes_to_parent =
if List.is_empty res_trans_s1.control.root_nodes then res_trans_s1.control.leaf_nodes
@ -1738,11 +1741,11 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let prune_nodes_t, prune_nodes_f = List.partition_tf ~f:is_true_prune_node prune_nodes in
let prune_nodes' = if branch then prune_nodes_t else prune_nodes_f in
List.iter
~f:(fun n -> Procdesc.node_set_succs_exn context.procdesc n nodes_branch [])
~f:(fun n -> Procdesc.node_set_succs context.procdesc n ~normal:nodes_branch ~exn:[])
prune_nodes'
in
let join_node = Procdesc.create_node context.procdesc sil_loc Procdesc.Node.Join_node [] in
Procdesc.node_set_succs_exn context.procdesc join_node trans_state.succ_nodes [] ;
Procdesc.node_set_succs context.procdesc join_node ~normal:trans_state.succ_nodes ~exn:[] ;
let trans_state_join_succ = {trans_state with succ_nodes= [join_node]} in
(* translate the condition expression *)
let res_trans_cond =
@ -1835,7 +1838,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
Procdesc.create_node context.procdesc sil_loc node_kind res_trans_cond_tmp.control.instrs
in
List.iter
~f:(fun n' -> Procdesc.node_set_succs_exn context.procdesc n' [switch_node] [])
~f:(fun n' -> Procdesc.node_set_succs context.procdesc n' ~normal:[switch_node] ~exn:[])
res_trans_cond_tmp.control.leaf_nodes ;
let root_nodes =
if res_trans_cond_tmp.control.root_nodes <> [] then res_trans_cond_tmp.control.root_nodes
@ -1889,8 +1892,8 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
create_prune_node context.procdesc ~branch:false ~negate_cond:true sil_eq_cond
res_trans_case_const.control.instrs sil_loc Sil.Ik_switch
in
Procdesc.node_set_succs_exn context.procdesc true_prune_node root_nodes [] ;
Procdesc.node_set_succs_exn context.procdesc false_prune_node curr_succ_nodes [] ;
Procdesc.node_set_succs context.procdesc true_prune_node ~normal:root_nodes ~exn:[] ;
Procdesc.node_set_succs context.procdesc false_prune_node ~normal:curr_succ_nodes ~exn:[] ;
(* return prune nodes as next roots *)
[true_prune_node; false_prune_node]
| {SwitchCase.condition= Default; root_nodes} ->
@ -1900,7 +1903,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let cases_root_nodes =
List.fold switch_cases ~init:trans_state.succ_nodes ~f:link_up_switch_cases
in
Procdesc.node_set_succs_exn context.procdesc switch_node cases_root_nodes [] ;
Procdesc.node_set_succs context.procdesc switch_node ~normal:cases_root_nodes ~exn:[] ;
let top_nodes = variable_result.control.root_nodes in
mk_trans_result (mk_fresh_void_exp_typ ())
{empty_control with root_nodes= top_nodes; leaf_nodes= trans_state.succ_nodes}
@ -1947,7 +1950,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
| Procdesc.Node.Stmt_node ReturnStmt ->
()
| _ ->
Procdesc.set_succs_exn_only try_end catch_start_nodes )
Procdesc.set_succs try_end ~normal:None ~exn:(Some catch_start_nodes) )
try_ends ;
try_trans_result
| _ ->
@ -2037,12 +2040,12 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
| Loops.DoWhile _ ->
[join_node]
in
Procdesc.node_set_succs_exn context.procdesc join_node join_succ_nodes [] ;
Procdesc.node_set_succs context.procdesc join_node ~normal:join_succ_nodes ~exn:[] ;
List.iter
~f:(fun n -> Procdesc.node_set_succs_exn context.procdesc n prune_t_succ_nodes [])
~f:(fun n -> Procdesc.node_set_succs context.procdesc n ~normal:prune_t_succ_nodes ~exn:[])
prune_nodes_t ;
List.iter
~f:(fun n -> Procdesc.node_set_succs_exn context.procdesc n succ_nodes [])
~f:(fun n -> Procdesc.node_set_succs context.procdesc n ~normal:succ_nodes ~exn:[])
prune_nodes_f ;
let root_nodes =
match loop_kind with
@ -2582,9 +2585,9 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
Procdesc.create_node context.procdesc sil_loc (Procdesc.Node.Stmt_node ReturnStmt)
(instrs @ instrs_of destr_trans_result @ instrs_of destructor_res)
in
Procdesc.node_set_succs_exn context.procdesc ret_node
[Procdesc.get_exit_node context.CContext.procdesc]
[] ;
Procdesc.node_set_succs context.procdesc ret_node
~normal:[Procdesc.get_exit_node context.CContext.procdesc]
~exn:[] ;
ret_node
in
let trans_result =
@ -2622,7 +2625,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
let instrs = var_instrs @ res_trans_stmt.control.instrs @ ret_instrs in
let ret_node = mk_ret_node instrs in
List.iter
~f:(fun n -> Procdesc.node_set_succs_exn procdesc n [ret_node] [])
~f:(fun n -> Procdesc.node_set_succs procdesc n ~normal:[ret_node] ~exn:[])
res_trans_stmt.control.leaf_nodes ;
let root_nodes_to_parent =
if List.length res_trans_stmt.control.root_nodes > 0 then

@ -163,7 +163,7 @@ let collect_controls pdesc l =
let collect_one result_rev {root_nodes; leaf_nodes; instrs; initd_exps} =
if root_nodes <> [] then
List.iter
~f:(fun n -> Procdesc.node_set_succs_exn pdesc n root_nodes [])
~f:(fun n -> Procdesc.node_set_succs pdesc n ~normal:root_nodes ~exn:[])
result_rev.leaf_nodes ;
let root_nodes = if result_rev.root_nodes <> [] then result_rev.root_nodes else root_nodes in
let leaf_nodes = if leaf_nodes <> [] then leaf_nodes else result_rev.leaf_nodes in
@ -219,9 +219,11 @@ module PriorityNode = struct
let node =
Procdesc.create_node trans_state.context.CContext.procdesc loc node_kind res_state.instrs
in
Procdesc.node_set_succs_exn trans_state.context.procdesc node trans_state.succ_nodes [] ;
Procdesc.node_set_succs trans_state.context.procdesc node ~normal:trans_state.succ_nodes
~exn:[] ;
List.iter
~f:(fun leaf -> Procdesc.node_set_succs_exn trans_state.context.procdesc leaf [node] [])
~f:(fun leaf ->
Procdesc.node_set_succs trans_state.context.procdesc leaf ~normal:[node] ~exn:[] )
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
@ -465,7 +467,7 @@ let trans_assertion_failure sil_loc (context : CContext.t) =
Procdesc.create_node context.CContext.procdesc sil_loc
(Procdesc.Node.Stmt_node AssertionFailure) [call_instr]
in
Procdesc.node_set_succs_exn context.procdesc failure_node [exit_node] [] ;
Procdesc.node_set_succs context.procdesc failure_node ~normal:[exit_node] ~exn:[] ;
mk_trans_result (Exp.Var ret_id, ret_typ) {empty_control with root_nodes= [failure_node]}
@ -476,7 +478,7 @@ let trans_assume_false sil_loc (context : CContext.t) succ_nodes =
Procdesc.create_node context.CContext.procdesc sil_loc (Nodes.prune_kind true if_kind)
instrs_cond
in
Procdesc.node_set_succs_exn context.procdesc prune_node succ_nodes [] ;
Procdesc.node_set_succs context.procdesc prune_node ~normal:succ_nodes ~exn:[] ;
mk_trans_result
(Exp.zero, Typ.(mk (Tint IInt)))
{empty_control with root_nodes= [prune_node]; leaf_nodes= [prune_node]}

@ -57,7 +57,8 @@ let add_edges (context : JContext.t) start_node exn_node exit_nodes method_body_
else JTransExn.create_exception_handlers context [exn_node] get_body_nodes impl
in
let connect node pc =
Procdesc.node_set_succs_exn context.procdesc node (get_succ_nodes node pc) (get_exn_nodes pc)
Procdesc.node_set_succs context.procdesc node ~normal:(get_succ_nodes node pc)
~exn:(get_exn_nodes pc)
in
let connect_nodes pc translated_instruction =
match translated_instruction with
@ -68,7 +69,7 @@ let add_edges (context : JContext.t) start_node exn_node exit_nodes method_body_
| JTrans.Prune (node_true, node_false) ->
connect node_true pc ; connect node_false pc
| JTrans.Loop (join_node, node_true, node_false) ->
Procdesc.node_set_succs_exn context.procdesc join_node [node_true; node_false] [] ;
Procdesc.node_set_succs context.procdesc join_node ~normal:[node_true; node_false] ~exn:[] ;
connect node_true pc ;
connect node_false pc
in
@ -77,10 +78,10 @@ let add_edges (context : JContext.t) start_node exn_node exit_nodes method_body_
direct_successors (-1) Int.Set.empty
in
(* the exceptions edges here are going directly to the exit node *)
Procdesc.node_set_succs_exn context.procdesc start_node first_nodes exit_nodes ;
Procdesc.node_set_succs context.procdesc start_node ~normal:first_nodes ~exn:exit_nodes ;
if not super_call then
(* the exceptions node is just before the exit node *)
Procdesc.node_set_succs_exn context.procdesc exn_node exit_nodes exit_nodes ;
Procdesc.node_set_succs context.procdesc exn_node ~normal:exit_nodes ~exn:exit_nodes ;
Array.iteri ~f:connect_nodes method_body_nodes

@ -325,7 +325,7 @@ let create_empty_cfg source_file procdesc =
let location = Location.none source_file in
let start_node = Procdesc.create_node procdesc location Procdesc.Node.Start_node [] in
let exit_node = Procdesc.create_node procdesc location Procdesc.Node.Exit_node [] in
Procdesc.node_set_succs_exn procdesc start_node [exit_node] [exit_node] ;
Procdesc.node_set_succs procdesc start_node ~normal:[exit_node] ~exn:[exit_node] ;
Procdesc.set_start_node procdesc start_node ;
Procdesc.set_exit_node procdesc exit_node ;
procdesc

@ -65,7 +65,7 @@ let translate_exceptions (context : JContext.t) exit_nodes get_body_nodes handle
match handler.JBir.e_catch_type with
| None ->
let finally_node = create_node loc (Procdesc.Node.Stmt_node FinallyBranch) [] in
Procdesc.node_set_succs_exn procdesc finally_node catch_nodes exit_nodes ;
Procdesc.node_set_succs procdesc finally_node ~normal:catch_nodes ~exn:exit_nodes ;
[finally_node]
| Some exn_class_name ->
let exn_type =
@ -132,8 +132,8 @@ let translate_exceptions (context : JContext.t) exit_nodes get_body_nodes handle
in
create_node loc node_kind_false instrs_false
in
Procdesc.node_set_succs_exn procdesc node_true catch_nodes exit_nodes ;
Procdesc.node_set_succs_exn procdesc node_false succ_nodes exit_nodes ;
Procdesc.node_set_succs procdesc node_true ~normal:catch_nodes ~exn:exit_nodes ;
Procdesc.node_set_succs procdesc node_false ~normal:succ_nodes ~exn:exit_nodes ;
[node_true; node_false]
in
let is_last_handler = ref true in
@ -155,7 +155,7 @@ let translate_exceptions (context : JContext.t) exit_nodes get_body_nodes handle
Location.none context.source_file
in
let entry_node = create_entry_node loc in
Procdesc.node_set_succs_exn procdesc entry_node nodes_first_handler exit_nodes ;
Procdesc.node_set_succs procdesc entry_node ~normal:nodes_first_handler ~exn:exit_nodes ;
Hashtbl.add catch_block_table handler_list [entry_node]
in
Hashtbl.iter (fun _ handler_list -> create_entry_block handler_list) handler_table ;

@ -66,7 +66,9 @@ let procedure proc_name (make_body : node_generator) : Procdesc.t =
Procdesc.create_node proc_desc (sourcefile_location ()) kind instrs
in
let exit_node = create_node Procdesc.Node.Exit_node [] in
let set_succs node succs = Procdesc.node_set_succs_exn proc_desc node succs [exit_node] in
let set_succs node succs =
Procdesc.node_set_succs proc_desc node ~normal:succs ~exn:[exit_node]
in
let {start_node= body_start; exit_node= body_exit} = make_body create_node set_succs in
let start_node = create_node Procdesc.Node.Start_node [] in
set_succs start_node [body_start] ;

@ -166,7 +166,7 @@ struct
in
let create_node kind cmds = Procdesc.create_node pdesc dummy_loc kind cmds in
let set_succs cur_node succs ~exn_handlers =
Procdesc.node_set_succs_exn pdesc cur_node succs exn_handlers
Procdesc.node_set_succs pdesc cur_node ~normal:succs ~exn:exn_handlers
in
let mk_prune_nodes_for_cond cond_exp if_kind =
let mk_prune_node cond_exp if_kind true_branch =

@ -37,9 +37,9 @@ let tests =
Procdesc.set_start_node test_pdesc n1 ;
(* let -> represent normal transitions and -*-> represent exceptional transitions *)
(* creating graph n1 -> n2, n1 -*-> n3, n2 -> n4, n2 -*-> n3, n3 -> n4 , n3 -*> n4 *)
Procdesc.node_set_succs_exn test_pdesc n1 [n2] [n3] ;
Procdesc.node_set_succs_exn test_pdesc n2 [n4] [n3] ;
Procdesc.node_set_succs_exn test_pdesc n3 [n4] [n4] ;
Procdesc.node_set_succs test_pdesc n1 ~normal:[n2] ~exn:[n3] ;
Procdesc.node_set_succs test_pdesc n2 ~normal:[n4] ~exn:[n3] ;
Procdesc.node_set_succs test_pdesc n3 ~normal:[n4] ~exn:[n4] ;
let normal_proc_cfg = ProcCfg.Normal.from_pdesc test_pdesc in
let exceptional_proc_cfg = ProcCfg.Exceptional.from_pdesc test_pdesc in
let backward_proc_cfg = BackwardCfg.from_pdesc test_pdesc in

@ -5,7 +5,7 @@ digraph cfg {
"dereference_ifthenelse.aa3447116ff03cffc729c06c91821cdc_1" -> "dereference_ifthenelse.aa3447116ff03cffc729c06c91821cdc_17" ;
"dereference_ifthenelse.aa3447116ff03cffc729c06c91821cdc_1" -> "dereference_ifthenelse.aa3447116ff03cffc729c06c91821cdc_18" ;
"dereference_ifthenelse.aa3447116ff03cffc729c06c91821cdc_2" [label="2: Exit dereference_ifthenelse \n EXIT_SCOPE(n$3); [line 15, column 1]\n " color=yellow style=filled]
"dereference_ifthenelse.aa3447116ff03cffc729c06c91821cdc_2" [label="2: Exit dereference_ifthenelse \n " color=yellow style=filled]
"dereference_ifthenelse.aa3447116ff03cffc729c06c91821cdc_3" [label="3: + \n " ]

@ -7,7 +7,7 @@ digraph cfg {
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_2" [label="2: Exit FN_deref_null_after_catch_bad \n NULLIFY(&0$?%__sil_tmpSIL_materialize_temp__n$2); [line 53, column 1]\n NULLIFY(&0$?%__sil_tmp__temp_construct_n$6); [line 53, column 1]\n " color=yellow style=filled]
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" [label="3: Return Stmt \n n$0=*&i:int* [line 52, column 11]\n n$1=*n$0:int [line 52, column 10]\n *&return:int=n$1 [line 52, column 3]\n NULLIFY(&i); [line 52, column 3]\n EXIT_SCOPE(n$0,n$1,0$?%__sil_tmpSIL_materialize_temp__n$2,i); [line 52, column 3]\n APPLY_ABSTRACTION; [line 52, column 3]\n " shape="box"]
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" [label="3: Return Stmt \n n$0=*&i:int* [line 52, column 11]\n n$1=*n$0:int [line 52, column 10]\n *&return:int=n$1 [line 52, column 3]\n NULLIFY(&i); [line 52, column 3]\n EXIT_SCOPE(n$0,n$1,i); [line 52, column 3]\n APPLY_ABSTRACTION; [line 52, column 3]\n " shape="box"]
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_2" ;
@ -35,11 +35,11 @@ digraph cfg {
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_2" [label="2: Exit FN_deref_null_in_catch_bad \n NULLIFY(&0$?%__sil_tmpSIL_materialize_temp__n$0); [line 43, column 1]\n NULLIFY(&0$?%__sil_tmp__temp_construct_n$4); [line 43, column 1]\n " color=yellow style=filled]
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_3" [label="3: Return Stmt \n *&return:int=0 [line 42, column 3]\n NULLIFY(&i); [line 42, column 3]\n EXIT_SCOPE(i,0$?%__sil_tmpSIL_materialize_temp__n$0); [line 42, column 3]\n APPLY_ABSTRACTION; [line 42, column 3]\n " shape="box"]
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_3" [label="3: Return Stmt \n *&return:int=0 [line 42, column 3]\n NULLIFY(&i); [line 42, column 3]\n EXIT_SCOPE(i); [line 42, column 3]\n APPLY_ABSTRACTION; [line 42, column 3]\n " shape="box"]
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_3" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_2" ;
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_4" [label="4: Destruction(temporaries cleanup) \n _=*&0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const [line 38, column 37]\n n$2=_fun_std::runtime_error::~runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const *) injected virtual [line 38, column 37]\n EXIT_SCOPE(_,n$2,0$?%__sil_tmpSIL_materialize_temp__n$0); [line 38, column 37]\n APPLY_ABSTRACTION; [line 38, column 37]\n " shape="box"]
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_4" [label="4: Destruction(temporaries cleanup) \n _=*&0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const [line 38, column 37]\n n$2=_fun_std::runtime_error::~runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const *) injected virtual [line 38, column 37]\n EXIT_SCOPE(_,n$2,0$?%__sil_tmpSIL_materialize_temp__n$0); [line 38, column 37]\n " shape="box"]
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_4" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_3" ;
@ -67,7 +67,7 @@ digraph cfg {
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_3" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_2" ;
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" [label="4: + \n EXIT_SCOPE(0$?%__sil_tmpSIL_materialize_temp__n$9,0$?%__sil_tmpSIL_materialize_temp__n$1); [line 59, column 5]\n " ]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" [label="4: + \n " ]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_3" ;
@ -118,7 +118,7 @@ digraph cfg {
"basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_1" -> "basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_4" ;
"basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_2" [label="2: Exit basic_throw_ok \n EXIT_SCOPE(0$?%__sil_tmpSIL_materialize_temp__n$0); [line 27, column 64]\n NULLIFY(&0$?%__sil_tmpSIL_materialize_temp__n$0); [line 27, column 64]\n NULLIFY(&0$?%__sil_tmp__temp_construct_n$4); [line 27, column 64]\n " color=yellow style=filled]
"basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_2" [label="2: Exit basic_throw_ok \n NULLIFY(&0$?%__sil_tmpSIL_materialize_temp__n$0); [line 27, column 64]\n NULLIFY(&0$?%__sil_tmp__temp_construct_n$4); [line 27, column 64]\n " color=yellow style=filled]
"basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_3" [label="3: Destruction(temporaries cleanup) \n _=*&0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const [line 27, column 61]\n n$2=_fun_std::runtime_error::~runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const *) injected virtual [line 27, column 61]\n EXIT_SCOPE(_,n$2,0$?%__sil_tmpSIL_materialize_temp__n$0); [line 27, column 61]\n APPLY_ABSTRACTION; [line 27, column 61]\n " shape="box"]
@ -147,11 +147,11 @@ digraph cfg {
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_2" [label="2: Exit dead_deref_null_after_throw_ok \n NULLIFY(&0$?%__sil_tmpSIL_materialize_temp__n$2); [line 33, column 1]\n NULLIFY(&0$?%__sil_tmp__temp_construct_n$6); [line 33, column 1]\n " color=yellow style=filled]
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_3" [label="3: Return Stmt \n n$0=*&i:int* [line 32, column 11]\n n$1=*n$0:int [line 32, column 10]\n *&return:int=n$1 [line 32, column 3]\n NULLIFY(&i); [line 32, column 3]\n EXIT_SCOPE(n$0,n$1,0$?%__sil_tmpSIL_materialize_temp__n$2,i); [line 32, column 3]\n APPLY_ABSTRACTION; [line 32, column 3]\n " shape="box"]
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_3" [label="3: Return Stmt \n n$0=*&i:int* [line 32, column 11]\n n$1=*n$0:int [line 32, column 10]\n *&return:int=n$1 [line 32, column 3]\n NULLIFY(&i); [line 32, column 3]\n EXIT_SCOPE(n$0,n$1,i); [line 32, column 3]\n APPLY_ABSTRACTION; [line 32, column 3]\n " shape="box"]
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_3" -> "dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_2" ;
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_4" [label="4: Destruction(temporaries cleanup) \n _=*&0$?%__sil_tmpSIL_materialize_temp__n$2:std::runtime_error const [line 31, column 39]\n n$4=_fun_std::runtime_error::~runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$2:std::runtime_error const *) injected virtual [line 31, column 39]\n EXIT_SCOPE(_,n$4,0$?%__sil_tmpSIL_materialize_temp__n$2); [line 31, column 39]\n APPLY_ABSTRACTION; [line 31, column 39]\n " shape="box"]
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_4" [label="4: Destruction(temporaries cleanup) \n _=*&0$?%__sil_tmpSIL_materialize_temp__n$2:std::runtime_error const [line 31, column 39]\n n$4=_fun_std::runtime_error::~runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$2:std::runtime_error const *) injected virtual [line 31, column 39]\n EXIT_SCOPE(_,n$4,0$?%__sil_tmpSIL_materialize_temp__n$2); [line 31, column 39]\n " shape="box"]
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_4" -> "dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_3" ;

@ -22,11 +22,11 @@ digraph cfg {
"capture_by_ref#4375601249296069049.1d794578c048d96b25fb1e90dbaa8225_2" [label="2: Exit capture_by_ref \n NULLIFY(&0$?%__sil_tmpSIL_materialize_temp__n$1); [line 38, column 1]\n " color=yellow style=filled]
"capture_by_ref#4375601249296069049.1d794578c048d96b25fb1e90dbaa8225_3" [label="3: Return Stmt \n n$0=*&x:int [line 37, column 10]\n *&return:int=n$0 [line 37, column 3]\n NULLIFY(&x); [line 37, column 3]\n EXIT_SCOPE(n$0,x,0$?%__sil_tmpSIL_materialize_temp__n$1); [line 37, column 3]\n APPLY_ABSTRACTION; [line 37, column 3]\n " shape="box"]
"capture_by_ref#4375601249296069049.1d794578c048d96b25fb1e90dbaa8225_3" [label="3: Return Stmt \n n$0=*&x:int [line 37, column 10]\n *&return:int=n$0 [line 37, column 3]\n NULLIFY(&x); [line 37, column 3]\n EXIT_SCOPE(n$0,x); [line 37, column 3]\n APPLY_ABSTRACTION; [line 37, column 3]\n " shape="box"]
"capture_by_ref#4375601249296069049.1d794578c048d96b25fb1e90dbaa8225_3" -> "capture_by_ref#4375601249296069049.1d794578c048d96b25fb1e90dbaa8225_2" ;
"capture_by_ref#4375601249296069049.1d794578c048d96b25fb1e90dbaa8225_4" [label="4: Destruction(temporaries cleanup) \n _=*&0$?%__sil_tmpSIL_materialize_temp__n$1:capture_by_ref::lambda_shared_lambda_lambda1.cpp:36:3 [line 36, column 19]\n n$3=_fun_capture_by_ref::lambda_shared_lambda_lambda1.cpp:36:3::~(&0$?%__sil_tmpSIL_materialize_temp__n$1:capture_by_ref::lambda_shared_lambda_lambda1.cpp:36:3*) injected [line 36, column 19]\n EXIT_SCOPE(_,n$3,0$?%__sil_tmpSIL_materialize_temp__n$1); [line 36, column 19]\n APPLY_ABSTRACTION; [line 36, column 19]\n " shape="box"]
"capture_by_ref#4375601249296069049.1d794578c048d96b25fb1e90dbaa8225_4" [label="4: Destruction(temporaries cleanup) \n _=*&0$?%__sil_tmpSIL_materialize_temp__n$1:capture_by_ref::lambda_shared_lambda_lambda1.cpp:36:3 [line 36, column 19]\n n$3=_fun_capture_by_ref::lambda_shared_lambda_lambda1.cpp:36:3::~(&0$?%__sil_tmpSIL_materialize_temp__n$1:capture_by_ref::lambda_shared_lambda_lambda1.cpp:36:3*) injected [line 36, column 19]\n EXIT_SCOPE(_,n$3,0$?%__sil_tmpSIL_materialize_temp__n$1); [line 36, column 19]\n " shape="box"]
"capture_by_ref#4375601249296069049.1d794578c048d96b25fb1e90dbaa8225_4" -> "capture_by_ref#4375601249296069049.1d794578c048d96b25fb1e90dbaa8225_3" ;

@ -56,11 +56,11 @@ digraph cfg {
"get_field_div0#return_struct#5765383981880135147.23dc82d8c29aaec22d9b9a68808820c3_2" [label="2: Exit return_struct::get_field_div0 \n NULLIFY(&0$?%__sil_tmpSIL_materialize_temp__n$7); [line 33, column 1]\n NULLIFY(&0$?%__sil_tmpSIL_materialize_temp__n$0); [line 33, column 1]\n " color=yellow style=filled]
"get_field_div0#return_struct#5765383981880135147.23dc82d8c29aaec22d9b9a68808820c3_3" [label="3: Return Stmt \n VARIABLE_DECLARED(0$?%__sil_tmpSIL_materialize_temp__n$0:return_struct::X); [line 32, column 14]\n n$5=_fun_return_struct::get(0:int,&0$?%__sil_tmpSIL_materialize_temp__n$0:return_struct::X*) assign_last [line 32, column 14]\n n$6=*&0$?%__sil_tmpSIL_materialize_temp__n$0.f:int [line 32, column 14]\n _=*&0$?%__sil_tmpSIL_materialize_temp__n$0:return_struct::X [line 32, column 21]\n n$2=_fun_return_struct::X::~X(&0$?%__sil_tmpSIL_materialize_temp__n$0:return_struct::X*) injected [line 32, column 21]\n *&return:int=(1 / n$6) [line 32, column 3]\n EXIT_SCOPE(_,n$2,n$5,n$6,0$?%__sil_tmpSIL_materialize_temp__n$0,0$?%__sil_tmpSIL_materialize_temp__n$7); [line 32, column 3]\n APPLY_ABSTRACTION; [line 32, column 3]\n " shape="box"]
"get_field_div0#return_struct#5765383981880135147.23dc82d8c29aaec22d9b9a68808820c3_3" [label="3: Return Stmt \n VARIABLE_DECLARED(0$?%__sil_tmpSIL_materialize_temp__n$0:return_struct::X); [line 32, column 14]\n n$5=_fun_return_struct::get(0:int,&0$?%__sil_tmpSIL_materialize_temp__n$0:return_struct::X*) assign_last [line 32, column 14]\n n$6=*&0$?%__sil_tmpSIL_materialize_temp__n$0.f:int [line 32, column 14]\n _=*&0$?%__sil_tmpSIL_materialize_temp__n$0:return_struct::X [line 32, column 21]\n n$2=_fun_return_struct::X::~X(&0$?%__sil_tmpSIL_materialize_temp__n$0:return_struct::X*) injected [line 32, column 21]\n *&return:int=(1 / n$6) [line 32, column 3]\n EXIT_SCOPE(_,n$2,n$5,n$6,0$?%__sil_tmpSIL_materialize_temp__n$0); [line 32, column 3]\n APPLY_ABSTRACTION; [line 32, column 3]\n " shape="box"]
"get_field_div0#return_struct#5765383981880135147.23dc82d8c29aaec22d9b9a68808820c3_3" -> "get_field_div0#return_struct#5765383981880135147.23dc82d8c29aaec22d9b9a68808820c3_2" ;
"get_field_div0#return_struct#5765383981880135147.23dc82d8c29aaec22d9b9a68808820c3_4" [label="4: Destruction(temporaries cleanup) \n _=*&0$?%__sil_tmpSIL_materialize_temp__n$7:return_struct::X [line 31, column 15]\n n$9=_fun_return_struct::X::~X(&0$?%__sil_tmpSIL_materialize_temp__n$7:return_struct::X*) injected [line 31, column 15]\n EXIT_SCOPE(_,n$9,0$?%__sil_tmpSIL_materialize_temp__n$7); [line 31, column 15]\n APPLY_ABSTRACTION; [line 31, column 15]\n " shape="box"]
"get_field_div0#return_struct#5765383981880135147.23dc82d8c29aaec22d9b9a68808820c3_4" [label="4: Destruction(temporaries cleanup) \n _=*&0$?%__sil_tmpSIL_materialize_temp__n$7:return_struct::X [line 31, column 15]\n n$9=_fun_return_struct::X::~X(&0$?%__sil_tmpSIL_materialize_temp__n$7:return_struct::X*) injected [line 31, column 15]\n EXIT_SCOPE(_,n$9,0$?%__sil_tmpSIL_materialize_temp__n$7); [line 31, column 15]\n " shape="box"]
"get_field_div0#return_struct#5765383981880135147.23dc82d8c29aaec22d9b9a68808820c3_4" -> "get_field_div0#return_struct#5765383981880135147.23dc82d8c29aaec22d9b9a68808820c3_3" ;

Loading…
Cancel
Save