From d9021b9517bd7f54e77b7ef214bc6a34ee95251e Mon Sep 17 00:00:00 2001 From: Sungkeun Cho Date: Fri, 12 Mar 2021 05:41:53 -0800 Subject: [PATCH] [frontend] Add try_entry, try_exit statements for C++ try-catch blocks Summary: This diff adds TryEntry and TryExit statements to the entry and exit of C++ `try` block, in order to handle exceptional control flow better in analyses. Reviewed By: da319, jvillard Differential Revision: D26946188 fbshipit-source-id: 33f4ae9e7 --- infer/src/IR/Procdesc.ml | 3 + infer/src/IR/Procdesc.mli | 1 + infer/src/IR/Sil.ml | 15 ++- infer/src/IR/Sil.mli | 2 + .../backend/ClosureSubstSpecializedMethod.ml | 2 +- infer/src/backend/preanal.ml | 3 +- infer/src/biabduction/Predicates.ml | 2 +- infer/src/biabduction/SymExec.ml | 2 +- .../bufferoverrun/bufferOverrunAnalysis.ml | 3 +- infer/src/clang/cTrans.ml | 30 ++++- infer/src/cost/cost.ml | 9 +- infer/src/nullsafe/typeCheck.ml | 3 +- infer/src/pulse/Pulse.ml | 3 +- .../cpp/liveness/dead_stores.cpp | 2 +- .../codetoanalyze/cpp/liveness/issues.exp | 1 - .../cpp/shared/exceptions/Exceptions.cpp.dot | 111 ++++++++++++------ 16 files changed, 139 insertions(+), 53 deletions(-) diff --git a/infer/src/IR/Procdesc.ml b/infer/src/IR/Procdesc.ml index d7bd8c4e4..7b975cc51 100644 --- a/infer/src/IR/Procdesc.ml +++ b/infer/src/IR/Procdesc.ml @@ -71,6 +71,7 @@ module Node = struct | CXXNewExpr | CXXStdInitializerListExpr | CXXTemporaryMarkerSet + | CXXTry | CXXTypeidExpr | DeclStmt | DefineBody @@ -320,6 +321,8 @@ module Node = struct F.pp_print_string fmt "CXXStdInitializerListExpr" | CXXTemporaryMarkerSet -> F.pp_print_string fmt "CXXTemporaryMarkerSet" + | CXXTry -> + F.pp_print_string fmt "CXXTry" | CXXTypeidExpr -> F.pp_print_string fmt "CXXTypeidExpr" | DeclStmt -> diff --git a/infer/src/IR/Procdesc.mli b/infer/src/IR/Procdesc.mli index 0d4590b16..edf6e2ac3 100644 --- a/infer/src/IR/Procdesc.mli +++ b/infer/src/IR/Procdesc.mli @@ -52,6 +52,7 @@ module Node : sig | CXXNewExpr | CXXStdInitializerListExpr | CXXTemporaryMarkerSet + | CXXTry | CXXTypeidExpr | DeclStmt | DefineBody diff --git a/infer/src/IR/Sil.ml b/infer/src/IR/Sil.ml index 116fed58f..a847b089e 100644 --- a/infer/src/IR/Sil.ml +++ b/infer/src/IR/Sil.ml @@ -31,6 +31,8 @@ type instr_metadata = | ExitScope of Var.t list * Location.t (** remove temporaries and dead program variables *) | Nullify of Pvar.t * Location.t (** nullify stack variable *) | Skip (** no-op *) + | TryEntry of {try_id: int; loc: Location.t} (** entry of C++ try block *) + | TryExit of {try_id: int; loc: Location.t} (** exit of C++ try block *) | VariableLifetimeBegins of Pvar.t * Typ.t * Location.t (** stack variable declared *) [@@deriving compare] @@ -91,7 +93,12 @@ let color_wrapper ~f = if Config.print_using_diff then Pp.color_wrapper ~f else let pp_exp_typ pe f (e, t) = F.fprintf f "%a:%a" (Exp.pp_diff pe) e (Typ.pp pe) t let location_of_instr_metadata = function - | Abstract loc | ExitScope (_, loc) | Nullify (_, loc) | VariableLifetimeBegins (_, _, loc) -> + | Abstract loc + | ExitScope (_, loc) + | Nullify (_, loc) + | TryEntry {loc} + | TryExit {loc} + | VariableLifetimeBegins (_, _, loc) -> loc | Skip -> Location.dummy @@ -112,7 +119,7 @@ let exps_of_instr_metadata = function List.map ~f:Var.to_exp vars | Nullify (pvar, _) -> [Exp.Lvar pvar] - | Skip -> + | Skip | TryEntry _ | TryExit _ -> [] | VariableLifetimeBegins (pvar, _, _) -> [Exp.Lvar pvar] @@ -160,6 +167,10 @@ let pp_instr_metadata pe f = function F.fprintf f "NULLIFY(%a); [%a]" (Pvar.pp pe) pvar Location.pp loc | Skip -> F.pp_print_string f "SKIP" + | TryEntry {loc} -> + F.fprintf f "TRY_ENTRY; [%a]" Location.pp loc + | TryExit {loc} -> + F.fprintf f "TRY_EXIT; [%a]" Location.pp loc | VariableLifetimeBegins (pvar, typ, loc) -> F.fprintf f "VARIABLE_DECLARED(%a:%a); [%a]" Pvar.pp_value pvar (Typ.pp_full pe) typ Location.pp loc diff --git a/infer/src/IR/Sil.mli b/infer/src/IR/Sil.mli index 4221d5d27..f88ab89e5 100644 --- a/infer/src/IR/Sil.mli +++ b/infer/src/IR/Sil.mli @@ -30,6 +30,8 @@ type instr_metadata = | ExitScope of Var.t list * Location.t (** remove temporaries and dead program variables *) | Nullify of Pvar.t * Location.t (** nullify stack variable *) | Skip (** no-op *) + | TryEntry of {try_id: int; loc: Location.t} (** entry of C++ try block *) + | TryExit of {try_id: int; loc: Location.t} (** exit of C++ try block *) | VariableLifetimeBegins of Pvar.t * Typ.t * Location.t (** stack variable declared *) [@@deriving compare] diff --git a/infer/src/backend/ClosureSubstSpecializedMethod.ml b/infer/src/backend/ClosureSubstSpecializedMethod.ml index 14d948ede..2f4c5fc29 100644 --- a/infer/src/backend/ClosureSubstSpecializedMethod.ml +++ b/infer/src/backend/ClosureSubstSpecializedMethod.ml @@ -124,7 +124,7 @@ let rec exec_exp pname e = let exec_metadata pname metadata = let open Sil in match metadata with - | Abstract _ | Skip -> + | Abstract _ | Skip | TryEntry _ | TryExit _ -> metadata | ExitScope (vars, loc) -> let updated = ref false in diff --git a/infer/src/backend/preanal.ml b/infer/src/backend/preanal.ml index a0cb84077..cfb330d8b 100644 --- a/infer/src/backend/preanal.ml +++ b/infer/src/backend/preanal.ml @@ -347,7 +347,8 @@ module Liveness = struct (VarDomain.add (Var.of_pvar lhs_pvar) active_defs, to_nullify) | Sil.Metadata (VariableLifetimeBegins (pvar, _, _)) -> (VarDomain.add (Var.of_pvar pvar) active_defs, to_nullify) - | Sil.Store _ | Prune _ | Metadata (Abstract _ | ExitScope _ | Skip) -> + | Sil.Store _ | Prune _ | Metadata (Abstract _ | ExitScope _ | Skip | TryEntry _ | TryExit _) + -> astate | Sil.Metadata (Nullify _) -> L.(die InternalError) diff --git a/infer/src/biabduction/Predicates.ml b/infer/src/biabduction/Predicates.ml index 4807dea44..0055a3efe 100644 --- a/infer/src/biabduction/Predicates.ml +++ b/infer/src/biabduction/Predicates.ml @@ -1015,7 +1015,7 @@ let instr_sub_ids ~sub_id_binders f (instr : Sil.instr) : Sil.instr = in let vars' = IList.map_changed ~equal:phys_equal ~f:sub_var vars in if phys_equal vars vars' then instr else Metadata (ExitScope (vars', loc)) - | Metadata (Abstract _ | Nullify _ | Skip | VariableLifetimeBegins _) -> + | Metadata (Abstract _ | Nullify _ | Skip | TryEntry _ | TryExit _ | VariableLifetimeBegins _) -> instr diff --git a/infer/src/biabduction/SymExec.ml b/infer/src/biabduction/SymExec.ml index 382b8fe31..5841d6fd4 100644 --- a/infer/src/biabduction/SymExec.ml +++ b/infer/src/biabduction/SymExec.ml @@ -1348,7 +1348,7 @@ let rec sym_exec | Sil.Metadata (ExitScope (dead_vars, _)) -> let dead_ids = List.filter_map dead_vars ~f:Var.get_ident in ret_old_path [Prop.exist_quantify tenv dead_ids prop_] - | Sil.Metadata (Skip | VariableLifetimeBegins _) -> + | Sil.Metadata (Skip | TryEntry _ | TryExit _ | VariableLifetimeBegins _) -> ret_old_path [prop_] diff --git a/infer/src/bufferoverrun/bufferOverrunAnalysis.ml b/infer/src/bufferoverrun/bufferOverrunAnalysis.ml index 0940b45a9..583036c2c 100644 --- a/infer/src/bufferoverrun/bufferOverrunAnalysis.ml +++ b/infer/src/bufferoverrun/bufferOverrunAnalysis.ml @@ -434,7 +434,8 @@ module TransferFunctions = struct mem | Metadata (ExitScope (dead_vars, _)) -> Dom.Mem.remove_temps (List.filter_map dead_vars ~f:Var.get_ident) mem - | Metadata (Abstract _ | Nullify _ | Skip | VariableLifetimeBegins _) -> + | Metadata (Abstract _ | Nullify _ | Skip | TryEntry _ | TryExit _ | VariableLifetimeBegins _) + -> mem diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 74f8ae370..ed38d43cf 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -2149,7 +2149,8 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s instruction trans_state' stmt - and tryStmt_trans trans_state stmts = + and tryStmt_trans ({context= {procdesc; translation_unit_context= {source_file}}} as trans_state) + ({Clang_ast_t.si_pointer= try_id; si_source_range} as stmt_info) stmts = let open Clang_ast_t in let translate_catch catch_root_nodes_acc = function | CXXCatchStmt (_, catch_body_stmts, _) -> @@ -2162,8 +2163,25 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s in match stmts with | try_body_stmt :: catch_stmts -> - let try_trans_result = instruction trans_state try_body_stmt in + let try_loc = + CLocation.location_of_source_range ~pick_location:`Start source_file si_source_range + in + let try_trans_result = + PriorityNode.force_sequential try_loc CXXTry trans_state stmt_info + ~mk_first_opt:(fun _ _ -> + Some + (mk_trans_result (mk_fresh_void_exp_typ ()) + {empty_control with instrs= [Metadata (TryEntry {try_id; loc= try_loc})]}) ) + ~mk_second:(fun _ _ -> instruction trans_state try_body_stmt) + ~mk_return:(fun ~fst:_ ~snd -> snd.return) + in let catch_start_nodes = List.fold catch_stmts ~f:translate_catch ~init:[] in + let try_exit_node = + Procdesc.create_node procdesc try_loc (Stmt_node CXXTry) + [Metadata (TryExit {try_id; loc= try_loc})] + in + Procdesc.set_succs try_exit_node ~normal:(Some trans_state.succ_nodes) + ~exn:(Some catch_start_nodes) ; (* add catch block as exceptional successor to end of try block. not ideal, but we will at least reach the code in the catch block this way *) (* TODO (T28898377): instead, we should extend trans_state with a list of maybe-throwing @@ -2182,9 +2200,9 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s | Stmt_node ReturnStmt -> () | _ -> - Procdesc.set_succs try_end ~normal:None ~exn:(Some catch_start_nodes) ) + Procdesc.set_succs try_end ~normal:(Some [try_exit_node]) ~exn:None ) try_ends ; - try_trans_result + {try_trans_result with control= {try_control with leaf_nodes= [try_exit_node]}} | _ -> (* try should always have a catch statement *) assert false @@ -4446,8 +4464,8 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s objCAutoreleasePoolStmt_trans trans_state stmt_info stmts | ObjCAtTryStmt (_, stmts) -> compoundStmt_trans trans_state stmts - | CXXTryStmt (_, try_stmts) -> - tryStmt_trans trans_state try_stmts + | CXXTryStmt (stmt_info, try_stmts) -> + tryStmt_trans trans_state stmt_info try_stmts | CXXCatchStmt _ -> (* should by handled by try statement *) assert false diff --git a/infer/src/cost/cost.ml b/infer/src/cost/cost.ml index 8407b6c5b..26afb66ce 100644 --- a/infer/src/cost/cost.ml +++ b/infer/src/cost/cost.ml @@ -214,7 +214,14 @@ module InstrBasicCostWithReason = struct CostDomain.zero_record | Sil.Load _ | Sil.Store _ | Sil.Prune _ -> CostDomain.unit_cost_atomic_operation - | Sil.Metadata (Abstract _ | ExitScope _ | Nullify _ | Skip | VariableLifetimeBegins _) -> + | Sil.Metadata + ( Abstract _ + | ExitScope _ + | Nullify _ + | Skip + | TryEntry _ + | TryExit _ + | VariableLifetimeBegins _ ) -> CostDomain.zero_record diff --git a/infer/src/nullsafe/typeCheck.ml b/infer/src/nullsafe/typeCheck.ml index 152bd50d8..b129aaa44 100644 --- a/infer/src/nullsafe/typeCheck.ml +++ b/infer/src/nullsafe/typeCheck.ml @@ -1220,7 +1220,8 @@ let typecheck_instr ({IntraproceduralAnalysis.proc_desc= curr_pdesc; tenv; _} as TypeState.remove_id id astate ~descr:"ExitScope" | Var.ProgramVar _ -> astate ) - | Sil.Metadata (Abstract _ | Nullify _ | Skip | VariableLifetimeBegins _) -> + | Sil.Metadata (Abstract _ | Nullify _ | Skip | TryEntry _ | TryExit _ | VariableLifetimeBegins _) + -> typestate | Sil.Load {id; e; typ; loc} -> typecheck_expr_for_errors analysis_data ~nullsafe_mode find_canonical_duplicate calls_this diff --git a/infer/src/pulse/Pulse.ml b/infer/src/pulse/Pulse.ml index fbcda66b1..365ddd5b7 100644 --- a/infer/src/pulse/Pulse.ml +++ b/infer/src/pulse/Pulse.ml @@ -367,7 +367,8 @@ module PulseTransferFunctions = struct remove_vars vars_to_remove astates | Metadata (VariableLifetimeBegins (pvar, typ, location)) when not (Pvar.is_global pvar) -> [PulseOperations.realloc_pvar tenv pvar typ location astate |> Domain.continue] - | Metadata (Abstract _ | VariableLifetimeBegins _ | Nullify _ | Skip) -> + | Metadata (Abstract _ | VariableLifetimeBegins _ | Nullify _ | Skip | TryEntry _ | TryExit _) + -> [ContinueProgram astate] ) diff --git a/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp b/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp index e394bc1d1..95aca7c6d 100644 --- a/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp +++ b/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp @@ -403,7 +403,7 @@ class Exceptions { return 0; } - int unreachable_catch_bad() { + int FN_unreachable_catch_bad() { int i = 1; try { } catch (...) { diff --git a/infer/tests/codetoanalyze/cpp/liveness/issues.exp b/infer/tests/codetoanalyze/cpp/liveness/issues.exp index 27ba2fdd9..692931a64 100644 --- a/infer/tests/codetoanalyze/cpp/liveness/issues.exp +++ b/infer/tests/codetoanalyze/cpp/liveness/issues.exp @@ -1,6 +1,5 @@ codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::Exceptions::FP_read_in_catch_tricky_ok, 1, DEAD_STORE, no_bucket, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::Exceptions::dead_in_catch_bad, 4, DEAD_STORE, no_bucket, ERROR, [Write of unused value] -codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::Exceptions::unreachable_catch_bad, 1, DEAD_STORE, no_bucket, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::FP_assign_array_tricky2_ok, 3, DEAD_STORE, no_bucket, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::binaryConditional_bad, 1, DEAD_STORE, no_bucket, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::binaryConditional_bad, 4, DEAD_STORE, no_bucket, ERROR, [Write of unused value] diff --git a/infer/tests/codetoanalyze/cpp/shared/exceptions/Exceptions.cpp.dot b/infer/tests/codetoanalyze/cpp/shared/exceptions/Exceptions.cpp.dot index ba1a0095e..44bf541fa 100644 --- a/infer/tests/codetoanalyze/cpp/shared/exceptions/Exceptions.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/shared/exceptions/Exceptions.cpp.dot @@ -3,7 +3,7 @@ digraph cfg { "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_1" [label="1: Start FN_deref_null_after_catch_bad\nFormals: i:int*\nLocals: 0$?%__sil_tmp__temp_construct_n$3:std::runtime_error 0$?%__sil_tmpSIL_materialize_temp__n$2:std::runtime_error const \n " color=yellow style=filled] - "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_1" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_7" ; + "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_1" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_8" ; "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_2" [label="2: Exit FN_deref_null_after_catch_bad \n " color=yellow style=filled] @@ -22,20 +22,28 @@ digraph cfg { "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_6" [label="6: Destruction(temporaries cleanup) \n n$5=_fun_std::runtime_error::runtime_error(&0$?%__sil_tmp__temp_construct_n$3:std::runtime_error*,&0$?%__sil_tmpSIL_materialize_temp__n$2:std::runtime_error const &) [line 48, column 11]\n n$6=_fun___infer_objc_cpp_throw(&0$?%__sil_tmp__temp_construct_n$3:std::runtime_error) [line 48, column 5]\n _=*&0$?%__sil_tmpSIL_materialize_temp__n$2:std::runtime_error const [line 48, column 37]\n n$8=_fun_std::runtime_error::~runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$2:std::runtime_error const *) injected virtual [line 48, column 37]\n " shape="box"] - "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_6" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" ; - "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_6" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_8" [color="red" ]; + "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_6" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_10" ; "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_7" [label="7: BinaryOperatorStmt: Assign \n n$9=*&i:int* [line 47, column 6]\n *n$9:int=2 [line 47, column 5]\n " shape="box"] "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_7" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_5" ; -"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_8" [label="8: BinaryOperatorStmt: Assign \n *&i:int*=null [line 50, column 5]\n " shape="box"] +"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_8" [label="8: CXXTry \n TRY_ENTRY; [line 46, column 3]\n " shape="box"] - "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_8" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" ; + "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_8" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_7" ; +"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_9" [label="9: BinaryOperatorStmt: Assign \n *&i:int*=null [line 50, column 5]\n " shape="box"] + + + "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_9" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" ; +"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_10" [label="10: CXXTry \n TRY_EXIT; [line 46, column 3]\n " shape="box"] + + + "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_10" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" ; + "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_10" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_9" [color="red" ]; "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_1" [label="1: Start FN_deref_null_in_catch_bad\nFormals: \nLocals: 0$?%__sil_tmp__temp_construct_n$1:std::runtime_error 0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const i:int* \n " color=yellow style=filled] - "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_1" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_8" ; + "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_1" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_10" ; "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_2" [label="2: Exit FN_deref_null_in_catch_bad \n " color=yellow style=filled] @@ -50,24 +58,32 @@ digraph cfg { "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_5" [label="5: Destruction(temporaries cleanup) \n n$3=_fun_std::runtime_error::runtime_error(&0$?%__sil_tmp__temp_construct_n$1:std::runtime_error*,&0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const &) [line 38, column 11]\n n$4=_fun___infer_objc_cpp_throw(&0$?%__sil_tmp__temp_construct_n$1:std::runtime_error) [line 38, column 5]\n _=*&0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const [line 38, column 37]\n n$6=_fun_std::runtime_error::~runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const *) injected virtual [line 38, column 37]\n " shape="box"] - "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_5" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_3" ; - "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_5" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_6" [color="red" ]; -"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_6" [label="6: Return Stmt \n n$7=*&i:int* [line 40, column 13]\n n$8=*n$7:int [line 40, column 12]\n " shape="box"] + "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_5" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_9" ; +"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_6" [label="6: CXXTry \n TRY_ENTRY; [line 37, column 3]\n " shape="box"] + + + "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_6" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_4" ; +"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_7" [label="7: Return Stmt \n n$8=*&i:int* [line 40, column 13]\n n$9=*n$8:int [line 40, column 12]\n " shape="box"] + + + "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_7" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_8" ; +"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_8" [label="8: Return Stmt \n *&return:int=n$9 [line 40, column 5]\n " shape="box"] - "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_6" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_7" ; -"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_7" [label="7: Return Stmt \n *&return:int=n$8 [line 40, column 5]\n " shape="box"] + "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_8" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_2" ; +"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_9" [label="9: CXXTry \n TRY_EXIT; [line 37, column 3]\n " shape="box"] - "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_7" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_2" ; -"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_8" [label="8: DeclStmt \n VARIABLE_DECLARED(i:int*); [line 36, column 3]\n *&i:int*=null [line 36, column 3]\n " shape="box"] + "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_9" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_3" ; + "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_9" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_7" [color="red" ]; +"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_10" [label="10: DeclStmt \n VARIABLE_DECLARED(i:int*); [line 36, column 3]\n *&i:int*=null [line 36, column 3]\n " shape="box"] - "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_8" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_4" ; + "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_10" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_6" ; "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_1" [label="1: Start FN_multiple_catches_bad\nFormals: b:_Bool\nLocals: 0$?%__sil_tmp__temp_construct_n$2:std::length_error 0$?%__sil_tmpSIL_materialize_temp__n$1:std::length_error const 0$?%__sil_tmp__temp_construct_n$9:std::range_error 0$?%__sil_tmpSIL_materialize_temp__n$8:std::range_error const j:int* i:int* \n " color=yellow style=filled] - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_1" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_16" ; + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_1" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_18" ; "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_2" [label="2: Exit FN_multiple_catches_bad \n " color=yellow style=filled] @@ -78,9 +94,7 @@ digraph cfg { "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" [label="4: + \n " ] - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_3" ; - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_13" [color="red" ]; - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_11" [color="red" ]; + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_16" ; "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_5" [label="5: Prune (true branch, if) \n n$0=*&b:_Bool [line 59, column 9]\n PRUNE(n$0, true); [line 59, column 9]\n " shape="invhouse"] @@ -105,31 +119,41 @@ digraph cfg { "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_10" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" ; -"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_11" [label="11: Return Stmt \n n$16=*&i:int* [line 65, column 13]\n n$17=*n$16:int [line 65, column 12]\n " shape="box"] +"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_11" [label="11: CXXTry \n TRY_ENTRY; [line 58, column 3]\n " shape="box"] + + + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_11" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_5" ; + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_11" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_6" ; +"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_12" [label="12: Return Stmt \n n$17=*&i:int* [line 65, column 13]\n n$18=*n$17:int [line 65, column 12]\n " shape="box"] - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_11" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_12" ; -"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_12" [label="12: Return Stmt \n *&return:int=n$17 [line 65, column 5]\n " shape="box"] + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_12" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_13" ; +"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_13" [label="13: Return Stmt \n *&return:int=n$18 [line 65, column 5]\n " shape="box"] - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_12" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_2" ; -"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_13" [label="13: Return Stmt \n n$18=*&j:int* [line 67, column 13]\n n$19=*n$18:int [line 67, column 12]\n " shape="box"] + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_13" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_2" ; +"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_14" [label="14: Return Stmt \n n$19=*&j:int* [line 67, column 13]\n n$20=*n$19:int [line 67, column 12]\n " shape="box"] - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_13" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_14" ; -"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_14" [label="14: Return Stmt \n *&return:int=n$19 [line 67, column 5]\n " shape="box"] + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_14" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_15" ; +"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_15" [label="15: Return Stmt \n *&return:int=n$20 [line 67, column 5]\n " shape="box"] - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_14" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_2" ; -"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_15" [label="15: DeclStmt \n VARIABLE_DECLARED(j:int*); [line 57, column 3]\n *&j:int*=null [line 57, column 3]\n " shape="box"] + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_15" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_2" ; +"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_16" [label="16: CXXTry \n TRY_EXIT; [line 58, column 3]\n " shape="box"] - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_15" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_5" ; - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_15" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_6" ; -"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_16" [label="16: DeclStmt \n VARIABLE_DECLARED(i:int*); [line 56, column 3]\n *&i:int*=null [line 56, column 3]\n " shape="box"] + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_16" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_3" ; + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_16" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_14" [color="red" ]; + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_16" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_12" [color="red" ]; +"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_17" [label="17: DeclStmt \n VARIABLE_DECLARED(j:int*); [line 57, column 3]\n *&j:int*=null [line 57, column 3]\n " shape="box"] - "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_16" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_15" ; + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_17" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_11" ; +"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_18" [label="18: DeclStmt \n VARIABLE_DECLARED(i:int*); [line 56, column 3]\n *&i:int*=null [line 56, column 3]\n " shape="box"] + + + "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_18" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_17" ; "basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_1" [label="1: Start basic_throw_ok\nFormals: \nLocals: 0$?%__sil_tmp__temp_construct_n$1:std::runtime_error 0$?%__sil_tmpSIL_materialize_temp__n$0:std::runtime_error const \n " color=yellow style=filled] @@ -222,7 +246,7 @@ digraph cfg { "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_1" [label="1: Start deref_null\nFormals: p:int*\nLocals: \n " color=yellow style=filled] - "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_1" -> "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_3" ; + "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_1" -> "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_5" ; "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_2" [label="2: Exit deref_null \n " color=yellow style=filled] @@ -234,10 +258,18 @@ digraph cfg { "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_4" -> "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_2" ; +"deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_5" [label="5: CXXTry \n TRY_ENTRY; [line 19, column 3]\n " shape="box"] + + + "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_5" -> "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_3" ; +"deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_6" [label="6: CXXTry \n TRY_EXIT; [line 19, column 3]\n " shape="box"] + + + "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_6" -> "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_2" ; "main.fad58de7366495db4650cfefac2fcd61_1" [label="1: Start main\nFormals: \nLocals: \n " color=yellow style=filled] - "main.fad58de7366495db4650cfefac2fcd61_1" -> "main.fad58de7366495db4650cfefac2fcd61_3" ; + "main.fad58de7366495db4650cfefac2fcd61_1" -> "main.fad58de7366495db4650cfefac2fcd61_5" ; "main.fad58de7366495db4650cfefac2fcd61_2" [label="2: Exit main \n " color=yellow style=filled] @@ -249,8 +281,17 @@ digraph cfg { "main.fad58de7366495db4650cfefac2fcd61_4" -> "main.fad58de7366495db4650cfefac2fcd61_2" ; -"main.fad58de7366495db4650cfefac2fcd61_5" [label="5: Return Stmt \n *&return:int=-1 [line 76, column 5]\n " shape="box"] +"main.fad58de7366495db4650cfefac2fcd61_5" [label="5: CXXTry \n TRY_ENTRY; [line 73, column 3]\n " shape="box"] + + + "main.fad58de7366495db4650cfefac2fcd61_5" -> "main.fad58de7366495db4650cfefac2fcd61_3" ; +"main.fad58de7366495db4650cfefac2fcd61_6" [label="6: Return Stmt \n *&return:int=-1 [line 76, column 5]\n " shape="box"] + + + "main.fad58de7366495db4650cfefac2fcd61_6" -> "main.fad58de7366495db4650cfefac2fcd61_2" ; +"main.fad58de7366495db4650cfefac2fcd61_7" [label="7: CXXTry \n TRY_EXIT; [line 73, column 3]\n " shape="box"] - "main.fad58de7366495db4650cfefac2fcd61_5" -> "main.fad58de7366495db4650cfefac2fcd61_2" ; + "main.fad58de7366495db4650cfefac2fcd61_7" -> "main.fad58de7366495db4650cfefac2fcd61_2" ; + "main.fad58de7366495db4650cfefac2fcd61_7" -> "main.fad58de7366495db4650cfefac2fcd61_6" [color="red" ]; }