Skip to content

Commit b66226e

Browse files
assign_from_json returns code_with_references_listt
This will allow references to be replaced after the all value pairs have been replaced. For instance in the regression test regression/jbmc/deterministic_assignments_json/test_char_array_pass.desc the reference 2 wouldn't have been assigned before the end of the assign_from_json call in which it is referenced for the first time so its allocation size would be non-deterministic but this is fixed by this commit.
1 parent 5cd0c45 commit b66226e

File tree

4 files changed

+51
-27
lines changed

4 files changed

+51
-27
lines changed

jbmc/src/java_bytecode/assignments_from_json.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -902,11 +902,10 @@ code_with_references_listt assign_from_json_rec(
902902
return result;
903903
}
904904

905-
void assign_from_json(
905+
code_with_references_listt assign_from_json(
906906
const exprt &expr,
907907
const jsont &json,
908908
const irep_idt &function_id,
909-
code_blockt &assignments,
910909
symbol_table_baset &symbol_table,
911910
optionalt<ci_lazy_methods_neededt> &needed_lazy_methods,
912911
size_t max_user_array_length,
@@ -930,15 +929,15 @@ void assign_from_json(
930929
location,
931930
max_user_array_length,
932931
class_type};
933-
code_blockt body;
934-
code_with_referencest::reference_substitutiont reference_substitution =
935-
[&](const std::string &reference_id) -> object_creation_referencet & {
936-
auto it = references.find(reference_id);
937-
INVARIANT(it != references.end(), "reference id must be present in map");
938-
return it->second;
939-
};
940-
const auto code_with_references = assign_from_json_rec(expr, json, {}, info);
932+
code_with_references_listt code_with_references =
933+
assign_from_json_rec(expr, json, {}, info);
934+
code_blockt assignments;
941935
allocate.declare_created_symbols(assignments);
942-
for(const auto &code_with_ref : code_with_references.list)
943-
assignments.append(code_with_ref->to_code(reference_substitution));
936+
std::for_each(
937+
assignments.statements().rbegin(),
938+
assignments.statements().rend(),
939+
[&](const codet &c) {
940+
code_with_references.add_to_front(code_without_referencest{c});
941+
});
942+
return code_with_references;
944943
}

jbmc/src/java_bytecode/assignments_from_json.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,10 @@ class ci_lazy_methods_neededt;
9696
/// a function, not a line number.
9797
///
9898
/// For parameter documentation, see \ref object_creation_infot.
99-
void assign_from_json(
99+
code_with_references_listt assign_from_json(
100100
const exprt &expr,
101101
const jsont &json,
102102
const irep_idt &function_id,
103-
code_blockt &block,
104103
symbol_table_baset &symbol_table,
105104
optionalt<ci_lazy_methods_neededt> &needed_lazy_methods,
106105
size_t max_user_array_length,

jbmc/src/java_bytecode/java_static_initializers.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -822,19 +822,27 @@ code_blockt get_user_specified_clinit_body(
822822
}
823823
}
824824
}
825-
code_blockt body;
825+
code_with_references_listt code_with_references;
826826
for(const auto &value_pair : static_field_values)
827827
{
828-
assign_from_json(
828+
code_with_references.append(assign_from_json(
829829
value_pair.first,
830830
value_pair.second,
831831
real_clinit_name,
832-
body,
833832
symbol_table,
834833
needed_lazy_methods,
835834
max_user_array_length,
836-
references);
835+
references));
837836
}
837+
code_with_referencest::reference_substitutiont reference_substitution =
838+
[&](const std::string &reference_id) -> object_creation_referencet & {
839+
auto it = references.find(reference_id);
840+
INVARIANT(it != references.end(), "reference id must be present in map");
841+
return it->second;
842+
};
843+
code_blockt body;
844+
for(const auto &code_with_ref : code_with_references.list)
845+
body.append(code_with_ref->to_code(reference_substitution));
838846
return body;
839847
}
840848
return code_blockt{{code_function_callt{clinit_func->symbol_expr()}}};

jbmc/unit/java_bytecode/java_static_initializers/assignments_from_json.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,23 @@ SCENARIO(
8989

9090
const reference_typet test_class_type =
9191
reference_type(struct_tag_typet{"java::TestClass"});
92-
code_blockt block;
9392
optionalt<ci_lazy_methods_neededt> option{};
94-
assign_from_json(
93+
const code_with_references_listt code = assign_from_json(
9594
symbol_exprt{"symbol_to_assign", test_class_type},
9695
json,
9796
clinit_name,
98-
block,
9997
symbol_table,
10098
option,
10199
max_user_array_length,
102100
references);
101+
102+
code_with_referencest::reference_substitutiont reference_substitution =
103+
[&](const std::string &reference_id) -> object_creation_referencet & {
104+
UNREACHABLE;
105+
};
106+
code_blockt block;
107+
for(auto code_with_references : code.list)
108+
block.append(code_with_references->to_code(reference_substitution));
103109
THEN("The instruction is the declaration of a symbol of TestClass* type")
104110
{
105111
const symbol_exprt declared_symbol =
@@ -175,18 +181,24 @@ SCENARIO(
175181

176182
const reference_typet test_class_type =
177183
reference_type(struct_tag_typet{"java::TestClass"});
178-
code_blockt block;
179184
optionalt<ci_lazy_methods_neededt> option{};
180-
assign_from_json(
185+
const code_with_references_listt code = assign_from_json(
181186
symbol_exprt{"symbol_to_assign", test_class_type},
182187
json,
183188
clinit_name,
184-
block,
185189
symbol_table,
186190
option,
187191
max_user_array_length,
188192
references);
189193

194+
code_with_referencest::reference_substitutiont reference_substitution =
195+
[&](const std::string &reference_id) -> object_creation_referencet & {
196+
UNREACHABLE;
197+
};
198+
code_blockt block;
199+
for(auto code_with_references : code.list)
200+
block.append(code_with_references->to_code(reference_substitution));
201+
190202
THEN("The instruction is the declaration of a symbol of TestClass* type")
191203
{
192204
const symbol_exprt allocation_symbol =
@@ -294,18 +306,24 @@ SCENARIO(
294306

295307
const reference_typet test_class_type =
296308
reference_type(struct_tag_typet{"java::TestClass"});
297-
code_blockt block;
298309
optionalt<ci_lazy_methods_neededt> option{};
299-
assign_from_json(
310+
const code_with_references_listt code = assign_from_json(
300311
symbol_exprt{"symbol_to_assign", test_class_type},
301312
json,
302313
clinit_name,
303-
block,
304314
symbol_table,
305315
option,
306316
max_user_array_length,
307317
references);
308318

319+
code_with_referencest::reference_substitutiont reference_substitution =
320+
[&](const std::string &reference_id) -> object_creation_referencet & {
321+
UNREACHABLE;
322+
};
323+
code_blockt block;
324+
for(auto code_with_references : code.list)
325+
block.append(code_with_references->to_code(reference_substitution));
326+
309327
THEN("The instruction is the declaration of a symbol of TestClass* type")
310328
{
311329
const symbol_exprt allocation_symbol =

0 commit comments

Comments
 (0)