Skip to content

Commit 591aea0

Browse files
authored
Merge pull request #1193 from smowton/smowton/fix/always_initialise_exception_object
Always allocate an exception object at throw site
2 parents 3292a93 + b4262f3 commit 591aea0

File tree

4 files changed

+63
-29
lines changed

4 files changed

+63
-29
lines changed
445 Bytes
Binary file not shown.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
test.class
3+
--function test.f --java-throw-runtime-exceptions
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
VERIFICATION SUCCESSFUL
7+
--
8+
reference is null in .*: FAILURE
9+
--
10+
This checks that the second use of a particular exception type in a given function is correctly initialised.
11+
In the failing case the #exception_value variable is nondet at the time it is thrown, so cbmc can set it to null and fail an assertion.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
public class test {
2+
3+
int field;
4+
5+
public static void f() {
6+
7+
test testinstance = new test();
8+
test testnull = null;
9+
int x = 0;
10+
try {
11+
x = testinstance.field;
12+
}
13+
catch(NullPointerException e) {
14+
x++;
15+
}
16+
try {
17+
x = testnull.field;
18+
}
19+
catch(NullPointerException e) {
20+
x++;
21+
}
22+
}
23+
24+
}

src/java_bytecode/java_bytecode_instrument.cpp

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Date: June 2017
99
\*******************************************************************/
1010

1111
#include <util/arith_tools.h>
12+
#include <util/fresh_symbol.h>
1213
#include <util/std_code.h>
1314
#include <util/std_expr.h>
1415
#include <util/symbol_table.h>
@@ -18,7 +19,6 @@ Date: June 2017
1819
#include "java_bytecode_convert_class.h"
1920
#include "java_bytecode_instrument.h"
2021
#include "java_entry_point.h"
21-
#include "java_object_factory.h"
2222
#include "java_root_class.h"
2323
#include "java_types.h"
2424
#include "java_utils.h"
@@ -90,47 +90,46 @@ codet java_bytecode_instrumentt::throw_exception(
9090
const source_locationt &original_loc,
9191
const irep_idt &exc_name)
9292
{
93-
exprt exc;
94-
code_blockt init_code;
95-
const irep_idt &exc_obj_name=
96-
id2string(goto_functionst::entry_point())+
97-
"::"+id2string(exc_name);
93+
irep_idt exc_class_name("java::"+id2string(exc_name));
9894

99-
if(!symbol_table.has_symbol(exc_obj_name))
95+
if(!symbol_table.has_symbol(exc_class_name))
10096
{
10197
generate_class_stub(
10298
exc_name,
10399
symbol_table,
104100
get_message_handler());
105-
const symbolt &exc_symbol=symbol_table.lookup(
106-
"java::"+id2string(exc_name));
107-
108-
// create the exception object
109-
exc=object_factory(
110-
pointer_typet(exc_symbol.type),
111-
exc_name,
112-
init_code,
113-
false,
114-
symbol_table,
115-
max_array_length,
116-
allocation_typet::LOCAL,
117-
original_loc);
118101
}
119-
else
120-
exc=symbol_table.lookup(exc_obj_name).symbol_expr();
102+
103+
pointer_typet exc_ptr_type;
104+
exc_ptr_type.subtype()=symbol_typet(exc_class_name);
105+
106+
// Allocate and throw an instance of the exception class:
107+
108+
symbolt &new_symbol=
109+
get_fresh_aux_symbol(
110+
exc_ptr_type,
111+
"new_exception",
112+
"new_exception",
113+
original_loc,
114+
ID_java,
115+
symbol_table);
116+
117+
side_effect_exprt new_instance(ID_java_new, exc_ptr_type);
118+
code_assignt assign_new(new_symbol.symbol_expr(), new_instance);
121119

122120
side_effect_expr_throwt throw_expr;
123-
throw_expr.add_source_location()=original_loc;
124-
throw_expr.move_to_operands(exc);
121+
throw_expr.copy_to_operands(new_symbol.symbol_expr());
122+
123+
code_blockt throw_code;
124+
throw_code.move_to_operands(assign_new);
125+
throw_code.copy_to_operands(code_expressiont(throw_expr));
125126

126127
code_ifthenelset if_code;
127128
if_code.add_source_location()=original_loc;
128129
if_code.cond()=cond;
129-
if_code.then_case()=code_expressiont(throw_expr);
130-
131-
init_code.move_to_operands(if_code);
130+
if_code.then_case()=throw_code;
132131

133-
return init_code;
132+
return if_code;
134133
}
135134

136135
/// Checks whether the array access array_struct[idx] is out-of-bounds,
@@ -209,7 +208,7 @@ codet java_bytecode_instrumentt::check_class_cast(
209208
throw_exception(
210209
not_exprt(class_cast_check),
211210
original_loc,
212-
"ClassCastException");
211+
"java.lang.ClassCastException");
213212
}
214213
else
215214
{

0 commit comments

Comments
 (0)