Skip to content

Commit 22e3710

Browse files
committed
CI lazy methods: load clinit for all param types
We load static initializers for all types of parameters of the entry function(s). This is necessary for the new nondet-initialization of enums, and also consistent with the Java language specification, which says that static initializers should be run on object initialization.
1 parent dbc786d commit 22e3710

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

jbmc/src/java_bytecode/ci_lazy_methods.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ void ci_lazy_methodst::initialize_instantiated_classes(
382382
if(param.type().id()==ID_pointer)
383383
{
384384
const pointer_typet &original_pointer=to_pointer_type(param.type());
385+
add_clinit_call_for_pointer_type(
386+
original_pointer, ns.get_symbol_table(), needed_lazy_methods);
385387
needed_lazy_methods.add_all_needed_classes(original_pointer);
386388
}
387389
}
@@ -399,6 +401,29 @@ void ci_lazy_methodst::initialize_instantiated_classes(
399401
needed_lazy_methods.add_needed_class("java::" + id2string(id));
400402
}
401403

404+
/// Helper function for `initialize_instantiated_classes`.
405+
/// For a given pointer_typet that is being noted as needed in
406+
/// `needed_lazy_methods`, notes that its static initializer is also needed.
407+
/// This applies the same logic to the class of `pointer_type` that
408+
/// `java_bytecode_convert_methodt::get_clinit_call` applies e.g. to classes
409+
/// whose constructor we call in a method body. This duplication is unavoidable
410+
/// due to the fact that ci_lazy_methods essentially has to go through the same
411+
/// logic as __CPROVER_start in its initial setup.
412+
/// \param pointer_type: The given pointer_typet
413+
/// \param symbol_table: Used to look up occurrences of static initializers
414+
/// \param [out] needed_lazy_methods: Gets notified of any static initializers
415+
/// that need to be loaded
416+
void ci_lazy_methodst::add_clinit_call_for_pointer_type(
417+
const pointer_typet &pointer_type,
418+
const symbol_tablet &symbol_table,
419+
ci_lazy_methods_neededt &needed_lazy_methods)
420+
{
421+
const irep_idt &pointer_id =
422+
to_symbol_type(pointer_type.subtype()).get_identifier();
423+
const irep_idt &clinit_wrapper = clinit_wrapper_name(pointer_id);
424+
if(symbol_table.symbols.count(clinit_wrapper))
425+
needed_lazy_methods.add_needed_method(clinit_wrapper);
426+
}
402427

403428
/// Get places where virtual functions are called.
404429
/// \param e: expression tree to search

jbmc/src/java_bytecode/ci_lazy_methods.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ class ci_lazy_methodst:public messaget
120120
const namespacet &ns,
121121
ci_lazy_methods_neededt &needed_lazy_methods);
122122

123+
void add_clinit_call_for_pointer_type(
124+
const pointer_typet &pointer_type,
125+
const symbol_tablet &symbol_table,
126+
ci_lazy_methods_neededt &needed_lazy_methods);
127+
123128
void gather_virtual_callsites(
124129
const exprt &e,
125130
std::unordered_set<exprt, irep_hash> &result);

0 commit comments

Comments
 (0)