Skip to content

Commit ba86208

Browse files
committed
JBMC: Zero-initialized 'cproverMonitorCount' component and removed
'@lock' field (fixes diffblue#2307) The 'cproverMonitorCount' field is a counter in the 'java.lang.Object' model (part of the java core models library). This field is used to implement a critical section and is thus necessary to support concurrency. This commit makes sure that this field (if present) is always zero initialized as it is not meant to be non-deterministic. This field is present only if the java core models library is loaded. Additionally, the commit removes '@lock' field from root class (usually: 'java.lang.Object') as it has been superseded by a locking mechanism implemented in the java core models library. Modified relevant unit/regression tests to reflect this change.
1 parent 57395af commit ba86208

File tree

10 files changed

+43
-49
lines changed

10 files changed

+43
-49
lines changed

jbmc/regression/jbmc/json_trace2/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ activate-multi-line-match
55
EXIT=0
66
SIGNAL=0
77
"outputID": "return",\n *"sourceLocation": \{\n *"file": "Test\.java",\n *"function": "java::Test\.test:\(Ljava/lang/Object;\)Z",\n *"line": "3"\n *\},\n *"stepType": "output",\n *"thread": 0,\n *"values": \[\n *\{\n *"binary": "00000000",\n *"data": "false",\n *"name": "integer",\n *"type": "boolean",\n *"width": 8
8-
"inputID": "arg1a",\n *"internal": true,\n *"mode": "java",\n *"sourceLocation": \{\n *"file": "Test\.java",\n *"function": "java::Test\.test:\(Ljava/lang/Object;\)Z",\n *"line": "3"\n *\},\n *"stepType": "input",\n *"thread": 0,\n *"values": \[\n *\{\n *"data": "null",\n *"name": "pointer",\n *"type": "struct java\.lang\.Object \{ __CPROVER_string @class_identifier; boolean @lock; \} \*"
8+
"inputID": "arg1a",\n *"internal": true,\n *"mode": "java",\n *"sourceLocation": \{\n *"file": "Test\.java",\n *"function": "java::Test\.test:\(Ljava/lang/Object;\)Z",\n *"line": "3"\n *\},\n *"stepType": "input",\n *"thread": 0,\n *"values": \[\n *\{\n *"data": "null",\n *"name": "pointer",\n *"type": "struct java\.lang\.Object \{ __CPROVER_string @class_identifier; \} \*"
99
--
1010
^warning: ignoring

jbmc/src/java_bytecode/java_object_factory.cpp

+12-5
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ static codet make_allocate_code(const symbol_exprt &lhs, const exprt &size)
536536
/// cprover_associate_length_to_array_func(
537537
/// *string_data_pointer, tmp_object_factory);
538538
/// arg = { [email protected]={
539-
/// .@class_identifier=\"java::java.lang.String\", .@lock=false },
539+
/// .@class_identifier=\"java::java.lang.String\" },
540540
/// .length=tmp_object_factory,
541541
/// .data=*string_data_pointer };
542542
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -570,11 +570,10 @@ codet initialize_nondet_string_struct(
570570
? "java::java.lang.String"
571571
: "java::" + id2string(struct_type.get_tag());
572572

573-
// @lock = false:
574573
const symbol_typet jlo_symbol("java::java.lang.Object");
575574
const struct_typet &jlo_type = to_struct_type(ns.follow(jlo_symbol));
576575
struct_exprt jlo_init(jlo_symbol);
577-
java_root_class_init(jlo_init, jlo_type, false, class_id);
576+
java_root_class_init(jlo_init, jlo_type, class_id);
578577

579578
struct_exprt struct_expr(obj.type());
580579
struct_expr.copy_to_operands(jlo_init);
@@ -1065,9 +1064,17 @@ void java_object_factoryt::gen_nondet_struct_init(
10651064
{
10661065
continue;
10671066
}
1068-
else if(name=="@lock")
1067+
else if(name == "cproverMonitorCount")
10691068
{
1070-
continue;
1069+
// Zero-initialize 'cproverMonitorCount' field as it is not meant to be
1070+
// nondet. This field is only present when the java core models are
1071+
// included in the class-path. It is used to implement a critical section,
1072+
// which is necessary to support concurrency.
1073+
if(update_in_place == update_in_placet::MUST_UPDATE_IN_PLACE)
1074+
continue;
1075+
code_assignt code(me, from_integer(0, me.type()));
1076+
code.add_source_location() = loc;
1077+
assignments.copy_to_operands(code);
10711078
}
10721079
else
10731080
{

jbmc/src/java_bytecode/java_root_class.cpp

+16-28
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,16 @@ Author: Daniel Kroening, [email protected]
1313

1414
#include "java_types.h"
1515

16-
/*******************************************************************
17-
18-
Function: java_root_class
19-
20-
Inputs:
21-
22-
Outputs:
23-
24-
Purpose:
25-
26-
\*******************************************************************/
27-
16+
/// Create components to an object of the root class (usually java.lang.Object)
17+
/// Specifically, we add a new component, '\@class_identifier'. This used
18+
/// primary to replace an expression like 'e instanceof A' with
19+
/// 'e.\@class_identifier == "A"'
20+
/// \param class_symbol: class symbol
2821
void java_root_class(symbolt &class_symbol)
2922
{
3023
struct_typet &struct_type=to_struct_type(class_symbol.type);
3124
struct_typet::componentst &components=struct_type.components();
3225

33-
{
34-
// for monitorenter/monitorexit
35-
struct_typet::componentt component;
36-
component.set_name("@lock");
37-
component.set_pretty_name("@lock");
38-
component.type()=java_boolean_type();
39-
40-
// add at the beginning
41-
components.insert(components.begin(), component);
42-
}
43-
4426
{
4527
// the class identifier is used for stuff such as 'instanceof'
4628
struct_typet::componentt component;
@@ -56,13 +38,11 @@ void java_root_class(symbolt &class_symbol)
5638
/// Adds members for an object of the root class (usually java.lang.Object).
5739
/// \param jlo [out] : object to initialize
5840
/// \param root_type: type of the root class
59-
/// \param lock: lock field
6041
/// \param class_identifier: class identifier field, generally begins with
6142
/// "java::" prefix.
6243
void java_root_class_init(
6344
struct_exprt &jlo,
6445
const struct_typet &root_type,
65-
const bool lock,
6646
const irep_idt &class_identifier)
6747
{
6848
jlo.operands().resize(root_type.components().size());
@@ -72,7 +52,15 @@ void java_root_class_init(
7252
constant_exprt clsid(class_identifier, clsid_type);
7353
jlo.operands()[clsid_nb]=clsid;
7454

75-
const std::size_t lock_nb=root_type.component_number("@lock");
76-
const typet &lock_type=root_type.components()[lock_nb].type();
77-
jlo.operands()[lock_nb]=from_integer(lock, lock_type);
55+
// Check if the 'cproverMonitorCount' component exists and initialize it.
56+
// This field is only present when the java core models are embedded. It is
57+
// used to implement a critical section, which is necessary to support
58+
// concurrency.
59+
if(root_type.has_component("cproverMonitorCount"))
60+
{
61+
const std::size_t count_nb =
62+
root_type.component_number("cproverMonitorCount");
63+
const typet &count_type = root_type.components()[count_nb].type();
64+
jlo.operands()[count_nb] = from_integer(0, count_type);
65+
}
7866
}

jbmc/src/java_bytecode/java_root_class.h

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ void java_root_class(
2121
void java_root_class_init(
2222
struct_exprt &jlo,
2323
const struct_typet &root_type,
24-
bool lock,
2524
const irep_idt &class_identifier);
2625

2726
#endif // CPROVER_JAVA_BYTECODE_JAVA_ROOT_CLASS_H

jbmc/src/java_bytecode/java_string_library_preprocess.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -840,12 +840,12 @@ codet java_string_library_preprocesst::code_assign_components_to_java_string(
840840
PRECONDITION(implements_java_char_sequence_pointer(lhs.type()));
841841
dereference_exprt deref=checked_dereference(lhs, lhs.type().subtype());
842842

843-
// A String has a field Object with @clsid = String and @lock = false:
843+
// A String has a field Object with @clsid = String
844844
const symbolt &jlo_symbol=*symbol_table.lookup("java::java.lang.Object");
845845
const struct_typet &jlo_struct=to_struct_type(jlo_symbol.type);
846846
struct_exprt jlo_init(jlo_struct);
847847
irep_idt clsid = get_tag(lhs.type().subtype());
848-
java_root_class_init(jlo_init, jlo_struct, false, clsid);
848+
java_root_class_init(jlo_init, jlo_struct, clsid);
849849

850850
struct_exprt struct_rhs(deref.type());
851851
struct_rhs.copy_to_operands(jlo_init);

jbmc/src/java_bytecode/java_string_literals.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,12 @@ symbol_exprt get_or_create_string_literal_symbol(
9494
namespacet ns(symbol_table);
9595

9696
// Regardless of string refinement setting, at least initialize
97-
// the literal with @clsid = String and @lock = false:
97+
// the literal with @clsid = String
9898
symbol_typet jlo_symbol("java::java.lang.Object");
9999
const auto &jlo_struct = to_struct_type(ns.follow(jlo_symbol));
100100
struct_exprt jlo_init(jlo_symbol);
101101
const auto &jls_struct = to_struct_type(ns.follow(string_type));
102-
java_root_class_init(jlo_init, jlo_struct, false, "java::java.lang.String");
102+
java_root_class_init(jlo_init, jlo_struct, "java::java.lang.String");
103103

104104
// If string refinement *is* around, populate the actual
105105
// contents as well:
@@ -197,7 +197,7 @@ symbol_exprt get_or_create_string_literal_symbol(
197197
else if(jls_struct.get_bool(ID_incomplete_class))
198198
{
199199
// Case where java.lang.String was stubbed, and so directly defines
200-
// @class_identifier and @lock:
200+
// @class_identifier
201201
new_symbol.value = jlo_init;
202202
}
203203

jbmc/unit/java-testing-utils/require_goto_statements.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,8 @@ const irep_idt &require_goto_statements::require_struct_component_assignment(
355355
// After we have found the declaration of the final assignment's
356356
// right hand side, then we want to identify that the type
357357
// is the one we expect, e.g.:
358-
// struct java.lang.Integer { __CPROVER_string @class_identifier;
359-
// boolean @lock; } tmp_object_factory$2;
358+
// struct java.lang.Integer { __CPROVER_string @class_identifier; }
359+
// tmp_object_factory$2;
360360
const auto &component_declaration =
361361
require_goto_statements::require_declaration_of_name(
362362
component_tmp_name, entry_point_instructions);

jbmc/unit/java_bytecode/goto_program_generics/generic_bases_test.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ SCENARIO(
5050
5151
// (struct java.lang.Object *) tmp_object_factory$2;
5252
// tmp_object_factory$2 = &tmp_object_factory$3;
53-
// struct java.lang.Integer { __CPROVER_string @class_identifier;
54-
// boolean @lock; } tmp_object_factory$3;
53+
// struct java.lang.Integer { __CPROVER_string @class_identifier; }
54+
// tmp_object_factory$3;
5555
require_goto_statements::require_struct_component_assignment(
5656
this_tmp_name,
5757
{"Wrapper"},
@@ -455,8 +455,8 @@ SCENARIO(
455455
{
456456
457457
// &tmp_object_factory$2;
458-
// struct java.lang.Object { __CPROVER_string @class_identifier;
459-
// boolean @lock; } tmp_object_factory$2;
458+
// struct java.lang.Object { __CPROVER_string @class_identifier; }
459+
// tmp_object_factory$2;
460460
require_goto_statements::require_struct_component_assignment(
461461
this_tmp_name,
462462
{"UnsupportedWrapper1"},

jbmc/unit/java_bytecode/goto_program_generics/generic_parameters_test.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,8 @@ SCENARIO(
544544
THEN("Object 'f' has unspecialized field 'field'")
545545
{
546546
// tmp_object_factory$2.field = &tmp_object_factory$3;
547-
// struct java.lang.Object { __CPROVER_string @class_identifier;
548-
// boolean @lock; } tmp_object_factory$3;
547+
// struct java.lang.Object { __CPROVER_string @class_identifier; }
548+
// tmp_object_factory$3;
549549
require_goto_statements::require_struct_component_assignment(
550550
field_input_name,
551551
{},

jbmc/unit/java_bytecode/java_object_factory/gen_nondet_string_init.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ SCENARIO(
8383
"return_array = cprover_associate_length_to_array_func"
8484
"(*string_data_pointer, tmp_object_factory);",
8585
"arg = { [email protected]={ .@class_identifier"
86-
"=\"java::java.lang.String\", .@lock=false },"
86+
"=\"java::java.lang.String\" },"
8787
" .length=tmp_object_factory, "
8888
".data=*string_data_pointer };"};
8989

0 commit comments

Comments
 (0)