Skip to content

Contracts dependence on remove_returns [depends-on: #2677] #2712

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

Closed
wants to merge 14 commits into from
17 changes: 17 additions & 0 deletions regression/ansi-c/code_contracts1/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
int foo()
__CPROVER_ensures(__CPROVER_forall {int i; 1 == 1})
{
return 1;
}

int bar()
__CPROVER_ensures(__CPROVER_forall {int i; 1 == 1} &&
__CPROVER_return_value == 1)
{
return 1;
}

int main() {
foo();
bar();
}
8 changes: 8 additions & 0 deletions regression/ansi-c/code_contracts1/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CORE
main.c

^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
^CONVERSION ERROR$
3 changes: 1 addition & 2 deletions regression/contracts/function_apply_01/test.desc
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
KNOWNBUG
CORE
main.c
--apply-code-contracts
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
--
Applying code contracts currently also checks them.
5 changes: 1 addition & 4 deletions regression/contracts/function_check_01/test.desc
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
CORE
main.c
--apply-code-contracts
--check-code-contracts
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
--
--check-code-contracts not implemented yet.
--apply-code-contracts is the current name for the flag. This should be
updated as the flag changes.
5 changes: 1 addition & 4 deletions regression/contracts/function_check_04/test.desc
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
CORE
main.c
--apply-code-contracts
--check-code-contracts
^\[main.assertion.1\] assertion x == 0: SUCCESS$
^\[foo.1\] : FAILURE$
^VERIFICATION FAILED$
--
--
--check-code-contracts not implemented yet.
--apply-code-contracts is the current name for the flag. This should be
updated as the flag changes.
5 changes: 2 additions & 3 deletions regression/contracts/function_check_05/test.desc
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
KNOWNBUG
CORE
main.c
--check-code-contracts
^\[main.assertion.1\] assertion y == 0: FAILURE$
^\[main.assertion.2\] assertion z == 1: SUCCESS$
^\[foo.1\] : SUCCESS$
^VERIFICATION SUCCESSFUL$
^VERIFICATION FAILED$
--
--
Contract checking does not properly havoc function calls.
2 changes: 1 addition & 1 deletion regression/contracts/function_check_mem_01/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void foo(bar *x)
__CPROVER_requires(__CPROVER_VALID_MEM(x, sizeof(bar)))
{
x->x += 1;
return
return;
}

int main()
Expand Down
2 changes: 1 addition & 1 deletion regression/contracts/function_check_mem_01/test.desc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
KNOWNBUG
CORE
main.c
--check-code-contracts
^EXIT=0$
Expand Down
5 changes: 1 addition & 4 deletions regression/contracts/invar_check_01/test.desc
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
CORE
main.c
--apply-code-contracts
--check-code-contracts
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
--
--check-code-contracts not implemented yet.
--apply-code-contracts is the current name for the flag. This should be
updated as the flag changes.
5 changes: 1 addition & 4 deletions regression/contracts/invar_check_02/test.desc
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
CORE
main.c
--apply-code-contracts
--check-code-contracts
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
--
--check-code-contracts not implemented yet.
--apply-code-contracts is the current name for the flag. This should be
updated as the flag changes.
5 changes: 1 addition & 4 deletions regression/contracts/invar_check_03/test.desc
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
CORE
main.c
--apply-code-contracts
--check-code-contracts
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
--
--check-code-contracts not implemented yet.
--apply-code-contracts is the current name for the flag. This should be
updated as the flag changes.
5 changes: 1 addition & 4 deletions regression/contracts/invar_check_04/test.desc
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
CORE
main.c
--apply-code-contracts
--check-code-contracts
^\[main.1\] Loop invariant violated before entry: SUCCESS$
^\[main.2\] Loop invariant not preserved: SUCCESS$
^\[main.assertion.1\] assertion r == 0: FAILURE$
^VERIFICATION FAILED$
--
--
--check-code-contracts not implemented yet.
--apply-code-contracts is the current name for the flag. This should be
updated as the flag changes.
2 changes: 1 addition & 1 deletion regression/goto-instrument/slice19/test.desc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
KNOWNBUG
CORE
main.c
--full-slice
^EXIT=0$
Expand Down
14 changes: 14 additions & 0 deletions regression/goto-instrument/slice24/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <assert.h>
#include <stdlib.h>

static void f(int *x) { *x = 5; }
static void g(int *x) { assert(*x == 5); }

int main(int argc, char **argv)
{
int *x = (int*)malloc(sizeof(int));
f(x);
g(x);

return 0;
}
8 changes: 8 additions & 0 deletions regression/goto-instrument/slice24/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
KNOWNBUG
main.c
--full-slice --add-library
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
Data dependencies across function calls are still not working correctly.
4 changes: 4 additions & 0 deletions src/analyses/dependence_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,9 @@ void dep_graph_domaint::data_dependencies(
{
bool found=false;
for(const auto &wr : w_range.second)
{
for(const auto &r_range : r_ranges)
{
if(!found &&
may_be_def_use_pair(wr.first, wr.second,
r_range.first, r_range.second))
Expand All @@ -184,6 +186,8 @@ void dep_graph_domaint::data_dependencies(
data_deps.insert(w_range.first);
found=true;
}
}
}
}

dep_graph.reaching_definitions()[to].clear_cache(it->first);
Expand Down
23 changes: 13 additions & 10 deletions src/analyses/goto_rw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ void rw_range_sett::get_objects_dereference(
{
const exprt &pointer=deref.pointer();
get_objects_rec(get_modet::READ, pointer);
if(mode!=get_modet::READ)
get_objects_rec(mode, pointer);
}

void rw_range_sett::get_objects_byte_extract(
Expand Down Expand Up @@ -414,16 +412,19 @@ void rw_range_sett::get_objects_typecast(

void rw_range_sett::get_objects_address_of(const exprt &object)
{
if(object.id() == ID_string_constant ||
if(object.id() == ID_symbol ||
object.id() == ID_string_constant ||
object.id() == ID_label ||
object.id() == ID_array ||
object.id() == ID_null_object)
// constant, nothing to do
{
return;
else if(object.id()==ID_symbol)
get_objects_rec(get_modet::READ, object);
}
else if(object.id()==ID_dereference)
{
get_objects_rec(get_modet::READ, object);
}
else if(object.id()==ID_index)
{
const index_exprt &index=to_index_expr(object);
Expand Down Expand Up @@ -524,6 +525,11 @@ void rw_range_sett::get_objects_rec(
get_objects_array(mode, to_array_expr(expr), range_start, size);
else if(expr.id()==ID_struct)
get_objects_struct(mode, to_struct_expr(expr), range_start, size);
else if(expr.id()==ID_dynamic_object)
{
const auto obj_instance = to_dynamic_object_expr(expr).get_instance();
add(mode, "goto_rw::dynamic_object-" + std::to_string(obj_instance), 0, -1);
}
else if(expr.id()==ID_symbol)
{
const symbol_exprt &symbol=to_symbol_expr(expr);
Expand Down Expand Up @@ -564,11 +570,6 @@ void rw_range_sett::get_objects_rec(
{
// dereferencing may yield some weird ones, ignore these
}
else if(mode==get_modet::LHS_W)
{
forall_operands(it, expr)
get_objects_rec(mode, *it);
}
else
throw "rw_range_sett: assignment to `"+expr.id_string()+"' not handled";
}
Expand Down Expand Up @@ -605,6 +606,8 @@ void rw_range_set_value_sett::get_objects_dereference(
exprt object=deref;
dereference(target, object, ns, value_sets);

PRECONDITION(object.is_not_nil());

range_spect new_size=
to_range_spect(pointer_offset_bits(object.type(), ns));

Expand Down
14 changes: 7 additions & 7 deletions src/analyses/reaching_definitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,19 +307,19 @@ void rd_range_domaint::transform_assign(
{
const irep_idt &identifier=it->first;
// ignore symex::invalid_object
const symbolt *symbol_ptr;
if(ns.lookup(identifier, symbol_ptr))
const symbolt *symbol_ptr = nullptr;
bool not_found = ns.lookup(identifier, symbol_ptr);
if(not_found && has_prefix(id2string(identifier), "symex::invalid_object"))
{
continue;
INVARIANT_STRUCTURED(
symbol_ptr!=nullptr,
nullptr_exceptiont,
"Symbol is in symbol table");
}

const range_domaint &ranges=rw_set.get_ranges(it);

if(is_must_alias &&
(!rd.get_is_threaded()(from) ||
(!symbol_ptr->is_shared() &&
(symbol_ptr != nullptr &&
symbol_ptr->is_shared() &&
!rd.get_is_dirty()(identifier))))
for(const auto &range : ranges)
kill(identifier, range.first, range.second);
Expand Down
8 changes: 6 additions & 2 deletions src/ansi-c/c_typecheck_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,11 +760,15 @@ void c_typecheck_baset::typecheck_declaration(
typet ret_type=empty_typet();
if(new_symbol.type.id()==ID_code)
ret_type=to_code_type(new_symbol.type).return_type();
assert(parameter_map.empty());
if(ret_type.id()!=ID_empty)
{
DATA_INVARIANT(
parameter_map.empty(), "parameter map should be cleared");
parameter_map["__CPROVER_return_value"]=ret_type;
}
typecheck_spec_expr(contract, ID_C_spec_ensures);
parameter_map.clear();
if(ret_type.id()!=ID_empty)
parameter_map.clear();

if(contract.find(ID_C_spec_requires).is_not_nil())
new_symbol.type.add(ID_C_spec_requires)=
Expand Down
7 changes: 3 additions & 4 deletions src/ansi-c/c_typecheck_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2139,11 +2139,10 @@ exprt c_typecheck_baset::do_special_functions(
throw 0;
}

exprt dynamic_object_expr=exprt(ID_dynamic_object, expr.type());
dynamic_object_expr.operands()=expr.arguments();
dynamic_object_expr.add_source_location()=source_location;
exprt is_dynamic_object_expr = is_dynamic_object_exprt(expr.arguments()[0]);
is_dynamic_object_expr.add_source_location() = source_location;

return dynamic_object_expr;
return is_dynamic_object_expr;
}
else if(identifier==CPROVER_PREFIX "POINTER_OFFSET")
{
Expand Down
4 changes: 2 additions & 2 deletions src/ansi-c/expr2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3580,8 +3580,8 @@ std::string expr2ct::convert_with_precedence(
else if(src.id()==ID_invalid_pointer)
return convert_function(src, "__CPROVER_invalid_pointer", precedence=16);

else if(src.id()==ID_dynamic_object)
return convert_function(src, "DYNAMIC_OBJECT", precedence=16);
else if(src.id()==ID_is_dynamic_object)
return convert_function(src, "IS_DYNAMIC_OBJECT", precedence=16);

else if(src.id()=="is_zero_string")
return convert_function(src, "IS_ZERO_STRING", precedence=16);
Expand Down
Loading