Skip to content

Commit 9171c86

Browse files
Merge pull request diffblue#5117 from romainbrenguier/experiment/never-throw
[TG-9400][UFC] Add an assume-no-exceptions-thrown option
2 parents 2af983d + b433f5c commit 9171c86

15 files changed

+305
-125
lines changed
Binary file not shown.
Binary file not shown.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class MyException extends Exception {}
2+
3+
public class Test {
4+
public static int mayThrow(char branch) throws Throwable {
5+
if (branch == 'n') {
6+
throw new NullPointerException();
7+
} else if (branch == 'c') {
8+
throw new MyException();
9+
} else if (branch == 't') {
10+
throw new Throwable();
11+
} else if (branch == 'r') {
12+
return 2;
13+
} else {
14+
return 1;
15+
}
16+
}
17+
18+
public static void check(char branch) {
19+
try {
20+
int i = mayThrow(branch);
21+
if (i == 2)
22+
assert false;
23+
if (i == 1)
24+
assert false;
25+
} catch (MyException e) {
26+
assert false;
27+
} catch (NullPointerException e) {
28+
assert false;
29+
} catch (Throwable e) {
30+
assert false;
31+
}
32+
}
33+
}
Binary file not shown.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
public class Thrower {
2+
public static void test(Integer t) {
3+
String ret = "";
4+
if (t != null)
5+
try {
6+
switch (t) {
7+
case 1:
8+
ret = "CCE";
9+
Object o = new Integer(0);
10+
String x = ((String) o);
11+
break;
12+
13+
case 2:
14+
ret = "AIOBE";
15+
int[] xs = new int[3];
16+
t = xs[5];
17+
18+
case 3:
19+
ret = "AE";
20+
t = 5 / 0;
21+
22+
case 4:
23+
ret = "NASE";
24+
Integer[] arr = new Integer[-7];
25+
26+
case 5:
27+
ret = "NPE";
28+
String str = null;
29+
str.toLowerCase();
30+
31+
default:
32+
break;
33+
}
34+
} catch (ClassCastException | NegativeArraySizeException
35+
| NullPointerException | ArithmeticException
36+
| ArrayIndexOutOfBoundsException e3) {
37+
38+
if (e3 instanceof ClassCastException)
39+
assert ret.equals("CCE");
40+
41+
if (e3 instanceof NegativeArraySizeException)
42+
assert ret.equals("NASE");
43+
44+
if (e3 instanceof NullPointerException)
45+
assert ret.equals("NPE");
46+
47+
if (e3 instanceof ArithmeticException)
48+
assert ret.equals("AE");
49+
50+
if (e3 instanceof ArrayIndexOutOfBoundsException)
51+
assert ret.equals("AIOBE");
52+
}
53+
}
54+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
Thrower.class
3+
--function Thrower.test --assert-no-exceptions-thrown --throw-runtime-exceptions
4+
line 39 assertion at file Thrower.java line 39 .*: FAILURE
5+
line 42 assertion at file Thrower.java line 42 .*: FAILURE
6+
line 45 assertion at file Thrower.java line 45 .*: FAILURE
7+
line 48 assertion at file Thrower.java line 48 .*: FAILURE
8+
line 51 assertion at file Thrower.java line 51 .*: FAILURE
9+
^EXIT=10$
10+
^SIGNAL=0$
11+
--
12+
--
13+
Checks that the runtime exceptions still throw with `--throw-runtime-exceptions`
14+
even when `--assert-no-exceptions-thrown` is specified.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
Test.class
3+
--function Test.check
4+
line 22 assertion at file Test.java line 22 .*: FAILURE
5+
line 24 assertion at file Test.java line 24 .*: FAILURE
6+
line 26 assertion at file Test.java line 26 .*: FAILURE
7+
line 28 assertion at file Test.java line 28 .*: FAILURE
8+
line 30 assertion at file Test.java line 30 .*: FAILURE
9+
^EXIT=10$
10+
^SIGNAL=0$
11+
--
12+
--
13+
Checks that we get the expected behaviour when --assert-no-exceptions-thrown is
14+
not used. This is to make sure that test.desc is actually testing what we wanted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CORE
2+
Test.class
3+
--function Test.check --assert-no-exceptions-thrown
4+
line 6 assertion at file Test.java line 6 .*: FAILURE
5+
line 8 assertion at file Test.java line 8 .*: FAILURE
6+
line 10 assertion at file Test.java line 10 .*: FAILURE
7+
line 22 assertion at file Test.java line 22 .*: FAILURE
8+
line 24 assertion at file Test.java line 24 .*: FAILURE
9+
line 26 assertion at file Test.java line 26 .*: SUCCESS
10+
line 28 assertion at file Test.java line 28 .*: SUCCESS
11+
line 30 assertion at file Test.java line 30 .*: SUCCESS
12+
^EXIT=10$
13+
^SIGNAL=0$
14+
--
15+
--
16+
Checks that the `throw` instructions have been replaced by assertions, which
17+
are failing here because they are reachable, and assumptions which prevent
18+
the last three assertions from failing.

jbmc/src/java_bytecode/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -666,12 +666,12 @@ and the methods in them. The methods, along with their parsed representation
666666
\ref java_bytecode_languaget::method_bytecode via a reference held in
667667
\ref java_bytecode_convert_classt::method_bytecode. typecheck then performs a
668668
switch over the value of
669-
[lazy_methods_mode](\ref java_bytecode_languaget::lazy_methods_mode) to
669+
[lazy_methods_mode](\ref java_bytecode_language_optionst::lazy_methods_mode) to
670670
determine which loading strategy to use.
671671

672672
\subsection eager-loading Eager loading
673673

674-
If [lazy_methods_mode](\ref java_bytecode_languaget::lazy_methods_mode) is
674+
If [lazy_methods_mode](\ref java_bytecode_language_optionst::lazy_methods_mode) is
675675
\ref java_bytecode_languaget::LAZY_METHODS_MODE_EAGER then eager loading is
676676
used. Under eager loading
677677
\ref java_bytecode_languaget::convert_single_method(const irep_idt &, symbol_table_baset &, lazy_class_to_declared_symbols_mapt &)
@@ -695,7 +695,7 @@ method parameters) and function references (at function call sites) to
695695
locate further classes and methods to load. The following paragraph describes
696696
the mechanism used.
697697

698-
If [lazy_methods_mode](\ref java_bytecode_languaget::lazy_methods_mode) is
698+
If [lazy_methods_mode](\ref java_bytecode_language_optionst::lazy_methods_mode) is
699699
\ref lazy_methods_modet::LAZY_METHODS_MODE_CONTEXT_INSENSITIVE then
700700
context-insensitive lazy loading is used. Under this stragegy
701701
\ref java_bytecode_languaget::do_ci_lazy_method_conversion is called to do all

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

0 commit comments

Comments
 (0)