Skip to content

Separate parsing of language options from languaget #2911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion jbmc/src/janalyzer/janalyzer_parse_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ void janalyzer_parse_optionst::get_command_line_options(optionst &options)
exit(CPROVER_EXIT_USAGE_ERROR);
}

parse_java_language_options(cmdline, options);

// check assertions
if(cmdline.isset("no-assertions"))
options.set_option("assertions", false);
Expand Down Expand Up @@ -350,7 +352,7 @@ int janalyzer_parse_optionst::doit()

try
{
goto_model = initialize_goto_model(cmdline, get_message_handler());
goto_model = initialize_goto_model(cmdline, get_message_handler(), options);
}

catch(const char *e)
Expand Down
1 change: 1 addition & 0 deletions jbmc/src/java_bytecode/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ SRC = bytecode_info.cpp \
java_types.cpp \
java_utils.cpp \
load_method_by_regex.cpp \
object_factory_parameters.cpp \
mz_zip_archive.cpp \
remove_exceptions.cpp \
remove_instanceof.cpp \
Expand Down
131 changes: 79 additions & 52 deletions jbmc/src/java_bytecode/java_bytecode_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ Author: Daniel Kroening, [email protected]

#include <string>

#include <util/symbol_table.h>
#include <util/suffix.h>
#include <util/config.h>
#include <util/cmdline.h>
#include <util/config.h>
#include <util/expr_iterator.h>
#include <util/invariant.h>
#include <util/journalling_symbol_table.h>
#include <util/options.h>
#include <util/string2int.h>
#include <util/invariant.h>
#include <util/suffix.h>
#include <util/symbol_table.h>

#include <json/json_parser.h>

#include <goto-programs/class_hierarchy.h>
Expand All @@ -39,82 +41,108 @@ Author: Daniel Kroening, [email protected]
#include "expr2java.h"
#include "load_method_by_regex.h"

/// Consume options that are java bytecode specific.
/// \param Command:line options
/// \return None
void java_bytecode_languaget::get_language_options(const cmdlinet &cmd)
/// Parse options that are java bytecode specific.
/// \param cmd Command line
/// \param [out] options The options object that will be updated.
void parse_java_language_options(const cmdlinet &cmd, optionst &options)
{
assume_inputs_non_null=cmd.isset("java-assume-inputs-non-null");
string_refinement_enabled = !cmd.isset("no-refine-strings");
throw_runtime_exceptions = cmd.isset("throw-runtime-exceptions");
assert_uncaught_exceptions = !cmd.isset("disable-uncaught-exception-check");
throw_assertion_error = cmd.isset("throw-assertion-error");
threading_support = cmd.isset("java-threading");

if(cmd.isset("max-nondet-array-length"))
options.set_option(
"java-assume-inputs-non-null", cmd.isset("java-assume-inputs-non-null"));
options.set_option(
"throw-runtime-exceptions", cmd.isset("throw-runtime-exceptions"));
options.set_option(
"uncaught-exception-check", !cmd.isset("disable-uncaught-exception-check"));
options.set_option(
"throw-assertion-error", cmd.isset("throw-assertion-error"));
options.set_option("java-threading", cmd.isset("java-threading"));

if(cmd.isset("java-max-vla-length"))
{
object_factory_parameters.max_nondet_array_length =
safe_string2size_t(cmd.get_value("max-nondet-array-length"));
options.set_option(
"java-max-vla-length", cmd.get_value("java-max-vla-length"));
}

if(cmd.isset("max-nondet-tree-depth"))
options.set_option(
"symex-driven-lazy-loading", cmd.isset("symex-driven-lazy-loading"));

if(cmd.isset("java-load-class"))
options.set_option("java-load-class", cmd.get_values("java-load-class"));

if(cmd.isset("java-no-load-class"))
{
object_factory_parameters.max_nondet_tree_depth =
safe_string2size_t(cmd.get_value("max-nondet-tree-depth"));
options.set_option(
"java-no-load-class", cmd.get_values("java-no-load-class"));
}

if(cmd.isset("max-nondet-string-length"))
if(cmd.isset("lazy-methods-extra-entry-point"))
{
options.set_option(
"lazy-methods-extra-entry-point",
cmd.get_values("lazy-methods-extra-entry-point"));
}
if(cmd.isset("java-cp-include-files"))
{
object_factory_parameters.max_nondet_string_length =
safe_string2size_t(cmd.get_value("max-nondet-string-length"));
options.set_option(
"java-cp-include-files", cmd.get_value("java-cp-include-files"));
}
if(cmd.isset("string-non-empty"))
object_factory_parameters.min_nondet_string_length = 1;
}

object_factory_parameters.string_printable = cmd.isset("string-printable");
if(cmd.isset("java-max-vla-length"))
max_user_array_length =
safe_string2size_t(cmd.get_value("java-max-vla-length"));
if(cmd.isset("symex-driven-lazy-loading"))
/// Consume options that are java bytecode specific.
void java_bytecode_languaget::set_language_options(const optionst &options)
{
object_factory_parameters.set(options);

assume_inputs_non_null =
options.get_bool_option("java-assume-inputs-non-null");
string_refinement_enabled = options.get_bool_option("refine-strings");
throw_runtime_exceptions =
options.get_bool_option("throw-runtime-exceptions");
assert_uncaught_exceptions =
options.get_bool_option("uncaught-exception-check");
throw_assertion_error = options.get_bool_option("throw-assertion-error");
threading_support = options.get_bool_option("java-threading");
max_user_array_length =
options.get_unsigned_int_option("java-max-vla-length");

if(options.get_bool_option("symex-driven-lazy-loading"))
lazy_methods_mode=LAZY_METHODS_MODE_EXTERNAL_DRIVER;
else if(!cmd.isset("no-lazy-methods"))
else if(options.get_bool_option("lazy-methods"))
lazy_methods_mode=LAZY_METHODS_MODE_CONTEXT_INSENSITIVE;
else
lazy_methods_mode=LAZY_METHODS_MODE_EAGER;

if(throw_runtime_exceptions)
{
java_load_classes.insert(
java_load_classes.end(),
exception_needed_classes.begin(),
exception_needed_classes.end());
java_load_classes.end(),
exception_needed_classes.begin(),
exception_needed_classes.end());
}
if(cmd.isset("java-load-class"))

if(options.is_set("java-load-class"))
{
const auto &values = cmd.get_values("java-load-class");
const auto &load_values = options.get_list_option("java-load-class");
java_load_classes.insert(
java_load_classes.end(), values.begin(), values.end());
java_load_classes.end(), load_values.begin(), load_values.end());
}
if(cmd.isset("java-no-load-class"))
if(options.is_set("java-no-load-class"))
{
const auto &values = cmd.get_values("java-no-load-class");
no_load_classes = {values.begin(), values.end()};
const auto &no_load_values = options.get_list_option("java-no-load-class");
no_load_classes = {no_load_values.begin(), no_load_values.end()};
}

const std::list<std::string> &extra_entry_points=
cmd.get_values("lazy-methods-extra-entry-point");
const std::list<std::string> &extra_entry_points =
options.get_list_option("lazy-methods-extra-entry-point");
std::transform(
extra_entry_points.begin(),
extra_entry_points.end(),
std::back_inserter(extra_methods),
build_load_method_by_regex);
const auto &new_points = build_extra_entry_points(cmd);
const auto &new_points = build_extra_entry_points(options);
extra_methods.insert(
extra_methods.end(), new_points.begin(), new_points.end());

if(cmd.isset("java-cp-include-files"))
java_cp_include_files = options.get_option("java-cp-include-files");
if(!java_cp_include_files.empty())
{
java_cp_include_files=cmd.get_value("java-cp-include-files");
// load file list from JSON file
if(java_cp_include_files[0]=='@')
{
Expand All @@ -129,7 +157,7 @@ void java_bytecode_languaget::get_language_options(const cmdlinet &cmd)
throw "the JSON file has a wrong format";
jsont include_files=json_cp_config["jar"];
if(!include_files.is_array())
throw "the JSON file has a wrong format";
throw "the JSON file has a wrong format";

// add jars from JSON config file to classpath
for(const jsont &file_entry : include_files.array)
Expand All @@ -145,7 +173,7 @@ void java_bytecode_languaget::get_language_options(const cmdlinet &cmd)
else
java_cp_include_files=".*";

nondet_static = cmd.isset("nondet-static");
nondet_static = options.get_bool_option("nondet-static");

language_options_initialized=true;
}
Expand Down Expand Up @@ -1219,8 +1247,7 @@ java_bytecode_languaget::~java_bytecode_languaget()
/// specifying extra entry points. To provide a regex entry point, the command
/// line option `--lazy-methods-extra-entry-point` can be used directly.
std::vector<load_extra_methodst>
java_bytecode_languaget::build_extra_entry_points(
const cmdlinet &command_line) const
java_bytecode_languaget::build_extra_entry_points(const optionst &options) const
{
return {};
}
6 changes: 4 additions & 2 deletions jbmc/src/java_bytecode/java_bytecode_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ enum lazy_methods_modet
class java_bytecode_languaget:public languaget
{
public:
virtual void get_language_options(const cmdlinet &) override;
void set_language_options(const optionst &) override;

virtual bool preprocess(
std::istream &instream,
Expand Down Expand Up @@ -196,7 +196,7 @@ class java_bytecode_languaget:public languaget

private:
virtual std::vector<load_extra_methodst>
build_extra_entry_points(const cmdlinet &command_line) const;
build_extra_entry_points(const optionst &) const;
const std::unique_ptr<const select_pointer_typet> pointer_type_selector;

/// Maps synthetic method names on to the particular type of synthetic method
Expand All @@ -213,4 +213,6 @@ class java_bytecode_languaget:public languaget

std::unique_ptr<languaget> new_java_bytecode_language();

void parse_java_language_options(const cmdlinet &cmd, optionst &options);

#endif // CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_LANGUAGE_H
5 changes: 3 additions & 2 deletions jbmc/src/java_bytecode/java_class_loader_limit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Author: Daniel Kroening, [email protected]

#include <json/json_parser.h>

#include <util/invariant.h>

/// Initializes class with either regex matcher or match set. If the string
/// starts with an `@` it is treated as a path to a JSON file. Otherwise, it is
/// treated as a regex.
Expand Down Expand Up @@ -48,8 +50,7 @@ Author: Daniel Kroening, [email protected]
void java_class_loader_limitt::setup_class_load_limit(
const std::string &java_cp_include_files)
{
if(java_cp_include_files.empty())
throw "class regexp cannot be empty, `get_language_options` not called?";
PRECONDITION(!java_cp_include_files.empty());

// '@' signals file reading with list of class files to load
use_regex_match = java_cp_include_files[0] != '@';
Expand Down
71 changes: 71 additions & 0 deletions jbmc/src/java_bytecode/object_factory_parameters.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*******************************************************************\

Module: Java Object Factory

Author: Diffblue Ltd

\*******************************************************************/

#include "object_factory_parameters.h"

#include <util/cmdline.h>
#include <util/options.h>

void object_factory_parameterst::set(const optionst &options)
{
if(options.is_set("max-nondet-array-length"))
{
max_nondet_array_length =
options.get_unsigned_int_option("max-nondet-array-length");
}
if(options.is_set("max-nondet-tree-depth"))
{
max_nondet_tree_depth =
options.get_unsigned_int_option("max-nondet-tree-depth");
}
if(options.is_set("max-nondet-string-length"))
{
max_nondet_string_length =
options.get_unsigned_int_option("max-nondet-string-length");
}
if(options.is_set("string-printable"))
{
string_printable = options.get_bool_option("string-printable");
}
if(options.is_set("min-nondet-string-length"))
{
min_nondet_string_length =
options.get_unsigned_int_option("min-nondet-string-length");
}
}

/// Parse the object factory parameters from a given command line
/// \param cmdline Command line
/// \param [out] options The options object that will be updated.
void parse_object_factory_options(const cmdlinet &cmdline, optionst &options)
{
if(cmdline.isset("max-nondet-array-length"))
{
options.set_option(
"max-nondet-array-length", cmdline.get_value("max-nondet-array-length"));
}
if(cmdline.isset("max-nondet-tree-depth"))
{
options.set_option(
"max-nondet-tree-depth", cmdline.get_value("max-nondet-tree-depth"));
}
if(cmdline.isset("max-nondet-string-length"))
{
options.set_option(
"max-nondet-string-length",
cmdline.get_value("max-nondet-string-length"));
}
if(cmdline.isset("string-printable"))
{
options.set_option("string-printable", cmdline.isset("string-printable"));
}
if(cmdline.isset("string-non-empty"))
{
options.set_option("min-nondet-string-length", 1);
}
}
8 changes: 8 additions & 0 deletions jbmc/src/java_bytecode/object_factory_parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Author: Daniel Kroening, [email protected]

#include <util/irep.h>

class cmdlinet;
class optionst;

#define MAX_NONDET_ARRAY_LENGTH_DEFAULT 5
#define MAX_NONDET_STRING_LENGTH \
static_cast<std::size_t>(std::numeric_limits<std::int32_t>::max())
Expand Down Expand Up @@ -56,6 +59,11 @@ struct object_factory_parameterst final

/// Function id, used as a prefix for identifiers of temporaries
irep_idt function_id;

/// Assigns the parameters from given options
void set(const optionst &);
};

void parse_object_factory_options(const cmdlinet &, optionst &);

#endif
Loading