[Eradicate] Fix issue where direct throw instructions were not handled like method calls that trow exceptions.

master
Cristiano Calcagno 10 years ago
parent 2365e6244d
commit a94fab55e8

@ -54,6 +54,8 @@ module Node = struct
let exn_handler_kind = Stmt_node "exception handler"
let exn_sink_kind = Stmt_node "exceptions sink"
let throw_kind = Stmt_node "throw"
type cfg = (** data type for the control flow graph *)
{ node_id : int ref;

@ -145,6 +145,9 @@ module Node : sig
(** kind of Stmt_node for an exceptions sink. *)
val exn_sink_kind : nodekind
(** kind of Stmt_node for a throw instruction. *)
val throw_kind : nodekind
(** Append the instructions and temporaries to the list of instructions to execute *)
val append_instrs_temps : t -> Sil.instr list -> Ident.t list -> unit

@ -938,13 +938,19 @@ let typecheck_node
let typestates_exn = ref [] in
let handle_exceptions typestate instr = match instr with
| Sil.Call (_, Sil.Const (Sil.Cfun callee_pname), _, _, _) ->
(* check if the call might throw an exception *)
let exceptions =
match get_proc_desc callee_pname with
| Some callee_pdesc ->
(Specs.proc_get_attributes callee_pname callee_pdesc).Sil.exceptions
| None -> [] in
if exceptions <> [] then
typestates_exn := typestate :: !typestates_exn;
typestates_exn := typestate :: !typestates_exn
| Sil.Set (Sil.Lvar pv, _, _, _) when
Sil.pvar_is_return pv &&
Cfg.Node.get_kind node = Cfg.Node.throw_kind ->
(* throw instruction *)
typestates_exn := typestate :: !typestates_exn
| _ -> () in
let canonical_node = find_canonical_duplicate node in

@ -936,11 +936,10 @@ let rec instruction context pc instr : translation =
else
Prune (prune_node_true, prune_node_false)
| JBir.Throw expr ->
let node_kind = Cfg.Node.Stmt_node "throw" in
let (ids, instrs, sil_expr) = expression context pc expr in
let sil_exn = Sil.Const (Sil.Cexn sil_expr) in
let sil_instr = Sil.Set (Sil.Lvar ret_var, ret_type, sil_exn, loc) in
let node = create_node node_kind ids (instrs @ [sil_instr]) in
let node = create_node Cfg.Node.throw_kind ids (instrs @ [sil_instr]) in
JContext.add_goto_jump context pc JContext.Exit;
Instr node
| JBir.New (var, cn, constr_type_list, constr_arg_list) ->

@ -88,4 +88,27 @@ public class ReturnNotNullable {
String testOptional(Optional<String> os) {
return os.orNull();
}
class E extends Exception {
}
String return_null_in_catch() {
try {
throw new E();
} catch (E e) {
return null;
}
}
String return_null_in_catch_after_throw() {
try {
try {
throw new E();
} catch (E e) {
throw e;
}
} catch (E e) {
return null;
}
}
}

@ -49,13 +49,21 @@ public class ReturnNotNullableTest {
throws IOException, InterruptedException, InferException {
String[] nullableMethods = {"returnNull", "returnNullable"};
String[] nullableMethods = {
"returnNull",
"returnNullable",
"return_null_in_catch",
"return_null_in_catch_after_throw",
};
List<ErrorPattern> errorPatterns = createPatterns(
RETURN_NOT_NULLABLE,
SOURCE_FILE,
nullableMethods);
String[] redundantMethods = {"redundantEq", "redundantNeq"};
String[] redundantMethods = {
"redundantEq",
"redundantNeq",
};
errorPatterns.addAll(
createPatterns(
CONDITION_REDUNDANT_NONNULL,

Loading…
Cancel
Save