Skip to content

Commit 18da0b1

Browse files
Merge pull request #4455 from thomasspriggs/tas/id_c_class
Standardise interface for accessing the owner of a symbol
2 parents b0086f1 + 65e3d31 commit 18da0b1

13 files changed

+256
-65
lines changed

jbmc/src/java_bytecode/java_bytecode_convert_class.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -689,10 +689,9 @@ void java_bytecode_convert_classt::convert(
689689
new_symbol.name=id2string(class_symbol.name)+"."+id2string(f.name);
690690
new_symbol.base_name=f.name;
691691
new_symbol.type=field_type;
692-
// Annotating the type with ID_C_class to provide a static field -> class
693-
// link matches the method used by java_bytecode_convert_method::convert
694-
// for methods.
695-
new_symbol.type.set(ID_C_class, class_symbol.name);
692+
// Provide a static field -> class link, like
693+
// java_bytecode_convert_method::convert does for method -> class.
694+
set_declaring_class(new_symbol, class_symbol.name);
696695
new_symbol.type.set(ID_C_field, f.name);
697696
new_symbol.type.set(ID_C_constant, f.is_final);
698697
new_symbol.pretty_name=id2string(class_symbol.pretty_name)+

jbmc/src/java_bytecode/java_bytecode_convert_method.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,8 @@ void java_bytecode_convert_methodt::convert(
419419
get_method_identifier(class_symbol.name, m);
420420

421421
method_id=method_identifier;
422+
set_declaring_class(
423+
symbol_table.get_writeable_ref(method_identifier), class_symbol.name);
422424

423425
// Obtain a std::vector of java_method_typet::parametert objects from the
424426
// (function) type of the symbol
@@ -428,7 +430,6 @@ void java_bytecode_convert_methodt::convert(
428430
// to the symbol later.
429431
java_method_typet method_type =
430432
to_java_method_type(symbol_table.lookup_ref(method_identifier).type);
431-
method_type.set(ID_C_class, class_symbol.name);
432433
method_type.set_is_final(m.is_final);
433434
method_return_type = method_type.return_type();
434435
java_method_typet::parameterst &parameters = method_type.parameters();
@@ -2206,6 +2207,7 @@ void java_bytecode_convert_methodt::convert_invoke(
22062207
symbol.mode = ID_java;
22072208
assign_parameter_names(
22082209
to_java_method_type(symbol.type), symbol.name, symbol_table);
2210+
set_declaring_class(symbol, arg0.get(ID_C_class));
22092211

22102212
debug() << "Generating codet: new opaque symbol: method '" << symbol.name
22112213
<< "'" << eom;

jbmc/src/java_bytecode/java_bytecode_language.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ static void create_stub_global_symbol(
496496
new_symbol.name = symbol_id;
497497
new_symbol.base_name = symbol_basename;
498498
new_symbol.type = symbol_type;
499-
new_symbol.type.set(ID_C_class, class_id);
499+
set_declaring_class(new_symbol, class_id);
500500
// Public access is a guess; it encourages merging like-typed static fields,
501501
// whereas a more restricted visbility would encourage separating them.
502502
// Neither is correct, as without the class file we can't know the truth.

jbmc/src/java_bytecode/java_enum_static_init_unwind_handler.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Author: Chris Smowton, [email protected]
1010
/// Unwind loops in static initializers
1111

1212
#include "java_enum_static_init_unwind_handler.h"
13+
#include "java_utils.h"
1314

1415
#include <util/invariant.h>
1516
#include <util/suffix.h>
@@ -76,11 +77,10 @@ tvt java_enum_static_init_unwind_handler(
7677
return tvt::unknown();
7778

7879
const symbolt &function_symbol = symbol_table.lookup_ref(enum_function_id);
79-
irep_idt class_id = function_symbol.type.get(ID_C_class);
80-
INVARIANT(
81-
!class_id.empty(), "functions should have their defining class annotated");
80+
const auto class_id = declaring_class(function_symbol);
81+
INVARIANT(class_id, "Java methods should have a defining class.");
8282

83-
const typet &class_type = symbol_table.lookup_ref(class_id).type;
83+
const typet &class_type = symbol_table.lookup_ref(*class_id).type;
8484
size_t unwinds = class_type.get_size_t(ID_java_enum_static_unwind);
8585
if(unwinds != 0 && unwind_count < unwinds)
8686
{

jbmc/src/java_bytecode/java_static_initializers.cpp

+23-31
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ static void clinit_wrapper_do_recursive_calls(
232232
symbol_table.symbols.end(),
233233
[&](const std::pair<irep_idt, symbolt> &symbol) {
234234
if(
235-
symbol.second.type.get(ID_C_class) == class_name &&
235+
declaring_class(symbol.second) == class_name &&
236236
symbol.second.is_static_lifetime &&
237237
!symbol.second.type.get_bool(ID_C_constant))
238238
{
@@ -352,10 +352,9 @@ static void create_clinit_wrapper_symbols(
352352
wrapper_method_symbol.pretty_name = wrapper_method_symbol.name;
353353
wrapper_method_symbol.base_name = "clinit_wrapper";
354354
wrapper_method_symbol.type = wrapper_method_type;
355-
// Note this use of a type-comment to provide a back-link from a method
356-
// to its associated class is the same one used in
357-
// java_bytecode_convert_methodt::convert
358-
wrapper_method_symbol.type.set(ID_C_class, class_name);
355+
// This provides a back-link from a method to its associated class, as is done
356+
// for java_bytecode_convert_methodt::convert.
357+
set_declaring_class(wrapper_method_symbol, class_name);
359358
wrapper_method_symbol.mode = ID_java;
360359
bool failed = symbol_table.add(wrapper_method_symbol);
361360
INVARIANT(!failed, "clinit-wrapper symbol should be fresh");
@@ -453,21 +452,20 @@ code_blockt get_thread_safe_clinit_wrapper_body(
453452
message_handlert &message_handler)
454453
{
455454
const symbolt &wrapper_method_symbol = symbol_table.lookup_ref(function_id);
456-
irep_idt class_name = wrapper_method_symbol.type.get(ID_C_class);
457-
INVARIANT(
458-
!class_name.empty(), "wrapper function should be annotated with its class");
455+
const auto class_name = declaring_class(wrapper_method_symbol);
456+
INVARIANT(class_name, "Wrapper function should have an owning class.");
459457

460458
const symbolt &clinit_state_sym =
461-
symbol_table.lookup_ref(clinit_state_var_name(class_name));
459+
symbol_table.lookup_ref(clinit_state_var_name(*class_name));
462460
const symbolt &clinit_thread_local_state_sym =
463-
symbol_table.lookup_ref(clinit_thread_local_state_var_name(class_name));
461+
symbol_table.lookup_ref(clinit_thread_local_state_var_name(*class_name));
464462

465463
// Create a function-local variable "init_complete". This variable is used to
466464
// avoid inspecting the global state (clinit_state_sym) outside of
467465
// the critical-section.
468466
const symbolt &init_complete = add_new_variable_symbol(
469467
symbol_table,
470-
clinit_local_init_complete_var_name(class_name),
468+
clinit_local_init_complete_var_name(*class_name),
471469
bool_typet(),
472470
nil_exprt(),
473471
true,
@@ -598,7 +596,7 @@ code_blockt get_thread_safe_clinit_wrapper_body(
598596
code_blockt init_body;
599597
clinit_wrapper_do_recursive_calls(
600598
symbol_table,
601-
class_name,
599+
*class_name,
602600
init_body,
603601
nondet_static,
604602
object_factory_parameters,
@@ -666,12 +664,11 @@ code_ifthenelset get_clinit_wrapper_body(
666664
// }
667665
// }
668666
const symbolt &wrapper_method_symbol = symbol_table.lookup_ref(function_id);
669-
irep_idt class_name = wrapper_method_symbol.type.get(ID_C_class);
670-
INVARIANT(
671-
!class_name.empty(), "wrapper function should be annotated with its class");
667+
const auto class_name = declaring_class(wrapper_method_symbol);
668+
INVARIANT(class_name, "Wrapper function should have an owning class.");
672669

673670
const symbolt &already_run_symbol =
674-
symbol_table.lookup_ref(clinit_already_run_variable_name(class_name));
671+
symbol_table.lookup_ref(clinit_already_run_variable_name(*class_name));
675672

676673
equal_exprt check_already_run(
677674
already_run_symbol.symbol_expr(),
@@ -683,7 +680,7 @@ code_ifthenelset get_clinit_wrapper_body(
683680

684681
clinit_wrapper_do_recursive_calls(
685682
symbol_table,
686-
class_name,
683+
*class_name,
687684
init_body,
688685
nondet_static,
689686
object_factory_parameters,
@@ -766,12 +763,9 @@ void stub_global_initializer_factoryt::create_stub_global_initializer_symbols(
766763
continue;
767764
}
768765

769-
const irep_idt class_id =
770-
global_symbol.type.get(ID_C_class);
771-
INVARIANT(
772-
!class_id.empty(),
773-
"static field should be annotated with its defining class");
774-
stub_globals_by_class.insert({class_id, stub_global});
766+
const auto class_id = declaring_class(global_symbol);
767+
INVARIANT(class_id, "Static field should have a defining class.");
768+
stub_globals_by_class.insert({*class_id, stub_global});
775769
}
776770

777771
// For each distinct class that has stub globals, create a clinit symbol:
@@ -799,10 +793,9 @@ void stub_global_initializer_factoryt::create_stub_global_initializer_symbols(
799793
static_init_symbol.base_name = "clinit():V";
800794
static_init_symbol.mode = ID_java;
801795
static_init_symbol.type = thunk_type;
802-
// Note this use of a type-comment to provide a back-link from a method
803-
// to its associated class is the same one used in
804-
// java_bytecode_convert_methodt::convert
805-
static_init_symbol.type.set(ID_C_class, it->first);
796+
// This provides a back-link from a method to its associated class, as is
797+
// done for java_bytecode_convert_methodt::convert.
798+
set_declaring_class(static_init_symbol, it->first);
806799

807800
bool failed = symbol_table.add(static_init_symbol);
808801
INVARIANT(!failed, "symbol should not already exist");
@@ -839,17 +832,16 @@ code_blockt stub_global_initializer_factoryt::get_stub_initializer_body(
839832
message_handlert &message_handler)
840833
{
841834
const symbolt &stub_initializer_symbol = symbol_table.lookup_ref(function_id);
842-
irep_idt class_id = stub_initializer_symbol.type.get(ID_C_class);
835+
const auto class_id = declaring_class(stub_initializer_symbol);
843836
INVARIANT(
844-
!class_id.empty(),
845-
"synthetic static initializer should be annotated with its class");
837+
class_id, "Synthetic static initializer should have an owning class.");
846838
code_blockt static_init_body;
847839

848840
// Add a standard nondet initialisation for each global declared on this
849841
// class. Note this is the same invocation used in
850842
// java_static_lifetime_init.
851843

852-
auto class_globals = stub_globals_by_class.equal_range(class_id);
844+
auto class_globals = stub_globals_by_class.equal_range(*class_id);
853845
INVARIANT(
854846
class_globals.first != class_globals.second,
855847
"class with synthetic clinit should have at least one global to init");

jbmc/src/java_bytecode/java_utils.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -464,3 +464,14 @@ symbolt &fresh_java_symbol(
464464
return get_fresh_aux_symbol(
465465
type, name_prefix, basename_prefix, source_location, ID_java, symbol_table);
466466
}
467+
468+
optionalt<irep_idt> declaring_class(const symbolt &symbol)
469+
{
470+
const irep_idt &class_id = symbol.type.get(ID_C_class);
471+
return class_id.empty() ? optionalt<irep_idt>{} : class_id;
472+
}
473+
474+
void set_declaring_class(symbolt &symbol, const irep_idt &declaring_class)
475+
{
476+
symbol.type.set(ID_C_class, declaring_class);
477+
}

jbmc/src/java_bytecode/java_utils.h

+11
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Author: Daniel Kroening, [email protected]
1414
#include <unordered_set>
1515

1616
#include <util/message.h>
17+
#include <util/optional.h>
1718
#include <util/std_expr.h>
1819
#include <util/symbol_table.h>
1920

@@ -115,4 +116,14 @@ symbolt &fresh_java_symbol(
115116
const irep_idt &function_name,
116117
symbol_table_baset &symbol_table);
117118

119+
/// Gets the identifier of the class which declared a given \p symbol. If the
120+
/// symbol is not declared by a class then an empty optional is returned. This
121+
/// is used for method symbols and static field symbols to link them back to the
122+
/// class which declared them.
123+
optionalt<irep_idt> declaring_class(const symbolt &symbol);
124+
125+
/// Sets the identifier of the class which declared a given \p symbol to \p
126+
/// declaring_class.
127+
void set_declaring_class(symbolt &symbol, const irep_idt &declaring_class);
128+
118129
#endif // CPROVER_JAVA_BYTECODE_JAVA_UTILS_H

jbmc/src/jdiff/java_syntactic_diff.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Author: Peter Schrammel
1212
#include "java_syntactic_diff.h"
1313

1414
#include <goto-programs/goto_model.h>
15+
#include <java_bytecode/java_utils.h>
1516

1617
bool java_syntactic_difft::operator()()
1718
{
@@ -35,16 +36,16 @@ bool java_syntactic_difft::operator()()
3536
CHECK_RETURN(fun1 != nullptr);
3637
const symbolt *fun2 = goto_model2.symbol_table.lookup(it->first);
3738
CHECK_RETURN(fun2 != nullptr);
38-
const irep_idt &class_name = fun1->type.get(ID_C_class);
39+
const optionalt<irep_idt> class_name = declaring_class(*fun1);
3940
bool function_access_changed =
4041
fun1->type.get(ID_access) != fun2->type.get(ID_access);
4142
bool class_access_changed = false;
4243
bool field_access_changed = false;
43-
if(!class_name.empty())
44+
if(class_name)
4445
{
45-
const symbolt *class1 = goto_model1.symbol_table.lookup(class_name);
46+
const symbolt *class1 = goto_model1.symbol_table.lookup(*class_name);
4647
CHECK_RETURN(class1 != nullptr);
47-
const symbolt *class2 = goto_model2.symbol_table.lookup(class_name);
48+
const symbolt *class2 = goto_model2.symbol_table.lookup(*class_name);
4849
CHECK_RETURN(class2 != nullptr);
4950
class_access_changed =
5051
class1->type.get(ID_access) != class2->type.get(ID_access);

0 commit comments

Comments
 (0)