Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
478f589
Add F.16 pass-by-value checker (Clang LibTooling)
tautschnig May 26, 2026
d0f3742
Add CI runner for the F.16 pass-by-value checker
tautschnig May 26, 2026
7387e7f
Add baseline of known F.16 pass-by-value violations
tautschnig May 26, 2026
8b0e114
CI: gate PRs on F.16 pass-by-value regressions
tautschnig May 26, 2026
0addaa9
Add --fix mode to the F.16 pass-by-value checker
tautschnig May 26, 2026
2b7b47d
Improve --fix robustness: --path-filter, manual save, own-param check
tautschnig May 26, 2026
8b37167
src/util: pass dstringt/irep_idt by value (F.16)
tautschnig May 26, 2026
6493a1b
src/langapi: pass irep_idt by value (F.16)
tautschnig May 26, 2026
430f87a
src/json-symtab-language: pass irep_idt by value (F.16)
tautschnig May 26, 2026
dc24c1d
src/assembler: pass irep_idt by value (F.16)
tautschnig May 26, 2026
c98d2a9
src/ansi-c: pass irep_idt by value (F.16)
tautschnig May 26, 2026
0ed788e
src/cpp: pass irep_idt by value (F.16)
tautschnig May 26, 2026
d9a796e
src/goto-programs: pass irep_idt by value (F.16)
tautschnig May 26, 2026
3b7eb51
src/linking: pass irep_idt by value (F.16)
tautschnig May 26, 2026
5aab609
src/analyses: pass irep_idt by value (F.16)
tautschnig May 26, 2026
9efbff0
src/pointer-analysis: pass irep_idt by value (F.16)
tautschnig May 26, 2026
e6ab1aa
src/solvers: pass irep_idt by value (F.16)
tautschnig May 26, 2026
0fab121
src/goto-symex: pass irep_idt by value (F.16)
tautschnig May 26, 2026
a990c9f
src/goto-checker: pass irep_idt by value (F.16)
tautschnig May 26, 2026
44c0b42
src/goto-instrument: pass irep_idt by value (F.16)
tautschnig May 26, 2026
d1bf6b8
src/ tools: pass irep_idt by value (F.16)
tautschnig May 26, 2026
1a0e2fd
jbmc/src/java_bytecode: pass irep_idt by value (F.16)
tautschnig May 26, 2026
d4b986e
jbmc/src tools: pass irep_idt by value (F.16)
tautschnig May 26, 2026
0b90bbf
unit tests: pass irep_idt by value (F.16)
tautschnig May 26, 2026
df7610b
F.16 checker: warn on non-fixable parameter sites
tautschnig May 26, 2026
97d76d8
F.16: regenerate empty baseline; allow zero findings
tautschnig May 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
19 changes: 19 additions & 0 deletions .github/workflows/syntax-checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,22 @@ jobs:
rustup toolchain install stable --profile minimal --no-self-update -c clippy -c rustfmt
- name: Run `cargo fmt` on top of Rust API project
run: cd src/libcprover-rust; cargo fmt --all -- --check

# This job takes approximately 3 minutes
check-pass-by-value:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- name: Fetch dependencies
env:
DEBIAN_FRONTEND: noninteractive
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -yq \
cmake g++ flex bison clang-18 llvm-18-dev libclang-18-dev
- name: Configure
run: cmake -S . -Bbuild -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- name: Check for pass-by-const-reference of cheap-to-copy types
run: ./scripts/run_pass_by_value_check.sh build
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,4 @@ dist/

# auto generated documentation
doc/html/
/scripts/check-pass-by-value
7 changes: 4 additions & 3 deletions jbmc/src/janalyzer/janalyzer_parse_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,8 @@ void janalyzer_parse_optionst::process_goto_function(
// Java virtual functions -> explicit dispatch tables:
remove_virtual_functions(function, *class_hierarchy);

auto function_is_stub = [&symbol_table, &model](const irep_idt &id) {
auto function_is_stub = [&symbol_table, &model](irep_idt id)
{
return symbol_table.lookup_ref(id).value.is_nil() &&
!model.can_produce_function(id);
};
Expand All @@ -698,15 +699,15 @@ void janalyzer_parse_optionst::process_goto_function(
transform_assertions_assumptions(options, function.get_goto_function().body);
}

bool janalyzer_parse_optionst::can_generate_function_body(const irep_idt &name)
bool janalyzer_parse_optionst::can_generate_function_body(irep_idt name)
{
static const irep_idt initialize_id = INITIALIZE_FUNCTION;

return name != goto_functionst::entry_point() && name != initialize_id;
}

bool janalyzer_parse_optionst::generate_function_body(
const irep_idt &function_name,
irep_idt function_name,
symbol_table_baset &symbol_table,
goto_functiont &function,
bool body_available)
Expand Down
4 changes: 2 additions & 2 deletions jbmc/src/janalyzer/janalyzer_parse_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ class janalyzer_parse_optionst : public parse_options_baset
const abstract_goto_modelt &model,
const optionst &options);

bool can_generate_function_body(const irep_idt &name);
bool can_generate_function_body(irep_idt name);

bool generate_function_body(
const irep_idt &function_name,
irep_idt function_name,
symbol_table_baset &symbol_table,
goto_functiont &function,
bool body_available);
Expand Down
2 changes: 1 addition & 1 deletion jbmc/src/java_bytecode/assignments_from_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ code_with_references_listt assign_from_json_rec(
code_with_references_listt assign_from_json(
const exprt &expr,
const jsont &json,
const irep_idt &function_id,
irep_idt function_id,
symbol_table_baset &symbol_table,
std::optional<ci_lazy_methods_neededt> &needed_lazy_methods,
size_t max_user_array_length,
Expand Down
2 changes: 1 addition & 1 deletion jbmc/src/java_bytecode/assignments_from_json.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class ci_lazy_methods_neededt;
code_with_references_listt assign_from_json(
const exprt &expr,
const jsont &json,
const irep_idt &function_id,
irep_idt function_id,
symbol_table_baset &symbol_table,
std::optional<ci_lazy_methods_neededt> &needed_lazy_methods,
size_t max_user_array_length,
Expand Down
8 changes: 4 additions & 4 deletions jbmc/src/java_bytecode/ci_lazy_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Author: Diffblue Ltd.
/// Java bytecode.
ci_lazy_methodst::ci_lazy_methodst(
const symbol_table_baset &symbol_table,
const irep_idt &main_class,
irep_idt main_class,
const std::vector<irep_idt> &main_jar_classes,
const std::vector<load_extra_methodst> &lazy_methods_extra_entry_points,
java_class_loadert &java_class_loader,
Expand Down Expand Up @@ -331,7 +331,7 @@ ci_lazy_methodst::convert_and_analyze_method(
const method_convertert &method_converter,
std::unordered_set<irep_idt> &methods_already_populated,
const bool class_initializer_already_seen,
const irep_idt &method_name,
irep_idt method_name,
symbol_table_baset &symbol_table,
std::unordered_set<irep_idt> &methods_to_convert_later,
std::unordered_set<irep_idt> &instantiated_classes,
Expand Down Expand Up @@ -557,8 +557,8 @@ void ci_lazy_methodst::gather_needed_globals(
/// `instantiated_classes`, or irep_idt() otherwise.
irep_idt ci_lazy_methodst::get_virtual_method_target(
const std::unordered_set<irep_idt> &instantiated_classes,
const irep_idt &call_basename,
const irep_idt &classname,
irep_idt call_basename,
irep_idt classname,
const symbol_table_baset &symbol_table)
{
// Program-wide, is this class ever instantiated?
Expand Down
23 changes: 11 additions & 12 deletions jbmc/src/java_bytecode/ci_lazy_methods.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class method_bytecodet
mapt map;

public:
bool contains_method(const irep_idt &method_id) const
bool contains_method(irep_idt method_id) const
{
return map.count(method_id) != 0;
}
Expand All @@ -63,8 +63,8 @@ class method_bytecodet
}

void add(
const irep_idt &class_id,
const irep_idt &method_id,
irep_idt class_id,
irep_idt method_id,
const java_bytecode_parse_treet::methodt &method)
{
add(class_method_and_bytecodet{class_id, method_id, method});
Expand All @@ -79,7 +79,7 @@ class method_bytecodet
return map.end();
}

opt_reft get(const irep_idt &method_id)
opt_reft get(irep_idt method_id)
{
const auto it = map.find(method_id);
if(it == map.end())
Expand All @@ -88,8 +88,7 @@ class method_bytecodet
}
};

typedef std::function<
bool(const irep_idt &function_id, ci_lazy_methods_neededt)>
typedef std::function<bool(irep_idt function_id, ci_lazy_methods_neededt)>
method_convertert;

typedef std::function<std::vector<irep_idt>(const symbol_table_baset &)>
Expand All @@ -100,7 +99,7 @@ class ci_lazy_methodst
public:
ci_lazy_methodst(
const symbol_table_baset &symbol_table,
const irep_idt &main_class,
irep_idt main_class,
const std::vector<irep_idt> &main_jar_classes,
const std::vector<load_extra_methodst> &lazy_methods_extra_entry_points,
java_class_loadert &java_class_loader,
Expand Down Expand Up @@ -138,13 +137,13 @@ class ci_lazy_methodst

irep_idt get_virtual_method_target(
const std::unordered_set<irep_idt> &instantiated_classes,
const irep_idt &call_basename,
const irep_idt &classname,
irep_idt call_basename,
irep_idt classname,
const symbol_table_baset &symbol_table);

static irep_idt build_virtual_method_name(
const irep_idt &class_name,
const irep_idt &component_method_name);
irep_idt class_name,
irep_idt component_method_name);

class_hierarchyt class_hierarchy;
irep_idt main_class;
Expand All @@ -169,7 +168,7 @@ class ci_lazy_methodst
const method_convertert &method_converter,
std::unordered_set<irep_idt> &methods_already_populated,
const bool class_initializer_already_seen,
const irep_idt &method_name,
irep_idt method_name,
symbol_table_baset &symbol_table,
std::unordered_set<irep_idt> &methods_to_convert_later,
std::unordered_set<irep_idt> &instantiated_classes,
Expand Down
10 changes: 4 additions & 6 deletions jbmc/src/java_bytecode/ci_lazy_methods_needed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ Author: Chris Smowton, chris.smowton@diffblue.com
/// Notes `method_symbol_name` is referenced from some reachable function, and
/// should therefore be elaborated.
/// \param method_symbol_name: method name; must exist in symbol table.
void ci_lazy_methods_neededt::add_needed_method(
const irep_idt &method_symbol_name)
void ci_lazy_methods_neededt::add_needed_method(irep_idt method_symbol_name)
{
callable_methods.insert(method_symbol_name);
}
Expand All @@ -39,7 +38,7 @@ void ci_lazy_methods_neededt::add_needed_method(
/// __CPROVER_start in its initial setup, and because return values of opaque
/// methods need to be considered in ci_lazy_methods too.
/// \param class_id: The given class id
void ci_lazy_methods_neededt::add_clinit_call(const irep_idt &class_id)
void ci_lazy_methods_neededt::add_clinit_call(irep_idt class_id)
{
const irep_idt &clinit_wrapper = clinit_wrapper_name(class_id);
if(symbol_table.symbols.count(clinit_wrapper))
Expand All @@ -50,7 +49,7 @@ void ci_lazy_methods_neededt::add_clinit_call(const irep_idt &class_id)
/// ancestors then note that it is needed.
/// \param class_id: The given class id
void ci_lazy_methods_neededt::add_cprover_nondet_initialize_if_it_exists(
const irep_idt &class_id)
irep_idt class_id)
{
resolve_inherited_componentt resolve_inherited_component{symbol_table};
std::optional<resolve_inherited_componentt::inherited_componentt>
Expand All @@ -69,8 +68,7 @@ void ci_lazy_methods_neededt::add_cprover_nondet_initialize_if_it_exists(
/// therefore reachable.
/// \param class_symbol_name: class name; must exist in symbol table.
/// \return Returns true if `class_symbol_name` is new (not seen before).
bool ci_lazy_methods_neededt::add_needed_class(
const irep_idt &class_symbol_name)
bool ci_lazy_methods_neededt::add_needed_class(irep_idt class_symbol_name)
{
if(!instantiated_classes.insert(class_symbol_name).second)
return false;
Expand Down
8 changes: 4 additions & 4 deletions jbmc/src/java_bytecode/ci_lazy_methods_needed.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ class ci_lazy_methods_neededt
pointer_type_selector(pointer_type_selector)
{}

void add_needed_method(const irep_idt &);
void add_needed_method(irep_idt);
// Returns true if new
bool add_needed_class(const irep_idt &);
bool add_needed_class(irep_idt);

void add_all_needed_classes(const pointer_typet &pointer_type);

Expand All @@ -57,8 +57,8 @@ class ci_lazy_methods_neededt

const select_pointer_typet &pointer_type_selector;

void add_clinit_call(const irep_idt &class_id);
void add_cprover_nondet_initialize_if_it_exists(const irep_idt &class_id);
void add_clinit_call(irep_idt class_id);
void add_cprover_nondet_initialize_if_it_exists(irep_idt class_id);

void initialize_instantiated_classes_from_pointer(
const pointer_typet &pointer_type,
Expand Down
12 changes: 6 additions & 6 deletions jbmc/src/java_bytecode/convert_java_nondet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static goto_programt get_gen_nondet_init_instructions(
symbol_table_baset &symbol_table,
message_handlert &message_handler,
const java_object_factory_parameterst &object_factory_parameters,
const irep_idt &mode)
irep_idt mode)
{
code_blockt gen_nondet_init_code;
const bool skip_classid = true;
Expand Down Expand Up @@ -79,13 +79,13 @@ static goto_programt get_gen_nondet_init_instructions(
/// \return The next instruction to process with this function and a boolean
/// indicating whether any changes were made to the goto program.
static std::pair<goto_programt::targett, bool> insert_nondet_init_code(
const irep_idt &function_identifier,
irep_idt function_identifier,
goto_programt &goto_program,
const goto_programt::targett &target,
symbol_table_baset &symbol_table,
message_handlert &message_handler,
java_object_factory_parameterst object_factory_parameters,
const irep_idt &mode)
irep_idt mode)
{
const auto next_instr = std::next(target);

Expand Down Expand Up @@ -164,12 +164,12 @@ static std::pair<goto_programt::targett, bool> insert_nondet_init_code(
/// nondet objects.
/// \param mode: Language mode
void convert_nondet(
const irep_idt &function_identifier,
irep_idt function_identifier,
goto_programt &goto_program,
symbol_table_baset &symbol_table,
message_handlert &message_handler,
const java_object_factory_parameterst &user_object_factory_parameters,
const irep_idt &mode)
irep_idt mode)
{
java_object_factory_parameterst object_factory_parameters =
user_object_factory_parameters;
Expand Down Expand Up @@ -202,7 +202,7 @@ void convert_nondet(
goto_model_functiont &function,
message_handlert &message_handler,
const java_object_factory_parameterst &object_factory_parameters,
const irep_idt &mode)
irep_idt mode)
{
convert_nondet(
function.get_function_id(),
Expand Down
2 changes: 1 addition & 1 deletion jbmc/src/java_bytecode/convert_java_nondet.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ void convert_nondet(
goto_model_functiont &function,
message_handlert &message_handler,
const java_object_factory_parameterst &object_factory_parameters,
const irep_idt &mode);
irep_idt mode);

#endif // CPROVER_JAVA_BYTECODE_CONVERT_NONDET_H
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ irep_idt get_create_array_with_type_name()
/// \param message_handler: any GOTO program conversion errors are logged here
/// \return new GOTO program body for `org.cprover.CProver.createArrayWithType`.
codet create_array_with_type_body(
const irep_idt &function_id,
irep_idt function_id,
symbol_table_baset &symbol_table,
message_handlert &message_handler)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class symbol_table_baset;
irep_idt get_create_array_with_type_name();

codet create_array_with_type_body(
const irep_idt &function_id,
irep_idt function_id,
symbol_table_baset &symbol_table,
message_handlert &message_handler);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void generic_parameter_specialization_mapt::pop(std::size_t container_index)
}

std::optional<reference_typet>
generic_parameter_specialization_mapt::pop(const irep_idt &parameter_name)
generic_parameter_specialization_mapt::pop(irep_idt parameter_name)
{
const auto types_it = param_to_container.find(parameter_name);
if(types_it == param_to_container.end())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class generic_parameter_specialization_mapt
/// \param parameter_name: The name of the type parameter
/// \returns: The specialization for the given type parameter, if there was
/// one before the pop, or an empty std::optional if the stack was empty
std::optional<reference_typet> pop(const irep_idt &parameter_name);
std::optional<reference_typet> pop(irep_idt parameter_name);

/// A wrapper for a generic_parameter_specialization_mapt and a namespacet
/// that can be output to a stream
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ const std::string thread_id = CPROVER_PREFIX "_thread_id";// NOLINT(*)
/// /return returns new or existing symbol.
static symbolt add_or_get_symbol(
symbol_table_baset &symbol_table,
const irep_idt &name,
const irep_idt &base_name,
irep_idt name,
irep_idt base_name,
const typet &type,
const exprt &value,
const bool is_thread_local,
Expand Down
9 changes: 4 additions & 5 deletions jbmc/src/java_bytecode/java_bytecode_convert_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ class java_bytecode_convert_classt
/// \param class_name: class the method is declared on
/// \param method: a `methodt` object from a java bytecode parse tree
/// \return true if the method is an ignored method, else false
static bool is_ignored_method(
const irep_idt &class_name, const methodt &method)
static bool is_ignored_method(irep_idt class_name, const methodt &method)
{
static irep_idt org_cprover_CProver_name = "org.cprover.CProver";
return
Expand All @@ -170,7 +169,7 @@ class java_bytecode_convert_classt

bool check_field_exists(
const fieldt &field,
const irep_idt &qualified_fieldname,
irep_idt qualified_fieldname,
const struct_union_typet::componentst &fields) const;

std::unordered_set<std::string> no_load_classes;
Expand Down Expand Up @@ -620,7 +619,7 @@ void java_bytecode_convert_classt::convert(

bool java_bytecode_convert_classt::check_field_exists(
const java_bytecode_parse_treet::fieldt &field,
const irep_idt &qualified_fieldname,
irep_idt qualified_fieldname,
const struct_union_typet::componentst &fields) const
{
if(field.is_static)
Expand Down Expand Up @@ -1178,7 +1177,7 @@ void convert_java_annotations(
/// the inner class are updated to point to the type parameters of the
/// corresponding outer classes.
void mark_java_implicitly_generic_class_type(
const irep_idt &class_name,
irep_idt class_name,
symbol_table_baset &symbol_table)
{
const std::string qualified_class_name = "java::" + id2string(class_name);
Expand Down
Loading
Loading