1/*******************************************************************\
5Author: Daniel Kroening, kroening@kroening.com
7\*******************************************************************/
33 #define JAVA_MAIN_METHOD "main:([Ljava/lang/String;)V"
41 const std::vector<exprt> &arguments,
50 // If __CPROVER_initialize already exists, replace it. It may already exist
51 // if a GOTO binary provided it. This behaviour mirrors the ANSI-C frontend.
58 symbol_table.
add(initialize);
66 sym.is_static_lifetime &&
69 // Consider some sort of annotation indicating a global variable that
70 // doesn't require initialisation?
80 "java::java.lang.Class.cproverInitializeClassLiteral:"
81 "(Ljava/lang/String;ZZZZZZZ)V";
116 bool string_refinement_enabled,
138 string_refinement_enabled);
140 // If that created any new symbols make sure we initialise those too:
143 // Call the literal initializer method instead of a nondet initializer:
145 // For arguments we can't parse yet:
150 // Argument order is: name, isAnnotation, isArray, isInterface,
151 // isSynthetic, isLocalClass, isMemberClass, isEnum
156 address_of_exprt(sym.symbol_expr()),
158 address_of_exprt(class_name_literal),
160 constant_bool(java_class_type.get_is_annotation()),
162 constant_bool(class_is_array),
164 constant_bool(java_class_type.get_interface()),
166 constant_bool(java_class_type.get_synthetic()),
172 constant_bool(java_class_type.get_is_enumeration())});
174 // First initialize the object as prior to a constructor:
181 message.
error() <<
"failed to zero-initialize " <<
sym.name
191 // Then call the init function:
213 pointer_type_selector,
217 else if(
sym.value.is_not_nil())
233 bool string_refinement_enabled,
248 // If there are strings given using --string-input-value, we need to add
249 // them to the symbol table now, so that they appear in __CPROVER_initialize
250 // and we can refer to them later when we initialize input values.
253 // We ignore the return value of the following call, we just need to
254 // make sure the string is in the symbol table.
256 val, symbol_table, string_refinement_enabled);
259 // We need to zero out all static variables, or nondet-initialize if they're
260 // external. Iterate over a copy of the symtab, as its iterators are
261 // invalidated by object_factory:
263 // sort alphabetically for reproducible results
265 for(
const auto &entry : symbol_table.
symbols)
285 object_factory_parameters,
286 pointer_type_selector,
287 string_refinement_enabled,
310 // checks whether the function is static and has a single String[] parameter
311 bool is_static = !function_type.
has_this();
312 // this should be implied by the signature
315 parameters.size() == 1 &&
336 // certain method arguments cannot be allowed to be null, we set the following
337 // variable to true iff the method under test is the "main" method, which will
338 // be called (by the jvm) with arguments that are never null
341 // we iterate through all the parameters of the function under test, allocate
342 // an object for that parameter (recursively allocating other objects
343 // necessary to initialize it), and mark such object using `code_inputt`.
352 // true iff this parameter is the `this` pointer of the method, which cannot
374 object_factory_parameters;
375 // only pointer must be non-null
378 // in main() also the array elements of the argument must be non-null
386 // Generate code to allocate and non-deterministicaly initialize the
387 // argument, if the argument has different possible object types (e.g., from
388 // casts in the function body), then choose one in a non-deterministic way.
402 pointer_type_selector,
408 // create a non-deterministic switch between all possible values for the
409 // type of the parameter.
411 // the idea is to get a new symbol for the parameter value `tmp`
413 // then add a non-deterministic switch over all possible input types,
414 // construct the object type at hand and assign to `tmp`
419 // tmp_expr = object_factory(...)
424 // method(..., param, ...)
435 std::vector<codet> cases;
449 pointer_type_selector,
467 // record as an input
512 const std::vector<exprt> &arguments,
539 // retrieve the exception variable
543 // record exceptional return variable as output
572 "resolve_friendly_method_name should return a symbol-table identifier");
574 return *symbol;
// Return found function
578 // are we given a main class?
579 if(main_class.
empty())
581 // no, but we allow this situation to output symbol table,
582 // goto functions, etc
590 // has the class a correct main method?
593 // no, but we allow this situation to output symbol table,
594 // goto functions, etc
607 bool assert_uncaught_exceptions,
610 bool string_refinement_enabled,
613 // check if the entry point is already there
616 return false;
// silently ignore
621 if(!
res.is_success())
631 assert_uncaught_exceptions,
632 object_factory_parameters,
633 pointer_type_selector,
641 bool assert_uncaught_exceptions,
649 // build call to initialization function
651 symbol_table_baset::symbolst::const_iterator
init_it =
658 return true;
// give up with error
667 // build call to the main method, of the form
668 // return = main_method(arg1, arg2, ..., argn)
669 // where return is a new variable
670 // and arg1 ... argn are constructed below as well
681 // if the method return type is not void, store return value in a new variable
696 // add the exceptional return value
704 // Zero-initialise the top-level exception catch variable:
709 // create code that allocates the objects used as test arguments and
710 // non-deterministically initializes them
716 // Create target labels for the toplevel exception handler:
722 // Push a universal exception handler:
723 // Catch all exceptions:
724 // This is equivalent to catching Throwable, but also works if some of
725 // the class hierarchy is missing so that we can't determine that
726 // the thrown instance is an indirect child of Throwable
734 // we insert the call to the method AFTER the argument initialization code
742 // Normal return: skip the exception handler:
745 // Exceptional return: catch and assign to exc_symbol.
750 // Converge normal and exceptional return:
753 // Mark return value, pointer type parameters and the exception as outputs.
757 // add uncaught-exception check if requested
758 if(assert_uncaught_exceptions)
764 // create a symbol for the __CPROVER__start function, associate the code that
765 // we just built and register it in the symbol table
773 if(!symbol_table.
insert(std::move(new_symbol)).second)
irep_idt rounding_mode_identifier()
Return the identifier of the program symbol used to store the current rounding mode.
@ DYNAMIC
Allocate dynamic objects (using ALLOCATE)
@ STATIC_GLOBAL
Allocate global objects with static lifetime.
static symbolt result_symbol(const irep_idt &identifier, const typet &type, const source_locationt &source_location, symbol_table_baset &symbol_table)
void set_class_identifier(struct_exprt &expr, const namespacet &ns, const struct_tag_typet &class_type)
If expr has its components filled in then sets the @class_identifier member of the struct.
Extract class identifier.
virtual void clear()
Reset the abstract state.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Internally generated symbol table entryThis is a symbol generated as part of translation to or modifi...
A codet representing sequential composition of program statements.
A goto_instruction_codet representing the declaration of a local variable.
A codet representing an assignment in the program.
goto_instruction_codet representation of a function call statement.
codet representation of a goto statement.
codet representation of a label for branch targets.
A statement that catches an exception, assigning the exception in flight to an expression (e....
A goto_instruction_codet representing the declaration that an output of a particular description has ...
Pops an exception handler from the stack of active handlers (i.e.
Pushes an exception handler, of the form: exception_tag1 -> label1 exception_tag2 -> label2 ....
A codet representing a skip statement.
const irep_idt & get_base_name() const
const irep_idt & get_identifier() const
const parameterst & parameters() const
const typet & return_type() const
bool get_is_constructor() const
Data structure for representing an arbitrary statement in a program.
std::optional< std::string > main
A constant literal expression.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Base class for all expressions.
std::vector< exprt > operandst
typet & type()
Return the type of the expression.
source_locationt & add_source_location()
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
There are a large number of kinds of tree structured or tree-like data in CPROVER.
const irep_idt & get(const irep_idt &name) const
const irep_idt & id() const
std::vector< parametert > parameterst
A symbol table wrapper that records which entries have been updated/removedA caller can pass a journa...
static journalling_symbol_tablet wrap(symbol_table_baset &base_symbol_table)
Class that provides messages with a built-in verbosity 'level'.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
The null pointer constant.
virtual std::set< struct_tag_typet > get_parameter_alternative_types(const irep_idt &function_name, const irep_idt ¶meter_name, const namespacet &ns) const
Get alternative types for a method parameter, e.g., based on the casts in the function body.
A side_effect_exprt that returns a non-deterministically chosen value.
An expression containing a side effect.
void set_function(const irep_idt &function)
A struct tag type, i.e., struct_typet with an identifier.
Expression to hold a symbol (variable)
The symbol table base class interface.
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
bool remove(const irep_idt &name)
Remove a symbol from the symbol table.
const symbolt * lookup(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
virtual std::pair< symbolt &, bool > insert(symbolt symbol)=0
Move or copy a new symbol to the symbol table.
const symbolst & symbols
Read-only field, used to look up symbols given their names.
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
source_locationt location
Source code location of definition of symbol.
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
typet type
Type of symbol.
irep_idt name
The unique identifier.
exprt value
Initial value of symbol.
Semantic type conversion.
std::optional< exprt > zero_initializer(const typet &type, const source_locationt &source_location, const namespacet &ns)
Create the equivalent of zero for type type.
Expression Initialization.
Goto Programs with Functions.
const std::string & id2string(const irep_idt &d)
void java_bytecode_instrument_uncaught_exceptions(code_blockt &init_code, const symbolt &exc_symbol, const source_locationt &source_location)
Instruments the start function with an assertion that checks whether an exception has escaped the ent...
#define JAVA_CLASS_MODEL_SUFFIX
static code_blockt java_record_outputs(const symbolt &function, const exprt::operandst &main_arguments, symbol_table_baset &symbol_table)
Mark return value, pointer type parameters and the exception as outputs.
bool java_entry_point(symbol_table_baset &symbol_table, const irep_idt &main_class, message_handlert &message_handler, bool assume_init_pointers_not_null, bool assert_uncaught_exceptions, const java_object_factory_parameterst &object_factory_parameters, const select_pointer_typet &pointer_type_selector, bool string_refinement_enabled, const build_argumentst &build_arguments)
Given the symbol_table and the main_class to test, this function generates a new function __CPROVER__...
bool is_java_main(const symbolt &function)
Checks whether the given symbol is a valid java main method i.e.
static std::optional< codet > record_return_value(const symbolt &function, const symbol_table_baset &symbol_table)
static constant_exprt constant_bool(bool val)
void create_java_initialize(symbol_table_baset &symbol_table)
Adds __cprover_initialize to the symbol_table but does not generate code for it yet.
static bool should_init_symbol(const symbolt &sym)
static codet record_exception(const symbolt &function, const symbol_table_baset &symbol_table)
bool generate_java_start_function(const symbolt &symbol, symbol_table_baset &symbol_table, message_handlert &message_handler, bool assert_uncaught_exceptions, const java_object_factory_parameterst &object_factory_parameters, const select_pointer_typet &pointer_type_selector, const build_argumentst &build_arguments)
Generate a _start function for a specific function.
void java_static_lifetime_init(symbol_table_baset &symbol_table, const source_locationt &source_location, bool assume_init_pointers_not_null, java_object_factory_parameterst object_factory_parameters, const select_pointer_typet &pointer_type_selector, bool string_refinement_enabled, message_handlert &message_handler)
Adds the body to __CPROVER_initialize.
static code_blockt record_pointer_parameters(const symbolt &function, const std::vector< exprt > &arguments, const symbol_table_baset &symbol_table)
main_function_resultt get_main_symbol(const symbol_table_baset &symbol_table, const irep_idt &main_class, message_handlert &message_handler)
Figures out the entry point of the code to verify.
irep_idt get_java_class_literal_initializer_signature()
Get the symbol name of java.lang.Class' initializer method.
static std::unordered_set< irep_idt > init_symbol(const symbolt &sym, code_blockt &code_block, symbol_table_baset &symbol_table, const source_locationt &source_location, bool assume_init_pointers_not_null, const java_object_factory_parameterst &object_factory_parameters, const select_pointer_typet &pointer_type_selector, bool string_refinement_enabled, message_handlert &message_handler)
std::pair< code_blockt, std::vector< exprt > > java_build_arguments(const symbolt &function, symbol_table_baset &symbol_table, bool assume_init_pointers_not_null, java_object_factory_parameterst object_factory_parameters, const select_pointer_typet &pointer_type_selector, message_handlert &message_handler)
static const symbolt * get_class_literal_initializer(const symbolt &symbol, const symbol_table_baset &symbol_table)
If symbol is a class literal, and an appropriate initializer method exists, return a pointer to its s...
#define JAVA_ENTRY_POINT_RETURN_SYMBOL
#define JAVA_ENTRY_POINT_EXCEPTION_SYMBOL
std::function< std::pair< code_blockt, std::vector< exprt > >(const symbolt &function, symbol_table_baset &symbol_table)> build_argumentst
void gen_nondet_init(const exprt &expr, code_blockt &init_code, symbol_table_baset &symbol_table, const source_locationt &loc, bool skip_classid, lifetimet lifetime, const java_object_factory_parameterst &object_factory_parameters, const select_pointer_typet &pointer_type_selector, update_in_placet update_in_place, message_handlert &log)
Initializes a primitive-typed or reference-typed object tree rooted at expr, allocating child objects...
exprt object_factory(const typet &type, const irep_idt base_name, code_blockt &init_code, symbol_table_baset &symbol_table, java_object_factory_parameterst parameters, lifetimet lifetime, const source_locationt &loc, const select_pointer_typet &pointer_type_selector, message_handlert &log)
Similar to gen_nondet_init below, but instead of allocating and non-deterministically initializing th...
This module is responsible for the synthesis of code (in the form of a sequence of codet statements) ...
symbol_exprt get_or_create_string_literal_symbol(const java_string_literal_exprt &string_expr, symbol_table_baset &symbol_table, bool string_refinement_enabled)
Creates or gets an existing constant global symbol for a given string literal.
signedbv_typet java_int_type()
empty_typet java_void_type()
std::optional< typet > java_type_from_string(const std::string &src, const std::string &class_name_prefix)
Transforms a string representation of a Java type into an internal type representation thereof.
reference_typet java_reference_type(const typet &subtype)
c_bool_typet java_boolean_type()
bool is_java_array_tag(const irep_idt &tag)
See above.
const java_method_typet & to_java_method_type(const typet &type)
const java_class_typet & to_java_class_type(const typet &type)
bool is_java_string_literal_id(const irep_idt &id)
bool is_non_null_library_global(const irep_idt &symbolid)
Check if a symbol is a well-known non-null global.
irep_idt resolve_friendly_method_name(const std::string &friendly_name, const symbol_table_baset &symbol_table, std::string &error)
Resolves a user-friendly method name (like packagename.Class.method) into an internal name (like java...
symbolt & fresh_java_symbol(const typet &type, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &function_name, symbol_table_baset &symbol_table)
code_blockt generate_nondet_switch(const irep_idt &name_prefix, const alternate_casest &switch_cases, const typet &int_type, const irep_idt &mode, const source_locationt &source_location, symbol_table_baset &symbol_table)
Pick nondeterministically between imperative actions 'switch_cases'.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
#define INITIALIZE_FUNCTION
const struct_exprt & to_struct_expr(const exprt &expr)
Cast an exprt to a struct_exprt.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
const class_typet & to_class_type(const typet &type)
Cast a typet to a class_typet.
size_t strlen(const char *s)
irep_idt function_id
Function id, used as a prefix for identifiers of temporaries.
std::list< std::string > string_input_values
Force one of finitely many explicitly given input strings.
size_t min_null_tree_depth
To force a certain depth of non-null objects.
bool has_suffix(const std::string &s, const std::string &suffix)