Skip to content

Commit 2e83ec9

Browse files
committed
Zero-initialize Class literals before calling initializer function
This (a) sets the class-identifier to "java.lang.Class," which wasn't being done before, and allows the class initializer to assume fields are nulled before entry, as for a normal constructor.
1 parent e54bba2 commit 2e83ec9

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed
383 Bytes
Binary file not shown.

jbmc/regression/jbmc/class-literals/Test.java

+17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,22 @@ public class Test {
33

44
public static void main() {
55

6+
// First check that all `.class` literals are indeed java.lang.Class
7+
// instances:
8+
assert ExampleAnnotation.class instanceof Class;
9+
assert ExampleInterface.class instanceof Class;
10+
assert ExampleEnum.class instanceof Class;
11+
assert ExampleSynthetic.class instanceof Class;
12+
assert char[].class instanceof Class;
13+
assert short[].class instanceof Class;
14+
assert int[].class instanceof Class;
15+
assert long[].class instanceof Class;
16+
assert float[].class instanceof Class;
17+
assert double[].class instanceof Class;
18+
assert boolean[].class instanceof Class;
19+
assert Object[].class instanceof Class;
20+
assert Object[][].class instanceof Class;
21+
622
assert ExampleAnnotation.class.isAnnotation();
723
assert ExampleInterface.class.isInterface();
824
assert ExampleEnum.class.isEnum();
@@ -29,6 +45,7 @@ public static void main() {
2945
assert ExampleAnnotation.class.getName() == "ExampleAnnotation";
3046
assert ExampleInterface.class.getName() == "ExampleInterface";
3147
assert ExampleEnum.class.getName() == "ExampleEnum";
48+
assert ExampleSynthetic.class.getName() == "ExampleSynthetic";
3249

3350
}
3451

jbmc/src/java_bytecode/java_entry_point.cpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ Author: Daniel Kroening, [email protected]
99
#include "java_entry_point.h"
1010

1111
#include <util/config.h>
12+
#include <util/expr_initializer.h>
1213
#include <util/string_constant.h>
1314
#include <util/suffix.h>
1415

16+
#include <goto-programs/class_identifier.h>
1517
#include <goto-programs/goto_functions.h>
1618

1719
#include <linking/static_lifetime_init.h>
@@ -117,7 +119,8 @@ static void java_static_lifetime_init(
117119
bool assume_init_pointers_not_null,
118120
const object_factory_parameterst &object_factory_parameters,
119121
const select_pointer_typet &pointer_type_selector,
120-
bool string_refinement_enabled)
122+
bool string_refinement_enabled,
123+
message_handlert &message_handler)
121124
{
122125
symbolt &initialize_symbol=*symbol_table.get_writeable(INITIALIZE_FUNCTION);
123126
code_blockt &code_block=to_code_block(to_code(initialize_symbol.value));
@@ -188,6 +191,19 @@ static void java_static_lifetime_init(
188191
args.push_back(
189192
constant_bool(class_symbol.type.get_bool(ID_enumeration)));
190193

194+
// First initialize the object as prior to a constructor:
195+
namespacet ns(symbol_table);
196+
197+
exprt zero_object =
198+
zero_initializer(
199+
sym.type, source_locationt(), ns, message_handler);
200+
set_class_identifier(
201+
to_struct_expr(zero_object), ns, to_symbol_type(sym.type));
202+
203+
code_block.copy_to_operands(
204+
code_assignt(sym.symbol_expr(), zero_object));
205+
206+
// Then call the init function:
191207
code_block.move_to_operands(initializer_call);
192208
}
193209
else if(sym.value.is_nil() && sym.type!=empty_typet())
@@ -530,7 +546,8 @@ bool java_entry_point(
530546
assume_init_pointers_not_null,
531547
object_factory_parameters,
532548
pointer_type_selector,
533-
string_refinement_enabled);
549+
string_refinement_enabled,
550+
message_handler);
534551

535552
return generate_java_start_function(
536553
symbol,

0 commit comments

Comments
 (0)