[clang] basic support for exceptional control-flow

Summary:
This diff:
- translates C++ `catch` blocks
- adds an exceptional control-flow edge from the end of a `try` block to the beginning of a `catch` block

This obviously doesn't reflect the way exceptions actually work, but I think it is better than what we have now. For one thing, we'll see/translate code inside `catch` blocks, which were opaque before. If Clang analyses don't want this behavior, they can simply use `ProcCfg.Normal` (which, up until this diff, behaved identically to `ProcCfg.Exceptional`.

In the future, we can extend `trans_state` to track blocks that might throw an exception, and have each of these blocks transition to `catch` instead.

Reviewed By: jvillard

Differential Revision: D7814521

fbshipit-source-id: 67b86a6
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 316da14857
commit 5ed2016899

@ -332,6 +332,8 @@ let append_locals pdesc new_locals =
(pdesc.attributes).locals <- pdesc.attributes.locals @ 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 *) (** Set the successor nodes and exception nodes, and build predecessor links *)
let set_succs_exn_base (node: Node.t) succs exn = let set_succs_exn_base (node: Node.t) succs exn =
node.succs <- succs ; node.succs <- succs ;

@ -190,6 +190,8 @@ val iter_nodes : (Node.t -> unit) -> t -> unit
val iter_slope_range : (Node.t -> unit) -> Node.t -> Node.t -> unit val iter_slope_range : (Node.t -> unit) -> Node.t -> Node.t -> unit
(** iterate between two nodes or until we reach a branching structure *) (** iterate between two nodes or until we reach a branching structure *)
val set_succs_exn_only : Node.t -> Node.t list -> unit
val node_set_succs_exn : t -> Node.t -> Node.t list -> Node.t list -> unit 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 *) (** Set the successor nodes and exception nodes, and build predecessor links *)

@ -1939,6 +1939,43 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
instruction trans_state' stmt instruction trans_state' stmt
and tryStmt_trans trans_state stmts =
let open Clang_ast_t in
let translate_catch catch_root_nodes_acc = function
| CXXCatchStmt (catch_stmt_info, catch_body_stmts, _) ->
let catch_trans_result =
compoundStmt_trans trans_state catch_stmt_info catch_body_stmts
in
(* no risk of duplicates because two catch blocks should never have the same root nodes
(they have to be in different syntactic locations, after all!) *)
catch_trans_result.control.root_nodes @ catch_root_nodes_acc
| _ ->
assert false
in
match stmts with
| try_body_stmt :: catch_stmts ->
let try_trans_result = instruction trans_state try_body_stmt in
let catch_start_nodes = List.fold catch_stmts ~f:translate_catch ~init:[] in
(* 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
blocks, and add transitions from those to the catch block instead *)
let try_control = try_trans_result.control in
let try_ends =
if List.is_empty try_control.leaf_nodes then
(* try ends in return; transition from beginning instead *)
try_control.root_nodes
else try_control.leaf_nodes
in
List.iter
~f:(fun try_end -> Procdesc.set_succs_exn_only try_end catch_start_nodes)
try_ends ;
try_trans_result
| _ ->
(* try should always have a catch statement *)
assert false
and loop_instruction trans_state loop_kind stmt_info = and loop_instruction trans_state loop_kind stmt_info =
let outer_continuation = trans_state.continuation in let outer_continuation = trans_state.continuation in
let context = trans_state.context in let context = trans_state.context in
@ -3323,16 +3360,16 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
compoundStmt_trans trans_state stmt_info stmts compoundStmt_trans trans_state stmt_info stmts
| ObjCAtTryStmt (stmt_info, stmts) -> | ObjCAtTryStmt (stmt_info, stmts) ->
compoundStmt_trans trans_state stmt_info stmts compoundStmt_trans trans_state stmt_info stmts
| CXXTryStmt (stmt_info, stmts) -> | CXXTryStmt (_, try_stmts) ->
L.(debug Capture Medium) tryStmt_trans trans_state try_stmts
"@\n!!!!WARNING: found statement %s. @\nTranslation need to be improved.... @\n" | CXXCatchStmt _ ->
(Clang_ast_proj.get_stmt_kind_string instr) ; (* should by handled by try statement *)
compoundStmt_trans trans_state stmt_info stmts assert false
| ObjCAtThrowStmt (stmt_info, stmts) | CXXThrowExpr (stmt_info, stmts, _) -> | ObjCAtThrowStmt (stmt_info, stmts) | CXXThrowExpr (stmt_info, stmts, _) ->
objc_cxx_throw_trans trans_state stmt_info stmts objc_cxx_throw_trans trans_state stmt_info stmts
| ObjCAtFinallyStmt (stmt_info, stmts) -> | ObjCAtFinallyStmt (stmt_info, stmts) ->
compoundStmt_trans trans_state stmt_info stmts compoundStmt_trans trans_state stmt_info stmts
| ObjCAtCatchStmt (stmt_info, _, _) | CXXCatchStmt (stmt_info, _, _) -> | ObjCAtCatchStmt (stmt_info, _, _) ->
compoundStmt_trans trans_state stmt_info [] compoundStmt_trans trans_state stmt_info []
| PredefinedExpr (_, _, expr_info, _) -> | PredefinedExpr (_, _, expr_info, _) ->
stringLiteral_trans trans_state expr_info "" stringLiteral_trans trans_state expr_info ""

@ -7,8 +7,10 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
#include <exception>
#include <mutex> #include <mutex>
#include <new> #include <new>
#include <stdexcept>
#include <thread> #include <thread>
namespace infer { namespace infer {
@ -358,4 +360,125 @@ void dead_lock_guard_ok() { std::lock_guard<std::mutex> lock(my_mutex); }
void dead_unique_lock_ok() { std::unique_lock<std::mutex> lock(my_mutex); } void dead_unique_lock_ok() { std::unique_lock<std::mutex> lock(my_mutex); }
extern int maybe_throw();
class Exceptions {
int read_in_catch1_ok() {
int i = 1;
try {
throw std::runtime_error("error");
} catch (...) {
return i;
}
return 0;
}
int read_in_catch_explicit_throw_ok() {
int i = 1;
try {
maybe_throw();
} catch (...) {
return i;
}
return 0;
}
int dead_in_catch_bad() {
try {
throw std::runtime_error("error");
} catch (...) {
int i = 1;
}
return 0;
}
int FN_unreachable_catch_bad() {
int i = 1;
try {
} catch (...) {
return i;
}
return 0;
}
int multiple_catches_ok(bool b) {
int i = 1;
int j = 2;
try {
if (b) {
throw std::length_error("error");
} else {
throw std::range_error("error");
}
} catch (std::length_error& msg) {
return i;
} catch (std::range_error& msg) {
return j;
}
return 0;
}
void dont_throw() {}
int FN_harder_unreachable_catch_bad() {
int i = 1;
try {
dont_throw();
} catch (...) {
return i;
}
return 0;
}
// currently, the only transition to the catch block is at the end of the try
// block
int FP_read_in_catch_tricky_ok(bool b1, bool b2) {
int i = 1;
try {
if (b1) {
throw std::runtime_error("error");
}
i = 2;
if (b2) {
throw std::runtime_error("error");
}
} catch (...) {
return i;
}
return 0;
}
int return_in_try1_ok() {
bool b;
try {
maybe_throw();
return 3;
} catch (const char* msg) {
b = true;
}
if (b) {
return 2;
}
return 3;
}
int return_in_try2_ok() {
bool b;
try {
return maybe_throw();
} catch (const char* msg) {
b = true;
}
if (b) {
return 2;
}
return 3;
}
};
} }

@ -1,3 +1,5 @@
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::Exceptions_FP_read_in_catch_tricky_ok, 1, DEAD_STORE, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::Exceptions_dead_in_catch_bad, 4, DEAD_STORE, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::FP_assign_array_tricky_ok, 3, DEAD_STORE, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::FP_assign_array_tricky_ok, 3, DEAD_STORE, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::capture_by_value_bad, 3, DEAD_STORE, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::capture_by_value_bad, 3, DEAD_STORE, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::dead_pointer_bad, 2, DEAD_STORE, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::dead_pointer_bad, 2, DEAD_STORE, ERROR, [Write of unused value]
@ -8,7 +10,7 @@ codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::dead_then_live_bad, 1,
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::easy_bad, 0, DEAD_STORE, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::easy_bad, 0, DEAD_STORE, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::init_capture_no_call_bad, 1, DEAD_STORE, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::init_capture_no_call_bad, 1, DEAD_STORE, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::init_capture_reassign_bad, 1, DEAD_STORE, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::init_capture_reassign_bad, 1, DEAD_STORE, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::lambda_bad::lambda_dead_stores.cpp:147:11_operator(), 1, DEAD_STORE, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::lambda_bad::lambda_dead_stores.cpp:149:11_operator(), 1, DEAD_STORE, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus1_bad, 2, DEAD_STORE, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus1_bad, 2, DEAD_STORE, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus2_bad, 2, DEAD_STORE, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus2_bad, 2, DEAD_STORE, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus3_bad, 2, DEAD_STORE, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus3_bad, 2, DEAD_STORE, ERROR, [Write of unused value]

@ -7,6 +7,9 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*/ */
#include <exception>
#include <stdexcept>
int deref(int* p) { int deref(int* p) {
if (p == 0) { if (p == 0) {
throw "Null pointer!"; throw "Null pointer!";
@ -23,6 +26,51 @@ int deref_null(int* p) {
int call_deref_with_null() { deref_null(nullptr); } int call_deref_with_null() { deref_null(nullptr); }
void basic_throw_ok() { throw std::runtime_error("throwing!"); }
int dead_deref_null_after_throw_ok() {
int* i = nullptr;
throw std::runtime_error("throwing!");
return *i;
}
int FN_deref_null_in_catch_bad() {
int* i = nullptr;
try {
throw std::runtime_error("error");
} catch (...) {
return *i;
}
return 0;
}
int FN_deref_null_after_catch_bad(int* i) {
try {
*i = 2;
throw std::runtime_error("error");
} catch (...) {
i = nullptr;
}
return *i;
}
int FN_multiple_catches_bad(bool b) {
int* i = nullptr;
int* j = nullptr;
try {
if (b) {
throw std::length_error("error");
} else {
throw std::range_error("error");
}
} catch (std::length_error& msg) {
return *i;
} catch (std::range_error& msg) {
return *j;
}
return 0;
}
int main() { int main() {
try { try {
return deref(0); return deref(0);

@ -1,24 +1,152 @@
/* @generated */ /* @generated */
digraph cfg { digraph cfg {
"call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_1" [label="1: Start call_deref_with_null\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 24, column 1]\n " color=yellow style=filled] "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$4:std::runtime_error 0$?%__sil_tmpSIL_materialize_temp__n$5:std::runtime_error const \n DECLARE_LOCALS(&return,&0$?%__sil_tmp__temp_construct_n$4,&0$?%__sil_tmpSIL_materialize_temp__n$5); [line 47, column 1]\n " color=yellow style=filled]
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_1" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_5" ;
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_2" [label="2: Exit FN_deref_null_after_catch_bad \n " color=yellow style=filled]
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" [label="3: Return Stmt \n n$0=*&i:int* [line 54, column 11]\n n$1=*n$0:int [line 54, column 10]\n *&return:int=n$1 [line 54, column 3]\n " shape="box"]
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_2" ;
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_4" [label="4: ObjCCPPThrow \n n$6=_fun_std::runtime_error_runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$5:std::runtime_error const *,\"error\":char const *) [line 50, column 11]\n n$7=_fun_std::runtime_error_runtime_error(&0$?%__sil_tmp__temp_construct_n$4:std::runtime_error*,&0$?%__sil_tmpSIL_materialize_temp__n$5:std::runtime_error const &) [line 50, column 11]\n n$8=_fun___infer_objc_cpp_throw(&0$?%__sil_tmp__temp_construct_n$4:std::runtime_error) [line 50, column 5]\n " shape="box"]
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_4" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" ;
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_4" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_6" [color="red" ];
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_5" [label="5: BinaryOperatorStmt: Assign \n n$9=*&i:int* [line 49, column 6]\n *n$9:int=2 [line 49, column 5]\n " shape="box"]
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_5" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_4" ;
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_6" [label="6: BinaryOperatorStmt: Assign \n *&i:int*=null [line 52, column 5]\n " shape="box"]
"FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_6" -> "FN_deref_null_after_catch_bad#4627123003703707696.43441e3badf1bb571cbe770f9d51a51c_3" ;
"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$2:std::runtime_error 0$?%__sil_tmpSIL_materialize_temp__n$3:std::runtime_error const i:int* \n DECLARE_LOCALS(&return,&0$?%__sil_tmp__temp_construct_n$2,&0$?%__sil_tmpSIL_materialize_temp__n$3,&i); [line 37, column 1]\n " color=yellow style=filled]
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_1" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_6" ;
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_2" [label="2: Exit FN_deref_null_in_catch_bad \n " color=yellow style=filled]
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_3" [label="3: Return Stmt \n *&return:int=0 [line 44, 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: ObjCCPPThrow \n n$4=_fun_std::runtime_error_runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$3:std::runtime_error const *,\"error\":char const *) [line 40, column 11]\n n$5=_fun_std::runtime_error_runtime_error(&0$?%__sil_tmp__temp_construct_n$2:std::runtime_error*,&0$?%__sil_tmpSIL_materialize_temp__n$3:std::runtime_error const &) [line 40, column 11]\n n$6=_fun___infer_objc_cpp_throw(&0$?%__sil_tmp__temp_construct_n$2:std::runtime_error) [line 40, column 5]\n " shape="box"]
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_4" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_3" ;
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_4" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_5" [color="red" ];
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_5" [label="5: Return Stmt \n n$8=*&i:int* [line 42, column 13]\n n$9=*n$8:int [line 42, column 12]\n *&return:int=n$9 [line 42, column 5]\n " shape="box"]
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_5" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_2" ;
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_6" [label="6: DeclStmt \n *&i:int*=null [line 38, column 3]\n " shape="box"]
"FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_6" -> "FN_deref_null_in_catch_bad#9297890526029657977.c83eec7c9ab8ce2e38ddbc08f8c3dfeb_4" ;
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_1" [label="1: Start FN_multiple_catches_bad\nFormals: b:_Bool\nLocals: 0$?%__sil_tmp__temp_construct_n$4:std::length_error 0$?%__sil_tmpSIL_materialize_temp__n$5:std::length_error const 0$?%__sil_tmp__temp_construct_n$10:std::range_error 0$?%__sil_tmpSIL_materialize_temp__n$11:std::range_error const j:int* i:int* \n DECLARE_LOCALS(&return,&0$?%__sil_tmp__temp_construct_n$4,&0$?%__sil_tmpSIL_materialize_temp__n$5,&0$?%__sil_tmp__temp_construct_n$10,&0$?%__sil_tmpSIL_materialize_temp__n$11,&j,&i); [line 57, column 1]\n " color=yellow style=filled]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_1" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_12" ;
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_2" [label="2: Exit FN_multiple_catches_bad \n " color=yellow style=filled]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_3" [label="3: Return Stmt \n *&return:int=0 [line 71, column 3]\n " shape="box"]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_3" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_2" ;
"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_10" [color="red" ];
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_9" [color="red" ];
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_5" [label="5: Prune (true branch, if) \n n$2=*&b:_Bool [line 61, column 9]\n PRUNE(n$2, true); [line 61, column 9]\n " shape="invhouse"]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_5" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_7" ;
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_6" [label="6: Prune (false branch, if) \n n$2=*&b:_Bool [line 61, column 9]\n PRUNE(!n$2, false); [line 61, column 9]\n " shape="invhouse"]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_6" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_8" ;
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_7" [label="7: ObjCCPPThrow \n n$6=_fun_std::length_error_length_error(&0$?%__sil_tmpSIL_materialize_temp__n$5:std::length_error const *,\"error\":char const *) [line 62, column 13]\n n$7=_fun_std::length_error_length_error(&0$?%__sil_tmp__temp_construct_n$4:std::length_error*,&0$?%__sil_tmpSIL_materialize_temp__n$5:std::length_error const &) [line 62, column 13]\n n$8=_fun___infer_objc_cpp_throw(&0$?%__sil_tmp__temp_construct_n$4:std::length_error) [line 62, column 7]\n " shape="box"]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_7" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" ;
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_8" [label="8: ObjCCPPThrow \n n$12=_fun_std::range_error_range_error(&0$?%__sil_tmpSIL_materialize_temp__n$11:std::range_error const *,\"error\":char const *) [line 64, column 13]\n n$13=_fun_std::range_error_range_error(&0$?%__sil_tmp__temp_construct_n$10:std::range_error*,&0$?%__sil_tmpSIL_materialize_temp__n$11:std::range_error const &) [line 64, column 13]\n n$14=_fun___infer_objc_cpp_throw(&0$?%__sil_tmp__temp_construct_n$10:std::range_error) [line 64, column 7]\n " shape="box"]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_8" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_4" ;
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_9" [label="9: Return Stmt \n n$17=*&i:int* [line 67, column 13]\n n$18=*n$17:int [line 67, column 12]\n *&return:int=n$18 [line 67, column 5]\n " shape="box"]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_9" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_2" ;
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_10" [label="10: Return Stmt \n n$21=*&j:int* [line 69, column 13]\n n$22=*n$21:int [line 69, column 12]\n *&return:int=n$22 [line 69, column 5]\n " shape="box"]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_10" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_2" ;
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_11" [label="11: DeclStmt \n *&j:int*=null [line 59, 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: DeclStmt \n *&i:int*=null [line 58, column 3]\n " shape="box"]
"FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_12" -> "FN_multiple_catches_bad#4595182522053295670.680a793e449c2d7439ff6441ca69fa98_11" ;
"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$2:std::runtime_error const \n DECLARE_LOCALS(&return,&0$?%__sil_tmp__temp_construct_n$1,&0$?%__sil_tmpSIL_materialize_temp__n$2); [line 29, column 1]\n " color=yellow style=filled]
"basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_1" -> "basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_3" ;
"basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_2" [label="2: Exit basic_throw_ok \n " color=yellow style=filled]
"basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_3" [label="3: ObjCCPPThrow \n n$3=_fun_std::runtime_error_runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$2:std::runtime_error const *,\"throwing!\":char const *) [line 29, column 31]\n n$4=_fun_std::runtime_error_runtime_error(&0$?%__sil_tmp__temp_construct_n$1:std::runtime_error*,&0$?%__sil_tmpSIL_materialize_temp__n$2:std::runtime_error const &) [line 29, column 31]\n n$5=_fun___infer_objc_cpp_throw(&0$?%__sil_tmp__temp_construct_n$1:std::runtime_error) [line 29, column 25]\n " shape="box"]
"basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_3" -> "basic_throw_ok#10529188890980782893.c9e1b8dd080b2621cfca65612331859d_2" ;
"call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_1" [label="1: Start call_deref_with_null\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 27, column 1]\n " color=yellow style=filled]
"call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_1" -> "call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_3" ; "call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_1" -> "call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_3" ;
"call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_2" [label="2: Exit call_deref_with_null \n " color=yellow style=filled] "call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_2" [label="2: Exit call_deref_with_null \n " color=yellow style=filled]
"call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_3" [label="3: Call _fun_deref_null \n n$1=_fun_deref_null(null:int*) [line 24, column 30]\n " shape="box"] "call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_3" [label="3: Call _fun_deref_null \n n$1=_fun_deref_null(null:int*) [line 27, column 30]\n " shape="box"]
"call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_3" -> "call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_2" ; "call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_3" -> "call_deref_with_null#4611966425999531792.6346543307e9a799421a89e451b917c2_2" ;
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_1" [label="1: Start deref\nFormals: p:int*\nLocals: \n DECLARE_LOCALS(&return); [line 10, column 1]\n " color=yellow style=filled] "dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_1" [label="1: Start dead_deref_null_after_throw_ok\nFormals: \nLocals: 0$?%__sil_tmp__temp_construct_n$3:std::runtime_error 0$?%__sil_tmpSIL_materialize_temp__n$4:std::runtime_error const i:int* \n DECLARE_LOCALS(&return,&0$?%__sil_tmp__temp_construct_n$3,&0$?%__sil_tmpSIL_materialize_temp__n$4,&i); [line 31, column 1]\n " color=yellow style=filled]
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_1" -> "dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_5" ;
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_2" [label="2: Exit dead_deref_null_after_throw_ok \n " color=yellow style=filled]
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_3" [label="3: Return Stmt \n n$0=*&i:int* [line 34, column 11]\n n$1=*n$0:int [line 34, column 10]\n *&return:int=n$1 [line 34, 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: ObjCCPPThrow \n n$5=_fun_std::runtime_error_runtime_error(&0$?%__sil_tmpSIL_materialize_temp__n$4:std::runtime_error const *,\"throwing!\":char const *) [line 33, column 9]\n n$6=_fun_std::runtime_error_runtime_error(&0$?%__sil_tmp__temp_construct_n$3:std::runtime_error*,&0$?%__sil_tmpSIL_materialize_temp__n$4:std::runtime_error const &) [line 33, column 9]\n n$7=_fun___infer_objc_cpp_throw(&0$?%__sil_tmp__temp_construct_n$3:std::runtime_error) [line 33, column 3]\n " shape="box"]
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_4" -> "dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_3" ;
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_5" [label="5: DeclStmt \n *&i:int*=null [line 32, column 3]\n " shape="box"]
"dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_5" -> "dead_deref_null_after_throw_ok#12025371096822526715.42d41c040f3a321bb94f60bf7b55d001_4" ;
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_1" [label="1: Start deref\nFormals: p:int*\nLocals: \n DECLARE_LOCALS(&return); [line 13, column 1]\n " color=yellow style=filled]
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_1" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_5" ; "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_1" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_5" ;
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_2" [label="2: Exit deref \n " color=yellow style=filled] "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_2" [label="2: Exit deref \n " color=yellow style=filled]
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_3" [label="3: Return Stmt \n n$0=*&p:int* [line 14, column 11]\n n$1=*n$0:int [line 14, column 10]\n *&return:int=n$1 [line 14, column 3]\n " shape="box"] "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_3" [label="3: Return Stmt \n n$0=*&p:int* [line 17, column 11]\n n$1=*n$0:int [line 17, column 10]\n *&return:int=n$1 [line 17, column 3]\n " shape="box"]
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_3" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_2" ; "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_3" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_2" ;
@ -26,43 +154,48 @@ digraph cfg {
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_4" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_3" ; "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_4" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_3" ;
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_5" [label="5: BinaryOperatorStmt: EQ \n n$3=*&p:int* [line 11, column 7]\n " shape="box"] "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_5" [label="5: BinaryOperatorStmt: EQ \n n$3=*&p:int* [line 14, column 7]\n " shape="box"]
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_5" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_6" ; "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_5" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_6" ;
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_5" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_7" ; "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_5" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_7" ;
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_6" [label="6: Prune (true branch, if) \n PRUNE((n$3 == null), true); [line 11, column 7]\n " shape="invhouse"] "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_6" [label="6: Prune (true branch, if) \n PRUNE((n$3 == null), true); [line 14, column 7]\n " shape="invhouse"]
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_6" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_8" ; "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_6" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_8" ;
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_7" [label="7: Prune (false branch, if) \n PRUNE(!(n$3 == null), false); [line 11, column 7]\n " shape="invhouse"] "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_7" [label="7: Prune (false branch, if) \n PRUNE(!(n$3 == null), false); [line 14, column 7]\n " shape="invhouse"]
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_7" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_4" ; "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_7" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_4" ;
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_8" [label="8: ObjCCPPThrow \n n$5=_fun___infer_objc_cpp_throw(\"Null pointer!\":char const *) [line 12, column 5]\n " shape="box"] "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_8" [label="8: ObjCCPPThrow \n n$5=_fun___infer_objc_cpp_throw(\"Null pointer!\":char const *) [line 15, column 5]\n " shape="box"]
"deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_8" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_4" ; "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_8" -> "deref#13506892413034678690.824465c4193ad2288eb512b1083edab3_4" ;
"deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_1" [label="1: Start deref_null\nFormals: p:int*\nLocals: \n DECLARE_LOCALS(&return); [line 17, column 1]\n " color=yellow style=filled] "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_1" [label="1: Start deref_null\nFormals: p:int*\nLocals: \n DECLARE_LOCALS(&return); [line 20, column 1]\n " color=yellow style=filled]
"deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_1" -> "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_3" ; "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_1" -> "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_3" ;
"deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_2" [label="2: Exit deref_null \n " color=yellow style=filled] "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_2" [label="2: Exit deref_null \n " color=yellow style=filled]
"deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_3" [label="3: Return Stmt \n n$4=*&p:int* [line 19, column 13]\n n$5=*n$4:int [line 19, column 12]\n *&return:int=n$5 [line 19, column 5]\n " shape="box"] "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_3" [label="3: Return Stmt \n n$1=*&p:int* [line 22, column 13]\n n$2=*n$1:int [line 22, column 12]\n *&return:int=n$2 [line 22, column 5]\n " shape="box"]
"deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_3" -> "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_2" ; "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_3" -> "deref_null#11536394632240553702.ea4eed042da22ab7ceb619ec1b7f73bb_2" ;
"main.fad58de7366495db4650cfefac2fcd61_1" [label="1: Start main\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 26, column 1]\n " color=yellow style=filled] "main.fad58de7366495db4650cfefac2fcd61_1" [label="1: Start main\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 74, column 1]\n " color=yellow style=filled]
"main.fad58de7366495db4650cfefac2fcd61_1" -> "main.fad58de7366495db4650cfefac2fcd61_3" ; "main.fad58de7366495db4650cfefac2fcd61_1" -> "main.fad58de7366495db4650cfefac2fcd61_3" ;
"main.fad58de7366495db4650cfefac2fcd61_2" [label="2: Exit main \n " color=yellow style=filled] "main.fad58de7366495db4650cfefac2fcd61_2" [label="2: Exit main \n " color=yellow style=filled]
"main.fad58de7366495db4650cfefac2fcd61_3" [label="3: Return Stmt \n n$4=_fun_deref(null:int*) [line 28, column 12]\n *&return:int=n$4 [line 28, column 5]\n " shape="box"] "main.fad58de7366495db4650cfefac2fcd61_3" [label="3: Return Stmt \n n$1=_fun_deref(null:int*) [line 76, column 12]\n *&return:int=n$1 [line 76, column 5]\n " shape="box"]
"main.fad58de7366495db4650cfefac2fcd61_3" -> "main.fad58de7366495db4650cfefac2fcd61_2" ; "main.fad58de7366495db4650cfefac2fcd61_3" -> "main.fad58de7366495db4650cfefac2fcd61_2" ;
"main.fad58de7366495db4650cfefac2fcd61_3" -> "main.fad58de7366495db4650cfefac2fcd61_4" [color="red" ];
"main.fad58de7366495db4650cfefac2fcd61_4" [label="4: Return Stmt \n *&return:int=-1 [line 78, column 5]\n " shape="box"]
"main.fad58de7366495db4650cfefac2fcd61_4" -> "main.fad58de7366495db4650cfefac2fcd61_2" ;
} }

Loading…
Cancel
Save