Skip to content

Commit 2ed5dfd

Browse files
Add an assert-no-exceptions-thrown option
This is to specify that we want to replace all throw instructions by assert false. This is useful mainly for performance reasons as it simplifies conditions for symex, while retaining the non-exceptional behaviour of the program.
1 parent 06c4069 commit 2ed5dfd

File tree

6 files changed

+41
-13
lines changed

6 files changed

+41
-13
lines changed

jbmc/src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2349,9 +2349,10 @@ void java_bytecode_convert_methodt::convert_athrow(
23492349
exprt::operandst &results) const
23502350
{
23512351
if(
2352-
!throw_assertion_error &&
2353-
uncaught_exceptions_domaint::get_exception_type(op[0].type()) ==
2354-
"java::java.lang.AssertionError")
2352+
assert_no_exceptions_thrown ||
2353+
((uncaught_exceptions_domaint::get_exception_type(op[0].type()) ==
2354+
"java::java.lang.AssertionError") &&
2355+
!throw_assertion_error))
23552356
{
23562357
// we translate athrow into
23572358
// ASSERT false;
@@ -3190,7 +3191,8 @@ void java_bytecode_convert_method(
31903191
java_string_library_preprocesst &string_preprocess,
31913192
const class_hierarchyt &class_hierarchy,
31923193
bool threading_support,
3193-
const optionalt<prefix_filtert> &method_context)
3194+
const optionalt<prefix_filtert> &method_context,
3195+
bool assert_no_exceptions_thrown)
31943196

31953197
{
31963198
java_bytecode_convert_methodt java_bytecode_convert_method(
@@ -3201,7 +3203,8 @@ void java_bytecode_convert_method(
32013203
needed_lazy_methods,
32023204
string_preprocess,
32033205
class_hierarchy,
3204-
threading_support);
3206+
threading_support,
3207+
assert_no_exceptions_thrown);
32053208

32063209
java_bytecode_convert_method(class_symbol, method, method_context);
32073210
}

jbmc/src/java_bytecode/java_bytecode_convert_method.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ void java_bytecode_convert_method(
3939
java_string_library_preprocesst &string_preprocess,
4040
const class_hierarchyt &class_hierarchy,
4141
bool threading_support,
42-
const optionalt<prefix_filtert> &method_context);
42+
const optionalt<prefix_filtert> &method_context,
43+
bool assert_no_exceptions_thrown);
4344

4445
void create_method_stub_symbol(
4546
const irep_idt &identifier,

jbmc/src/java_bytecode/java_bytecode_convert_method_class.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ class java_bytecode_convert_methodt:public messaget
4040
optionalt<ci_lazy_methods_neededt> needed_lazy_methods,
4141
java_string_library_preprocesst &_string_preprocess,
4242
const class_hierarchyt &class_hierarchy,
43-
bool threading_support)
43+
bool threading_support,
44+
bool assert_no_exceptions_thrown)
4445
: messaget(_message_handler),
4546
symbol_table(symbol_table),
4647
ns(symbol_table),
4748
max_array_length(_max_array_length),
4849
throw_assertion_error(throw_assertion_error),
50+
assert_no_exceptions_thrown(assert_no_exceptions_thrown),
4951
threading_support(threading_support),
5052
needed_lazy_methods(std::move(needed_lazy_methods)),
5153
string_preprocess(_string_preprocess),
@@ -76,6 +78,7 @@ class java_bytecode_convert_methodt:public messaget
7678
namespacet ns;
7779
const size_t max_array_length;
7880
const bool throw_assertion_error;
81+
const bool assert_no_exceptions_thrown;
7982
const bool threading_support;
8083
optionalt<ci_lazy_methods_neededt> needed_lazy_methods;
8184

jbmc/src/java_bytecode/java_bytecode_language.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ void parse_java_language_options(const cmdlinet &cmd, optionst &options)
5959
"uncaught-exception-check", !cmd.isset("disable-uncaught-exception-check"));
6060
options.set_option(
6161
"throw-assertion-error", cmd.isset("throw-assertion-error"));
62+
options.set_option(
63+
"assert-no-exceptions-thrown", cmd.isset("assert-no-exceptions-thrown"));
6264
options.set_option("java-threading", cmd.isset("java-threading"));
6365

6466
if(cmd.isset("java-max-vla-length"))
@@ -144,6 +146,8 @@ java_bytecode_language_optionst::java_bytecode_language_optionst(
144146
assert_uncaught_exceptions =
145147
options.get_bool_option("uncaught-exception-check");
146148
throw_assertion_error = options.get_bool_option("throw-assertion-error");
149+
assert_no_exceptions_thrown =
150+
options.get_bool_option("assert-no-exceptions-thrown");
147151
threading_support = options.get_bool_option("java-threading");
148152
max_user_array_length =
149153
options.get_unsigned_int_option("java-max-vla-length");
@@ -1321,7 +1325,8 @@ bool java_bytecode_languaget::convert_single_method(
13211325
string_preprocess,
13221326
class_hierarchy,
13231327
language_options->threading_support,
1324-
language_options->method_context);
1328+
language_options->method_context,
1329+
language_options->assert_no_exceptions_thrown);
13251330
INVARIANT(declaring_class(symbol), "Method must have a declaring class.");
13261331
return false;
13271332
}
@@ -1355,7 +1360,7 @@ bool java_bytecode_languaget::convert_single_method(
13551360

13561361
bool java_bytecode_languaget::final(symbol_table_baset &)
13571362
{
1358-
PRECONDITION(language_options_initialized);
1363+
PRECONDITION(language_options.has_value());
13591364
return false;
13601365
}
13611366

jbmc/src/java_bytecode/java_bytecode_language.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Author: Daniel Kroening, [email protected]
3333
#define JAVA_BYTECODE_LANGUAGE_OPTIONS /*NOLINT*/ \
3434
"(disable-uncaught-exception-check)" \
3535
"(throw-assertion-error)" \
36+
"(assert-no-exceptions-thrown)" \
3637
"(java-assume-inputs-non-null)" \
3738
"(java-assume-inputs-interval):" \
3839
"(java-assume-inputs-integral)" \
@@ -57,6 +58,9 @@ Author: Daniel Kroening, [email protected]
5758
" assert statements instead of failing\n" \
5859
" at the location of the assert statement\n" \
5960
" --throw-runtime-exceptions make implicit runtime exceptions explicit\n" \
61+
" --assert-no-exceptions-thrown\n"\
62+
" transform `throw` instructions into `assert FALSE`\n"/* NOLINT(*) */ \
63+
" followed by `assume FALSE`.\n" \
6064
" --max-nondet-array-length N limit nondet (e.g. input) array size to <= N\n" /* NOLINT(*) */ \
6165
" --max-nondet-tree-depth N limit size of nondet (e.g. input) object tree;\n" /* NOLINT(*) */ \
6266
" at level N references are set to null\n" /* NOLINT(*) */ \
@@ -166,6 +170,10 @@ struct java_bytecode_language_optionst
166170
bool nondet_static = false;
167171
bool ignore_manifest_main_class = false;
168172

173+
/// Transform `athrow` bytecode instructions into `assert FALSE` followed
174+
/// by `assume FALSE`.
175+
bool assert_no_exceptions_thrown = false;
176+
169177
/// max size for user code created arrays
170178
size_t max_user_array_length = 0;
171179
lazy_methods_modet lazy_methods_mode =

jbmc/unit/java_bytecode/java_bytecode_convert_method/convert_method.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,14 +457,16 @@ SCENARIO(
457457
symbol_tablet symbol_table;
458458
java_string_library_preprocesst string_preprocess;
459459
const class_hierarchyt class_hierarchy{};
460+
const bool assert_no_exceptions_thrown = false;
460461
java_bytecode_convert_methodt converter{symbol_table,
461462
null_message_handler,
462463
10,
463464
true,
464465
{},
465466
string_preprocess,
466467
class_hierarchy,
467-
false};
468+
false,
469+
assert_no_exceptions_thrown};
468470

469471
GIVEN("An int array")
470472
{
@@ -571,14 +573,16 @@ SCENARIO(
571573
const std::size_t max_array_length = 10;
572574
const bool throw_assertion_error = true;
573575
const bool threading_support = false;
576+
const bool assert_no_exceptions_thrown = false;
574577
java_bytecode_convert_methodt converter{symbol_table,
575578
null_message_handler,
576579
max_array_length,
577580
throw_assertion_error,
578581
{},
579582
string_preprocess,
580583
class_hierarchy,
581-
threading_support};
584+
threading_support,
585+
assert_no_exceptions_thrown};
582586

583587
GIVEN("An int_array variable")
584588
{
@@ -677,14 +681,16 @@ SCENARIO(
677681
const std::size_t max_array_length = 10;
678682
const bool throw_assertion_error = true;
679683
const bool threading_support = false;
684+
const bool assert_no_exceptions_thrown = false;
680685
java_bytecode_convert_methodt converter{symbol_table,
681686
null_message_handler,
682687
max_array_length,
683688
throw_assertion_error,
684689
{},
685690
string_preprocess,
686691
class_hierarchy,
687-
threading_support};
692+
threading_support,
693+
assert_no_exceptions_thrown};
688694

689695
GIVEN("An int_array variable")
690696
{
@@ -818,14 +824,16 @@ SCENARIO(
818824
const std::size_t max_array_length = 10;
819825
const bool throw_assertion_error = true;
820826
const bool threading_support = false;
827+
const bool assert_no_exceptions_thrown = false;
821828
java_bytecode_convert_methodt converter{symbol_table,
822829
null_message_handler,
823830
max_array_length,
824831
throw_assertion_error,
825832
{},
826833
string_preprocess,
827834
class_hierarchy,
828-
threading_support};
835+
threading_support,
836+
assert_no_exceptions_thrown};
829837

830838
GIVEN("An int_array variable")
831839
{

0 commit comments

Comments
 (0)