Skip to content

Fix: Do not nondet functions and fix scoping issue #4277

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
2 changes: 1 addition & 1 deletion regression/goto-harness/chain.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ if [ -e "${name}-mod.gb" ] ; then
fi

$goto_harness "${name}.gb" "${name}-mod.gb" --harness-function-name $entry_point ${args}
$cbmc --function $entry_point "${name}-mod.gb"
$cbmc --function $entry_point "${name}-mod.gb" --unwind 20 --unwinding-assertions

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically it’s a bit annoying to hardcode cbmc options here. We’ve been considering changing our chain.sh to allow us to set cbmc options per test case, but we decided to not do this as part of this PR for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hannes-steffenhagen-diffblue - Might be worth raising this point with @karkhaz as he is currently working on re-writing test.pl in Python and cleaning up a few things at the same time - could be a good time to address chain.sh as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chrisr-diffblue We were thinking as part of a later PR to change chain.sh into a python script. This would make it much easier for things like organising configuration of different tool invocations. We'll see if we can leverage the work done on that front as well.

25 changes: 25 additions & 0 deletions regression/goto-harness/nondet_elements_longer_lists/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <assert.h>

typedef struct list
{
int datum;
struct list *next;
} list_nodet;

void test_function(list_nodet *node)
{
int i = 0;
list_nodet *list_walker = node;
while(list_walker)
{
list_walker->datum = ++i;
list_walker = list_walker->next;
}
list_walker = node;
i = 0;
while(list_walker)
{
assert(list_walker->datum == ++i);
list_walker = list_walker->next;
}
}
10 changes: 10 additions & 0 deletions regression/goto-harness/nondet_elements_longer_lists/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
main.c
--harness-type call-function --max-nondet-tree-depth 4 --min-null-tree-depth 1 --function test_function
\[test_function.unwind.\d+\] line \d+ unwinding assertion loop 0: SUCCESS
\[test_function.unwind.\d+\] line \d+ unwinding assertion loop 1: SUCCESS
\[test_function.assertion.\d+\] line \d+ assertion list_walker->datum == \+\+i: SUCCESS
^EXIT=0$
^SIGNAL=0$
VERIFICATION SUCCESSFUL
--
26 changes: 26 additions & 0 deletions regression/goto-harness/nondet_elements_longer_lists_global/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <assert.h>

typedef struct list
{
int datum;
struct list *next;
} list_nodet;

list_nodet *global_list;
void test_function(void)
{
int i = 0;
list_nodet *list_walker = global_list;
while(list_walker)
{
list_walker->datum = ++i;
list_walker = list_walker->next;
}
list_walker = global_list;
i = 0;
while(list_walker)
{
assert(list_walker->datum == ++i);
list_walker = list_walker->next;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
main.c
--harness-type call-function --max-nondet-tree-depth 4 --min-null-tree-depth 1 --function test_function --nondet-globals
\[test_function.unwind.\d+\] line \d+ unwinding assertion loop 0: SUCCESS
\[test_function.unwind.\d+\] line \d+ unwinding assertion loop 1: SUCCESS
\[test_function.assertion.\d+\] line \d+ assertion list_walker->datum == \+\+i: SUCCESS
^EXIT=0$
^SIGNAL=0$
VERIFICATION SUCCESSFUL
--
14 changes: 13 additions & 1 deletion src/goto-harness/function_call_harness_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,16 +180,28 @@ void function_call_harness_generatort::implt::generate_nondet_globals(
{
if(nondet_globals)
{
// generating initialisation code may introduce new globals
// i.e. modify the symbol table.
// Modifying the symbol table while iterating over it is not
// a good idea, therefore we just collect the names of globals
// we need to initialise first and then generate the
// initialisation code for all of them.
auto globals = std::vector<symbol_exprt>{};
for(const auto &symbol_table_entry : *symbol_table)
{
const auto &symbol = symbol_table_entry.second;
if(
symbol.is_static_lifetime && symbol.is_lvalue &&
symbol.type.id() != ID_code &&
!has_prefix(id2string(symbol.name), CPROVER_PREFIX))
{
generate_initialisation_code_for(function_body, symbol.symbol_expr());
globals.push_back(symbol.symbol_expr());
}
}
for(auto const &global : globals)
{
generate_initialisation_code_for(function_body, global);
}
}
}

Expand Down
13 changes: 11 additions & 2 deletions src/goto-harness/recursive_initialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,17 @@ void recursive_initializationt::initialize_pointer(
goto_model.symbol_table};
exprt choice =
allocate_objects.allocate_automatic_local_object(bool_typet{}, "choice");
auto pointee =
allocate_objects.allocate_automatic_local_object(type.subtype(), "pointee");
symbolt &pointee_symbol = get_fresh_aux_symbol(
type.subtype(),
"__goto_harness",
"pointee",
lhs.source_location(),
initialization_config.mode,
goto_model.symbol_table);
pointee_symbol.is_static_lifetime = true;
pointee_symbol.is_lvalue = true;

auto pointee = pointee_symbol.symbol_expr();
allocate_objects.declare_created_symbols(body);
body.add(code_assignt{lhs, null_pointer_exprt{type}});
bool is_unknown_struct_tag =
Expand Down