Skip to content

Commit 943409b

Browse files
committed
Cleans-up the implementation to support assigns clauses
Signed-off-by: Felipe R. Monteiro <[email protected]>
1 parent 9678a3d commit 943409b

File tree

4 files changed

+42
-45
lines changed

4 files changed

+42
-45
lines changed

src/ansi-c/c_typecheck_code.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -814,14 +814,14 @@ void c_typecheck_baset::typecheck_assigns(
814814
// Make sure there is an assigns clause to check
815815
if(assigns.is_not_nil())
816816
{
817-
for(code_typet::parametert curr_param : function_declarator.parameters())
817+
for(const auto &curr_param : function_declarator.parameters())
818818
{
819819
if(curr_param.id() == ID_declaration)
820820
{
821-
ansi_c_declarationt &param_declaration =
821+
const ansi_c_declarationt &param_declaration =
822822
to_ansi_c_declaration(curr_param);
823823

824-
for(auto &decl : param_declaration.declarators())
824+
for(const auto &decl : param_declaration.declarators())
825825
{
826826
typecheck_assigns(decl, assigns);
827827
}

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,7 @@ void c_typecheck_baset::typecheck_expr_main(exprt &expr)
477477
else
478478
{
479479
error().source_location = expr.source_location();
480-
error() << "expression categorized improperly during parsing: "
481-
<< expr.pretty() << eom;
480+
error() << "unexpected expression: " << expr.pretty() << eom;
482481
throw 0;
483482
}
484483
}

src/goto-instrument/code_contracts.cpp

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,7 @@ Date: February 2016
1111
/// \file
1212
/// Verify and use annotated invariants and pre/post-conditions
1313

14-
#include "code_contracts.h"
15-
#include "loop_utils.h"
16-
1714
#include <algorithm>
18-
#include <cstring>
19-
#include <iostream>
2015
#include <unordered_set>
2116

2217
#include <analyses/local_may_alias.h>
@@ -32,6 +27,9 @@ Date: February 2016
3227
#include <util/pointer_predicates.h>
3328
#include <util/replace_symbol.h>
3429

30+
#include "code_contracts.h"
31+
#include "loop_utils.h"
32+
3533
/// Predicate to be used with the exprt::visit() function. The function
3634
/// found_return_value() will return `true` iff this predicate is called on an
3735
/// expr that contains `__CPROVER_return_value`.
@@ -70,12 +68,15 @@ static void check_apply_invariants(
7068
PRECONDITION(!loop.empty());
7169

7270
// find the last back edge
73-
goto_programt::targett loop_end = loop_head;
74-
for(loopt::const_iterator it = loop.begin(); it != loop.end(); ++it)
75-
if(
76-
(*it)->is_goto() && (*it)->get_target() == loop_head &&
77-
(*it)->location_number > loop_end->location_number)
78-
loop_end = *it;
71+
goto_programt::targett loop_end=loop_head;
72+
for(loopt::const_iterator
73+
it=loop.begin();
74+
it!=loop.end();
75+
++it)
76+
if((*it)->is_goto() &&
77+
(*it)->get_target()==loop_head &&
78+
(*it)->location_number>loop_end->location_number)
79+
loop_end=*it;
7980

8081
// see whether we have an invariant
8182
exprt invariant = static_cast<const exprt &>(
@@ -138,7 +139,7 @@ static void check_apply_invariants(
138139

139140
// change the back edge into assume(false) or assume(guard)
140141
loop_end->targets.clear();
141-
loop_end->type = ASSUME;
142+
loop_end->type=ASSUME;
142143
if(loop_head->is_goto())
143144
loop_end->set_condition(false_exprt());
144145
else
@@ -149,10 +150,11 @@ bool code_contractst::has_contract(const irep_idt fun_name)
149150
{
150151
const symbolt &function_symbol = ns.lookup(fun_name);
151152
const code_typet &type = to_code_type(function_symbol.type);
152-
const irept assigns = type.find(ID_C_spec_assigns);
153-
const irept ensures = type.find(ID_C_spec_ensures);
153+
if(type.find(ID_C_spec_assigns).is_not_nil())
154+
return true;
154155

155-
return ensures.is_not_nil() || assigns.is_not_nil();
156+
return type.find(ID_C_spec_requires).is_not_nil() ||
157+
type.find(ID_C_spec_ensures).is_not_nil();
156158
}
157159

158160
bool code_contractst::apply_contract(
@@ -223,7 +225,7 @@ bool code_contractst::apply_contract(
223225
}
224226

225227
// Replace formal parameters
226-
code_function_callt::argumentst::const_iterator a_it =
228+
code_function_callt::argumentst::const_iterator a_it=
227229
call.arguments().begin();
228230
for(code_typet::parameterst::const_iterator p_it = type.parameters().begin();
229231
p_it != type.parameters().end() && a_it != call.arguments().end();
@@ -260,11 +262,7 @@ bool code_contractst::apply_contract(
260262
const exprt::operandst &targets = assigns.operands();
261263
for(const exprt &curr_op : targets)
262264
{
263-
if(curr_op.id() == ID_symbol)
264-
{
265-
assigns_tgts.insert(curr_op);
266-
}
267-
else if(curr_op.id() == ID_dereference)
265+
if(curr_op.id() == ID_symbol || curr_op.id() == ID_dereference)
268266
{
269267
assigns_tgts.insert(curr_op);
270268
}
@@ -335,7 +333,7 @@ const symbolt &code_contractst::new_tmp_symbol(
335333
symbol_table);
336334
}
337335

338-
exprt create_alias_expression(
336+
static exprt create_alias_expression(
339337
const exprt &assigns,
340338
const exprt &lhs,
341339
std::vector<exprt> &aliasable_references)
@@ -344,9 +342,9 @@ exprt create_alias_expression(
344342
exprt running = false_exprt();
345343
for(auto aliasable : aliasable_references)
346344
{
347-
exprt leftPtr = address_of_exprt{lhs};
348-
exprt rightPtr = aliasable;
349-
exprt same = same_object(leftPtr, rightPtr);
345+
exprt left_ptr = address_of_exprt{lhs};
346+
exprt right_ptr = aliasable;
347+
exprt same = same_object(left_ptr, right_ptr);
350348

351349
if(first_iter)
352350
{
@@ -372,13 +370,12 @@ void code_contractst::populate_assigns_references(
372370
std::vector<exprt> &created_references)
373371
{
374372
const code_typet &type = to_code_type(function_symbol.type);
375-
exprt assigns = static_cast<const exprt &>(type.find(ID_C_spec_assigns));
373+
const exprt &assigns =
374+
static_cast<const exprt &>(type.find(ID_C_spec_assigns));
376375

377-
exprt::operandst &targets = assigns.operands();
378-
for(exprt curr_op : targets)
376+
const exprt::operandst &targets = assigns.operands();
377+
for(const exprt &curr_op : targets)
379378
{
380-
exprt op_addr = address_of_exprt{curr_op};
381-
382379
// Declare a new symbol to stand in for the reference
383380
symbol_exprt standin = new_tmp_symbol(
384381
pointer_type(curr_op.type()),
@@ -391,14 +388,15 @@ void code_contractst::populate_assigns_references(
391388
goto_programt::make_decl(standin, function_symbol.location));
392389

393390
created_decls.add(goto_programt::make_assignment(
394-
code_assignt(standin, std::move(op_addr)), function_symbol.location));
391+
code_assignt(standin, std::move(address_of_exprt{curr_op})),
392+
function_symbol.location));
395393

396394
// Add a map entry from the original operand to the new symbol
397395
created_references.push_back(standin);
398396
}
399397
}
400398

401-
void code_contractst::instrument_assn_statement(
399+
void code_contractst::instrument_assigns_statement(
402400
goto_programt::instructionst::iterator &instruction_iterator,
403401
goto_programt &program,
404402
exprt &assigns,
@@ -407,7 +405,7 @@ void code_contractst::instrument_assn_statement(
407405
{
408406
INVARIANT(
409407
instruction_iterator->is_assign(),
410-
"The first argument of instrument_assn_statement should always be"
408+
"The first argument of instrument_assigns_statement should always be"
411409
" an assignment");
412410
const exprt &lhs = instruction_iterator->get_assign().lhs();
413411
if(freely_assignable_exprs.find(lhs) != freely_assignable_exprs.end())
@@ -569,7 +567,7 @@ bool code_contractst::check_for_looped_mallocs(const goto_programt &program)
569567
const irep_idt &called_name =
570568
to_symbol_expr(call.function()).get_identifier();
571569

572-
if(std::strcmp(called_name.c_str(), "malloc") == 0)
570+
if(called_name == "malloc")
573571
{
574572
malloc_calls.push_back(instruction);
575573
}
@@ -666,15 +664,15 @@ bool code_contractst::add_pointer_checks(const std::string &function_name)
666664

667665
// Insert aliasing assertions
668666
for(; instruction_iterator != program.instructions.end();
669-
std::advance(instruction_iterator, 1))
667+
++instruction_iterator)
670668
{
671669
if(instruction_iterator->is_decl())
672670
{
673671
freely_assignable_exprs.insert(instruction_iterator->get_decl().symbol());
674672
}
675673
else if(instruction_iterator->is_assign())
676674
{
677-
instrument_assn_statement(
675+
instrument_assigns_statement(
678676
instruction_iterator,
679677
program,
680678
assigns,
@@ -779,7 +777,7 @@ void code_contractst::add_contract_check(
779777
static_cast<const exprt &>(gf.type.find(ID_C_spec_ensures));
780778
INVARIANT(
781779
ensures.is_not_nil() || assigns.is_not_nil(),
782-
"Code conract enforcement is trivial without an ensures or assigns "
780+
"Code contract enforcement is trivial without an ensures or assigns "
783781
"clause.");
784782

785783
// build:
@@ -810,7 +808,7 @@ void code_contractst::add_contract_check(
810808
replace_symbolt replace;
811809

812810
// decl ret
813-
if(gf.type.return_type() != empty_typet())
811+
if(gf.type.return_type()!=empty_typet())
814812
{
815813
symbol_exprt r = new_tmp_symbol(
816814
gf.type.return_type(),
@@ -820,7 +818,7 @@ void code_contractst::add_contract_check(
820818
.symbol_expr();
821819
check.add(goto_programt::make_decl(r, skip->source_location));
822820

823-
call.lhs() = r;
821+
call.lhs()=r;
824822

825823
symbol_exprt ret_val(CPROVER_PREFIX "return_value", call.lhs().type());
826824
replace.insert(ret_val, r);

src/goto-instrument/code_contracts.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class code_contractst
104104
/// to ensure that the left-hand-side of the assignment aliases some
105105
/// expression in original_references, unless it is contained in
106106
/// freely_assignable_exprs.
107-
void instrument_assn_statement(
107+
void instrument_assigns_statement(
108108
goto_programt::instructionst::iterator &ins_it,
109109
goto_programt &program,
110110
exprt &assigns,

0 commit comments

Comments
 (0)