Skip to content

Commit 08f6b27

Browse files
committed
Replace direct use of EXC_SUFFIX with a universal catch
1 parent 4e13ea9 commit 08f6b27

File tree

2 files changed

+56
-15
lines changed

2 files changed

+56
-15
lines changed

src/java_bytecode/java_entry_point.cpp

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -307,11 +307,9 @@ void java_record_outputs(
307307
codet output(ID_output);
308308
output.operands().resize(2);
309309

310-
assert(symbol_table.has_symbol(id2string(function.name)+EXC_SUFFIX));
311-
312310
// retrieve the exception variable
313311
const symbolt exc_symbol=symbol_table.lookup(
314-
id2string(function.name)+EXC_SUFFIX);
312+
JAVA_ENTRY_POINT_EXCEPTION_SYMBOL);
315313

316314
output.op0()=address_of_exprt(
317315
index_exprt(string_constantt(exc_symbol.base_name),
@@ -613,17 +611,19 @@ bool java_entry_point(
613611
call_main.lhs()=return_symbol.symbol_expr();
614612
}
615613

616-
if(!symbol_table.has_symbol(id2string(symbol.name)+EXC_SUFFIX))
617-
{
618-
// add the exceptional return value
619-
auxiliary_symbolt exc_symbol;
620-
exc_symbol.mode=ID_java;
621-
exc_symbol.is_static_lifetime=true;
622-
exc_symbol.name=id2string(symbol.name)+EXC_SUFFIX;
623-
exc_symbol.base_name=id2string(symbol.name)+EXC_SUFFIX;
624-
exc_symbol.type=java_reference_type(empty_typet());
625-
symbol_table.add(exc_symbol);
626-
}
614+
// add the exceptional return value
615+
auxiliary_symbolt exc_symbol;
616+
exc_symbol.mode=ID_java;
617+
exc_symbol.name=JAVA_ENTRY_POINT_EXCEPTION_SYMBOL;
618+
exc_symbol.base_name=exc_symbol.name;
619+
exc_symbol.type=java_reference_type(empty_typet());
620+
symbol_table.add(exc_symbol);
621+
622+
// Zero-initialise the top-level exception catch variable:
623+
init_code.copy_to_operands(
624+
code_assignt(
625+
exc_symbol.symbol_expr(),
626+
null_pointer_exprt(to_pointer_type(exc_symbol.type))));
627627

628628
// create code that allocates the objects used as test arguments and
629629
// non-deterministically initializes them
@@ -638,8 +638,48 @@ bool java_entry_point(
638638
pointer_type_selector);
639639
call_main.arguments()=main_arguments;
640640

641+
// Create target labels for the toplevel exception handler:
642+
code_labelt toplevel_catch("toplevel_catch", code_skipt());
643+
code_labelt after_catch("after_catch", code_skipt());
644+
645+
code_blockt call_block;
646+
647+
// Push a universal exception handler:
648+
side_effect_expr_catcht push_universal_handler;
649+
irept catch_type_list(ID_exception_list);
650+
irept catch_target_list(ID_label);
651+
// Catch all exceptions:
652+
// This is equivalent to catching Throwable, but also works if some of
653+
// the class hierarchy is missing so that we can't determine that
654+
// the thrown instance is an indirect child of Throwable
655+
catch_type_list.get_sub().push_back(irept());
656+
catch_target_list.get_sub().push_back(irept(toplevel_catch.get_label()));
657+
push_universal_handler.set(ID_exception_list, catch_type_list);
658+
push_universal_handler.set(ID_label, catch_target_list);
659+
660+
call_block.copy_to_operands(code_expressiont(push_universal_handler));
661+
641662
// we insert the call to the method AFTER the argument initialization code
642-
init_code.move_to_operands(call_main);
663+
call_block.move_to_operands(call_main);
664+
665+
// Pop the handler:
666+
side_effect_expr_catcht pop_handler;
667+
pop_handler.set(ID_exception_list, get_nil_irep());
668+
pop_handler.set(ID_label, get_nil_irep());
669+
670+
//call_block.copy_to_operands(code_expressiont(pop_handler));
671+
init_code.move_to_operands(call_block);
672+
673+
// Normal return: skip the exception handler:
674+
init_code.copy_to_operands(code_gotot(after_catch.get_label()));
675+
676+
// Exceptional return: catch and assign to exc_symbol.
677+
side_effect_expr_landingpadt landingpad(exc_symbol.symbol_expr());
678+
init_code.copy_to_operands(toplevel_catch);
679+
init_code.copy_to_operands(code_expressiont(landingpad));
680+
681+
// Converge normal and exceptional return:
682+
init_code.move_to_operands(after_catch);
643683

644684
// declare certain (which?) variables as test outputs
645685
java_record_outputs(symbol, main_arguments, init_code, symbol_table);

src/java_bytecode/java_entry_point.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Kroening, [email protected]
1515
#include <java_bytecode/select_pointer_type.h>
1616

1717
#define JAVA_ENTRY_POINT_RETURN_SYMBOL "return'"
18+
#define JAVA_ENTRY_POINT_EXCEPTION_SYMBOL "uncaught_exception'"
1819

1920
bool java_entry_point(
2021
class symbol_tablet &symbol_table,

0 commit comments

Comments
 (0)