Skip to content

Commit f2920da

Browse files
committed
Code contracts: match up introducing/removing parameter map modifications
Code contracts that introduce local declarations result in nested typecheck_declaration calls. The artificial __CPROVER_return_value symbol must then be added/removed by a single call only.
1 parent e8d26ae commit f2920da

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
int foo()
2+
__CPROVER_ensures(__CPROVER_forall {int i; 1 == 1})
3+
{
4+
return 1;
5+
}
6+
7+
int bar()
8+
__CPROVER_ensures(__CPROVER_forall {int i; 1 == 1} &&
9+
__CPROVER_return_value == 1)
10+
{
11+
return 1;
12+
}
13+
14+
int main() {
15+
foo();
16+
bar();
17+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
^CONVERSION ERROR$

src/ansi-c/c_typecheck_base.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,11 +758,15 @@ void c_typecheck_baset::typecheck_declaration(
758758
typet ret_type=empty_typet();
759759
if(new_symbol.type.id()==ID_code)
760760
ret_type=to_code_type(new_symbol.type).return_type();
761-
assert(parameter_map.empty());
762761
if(ret_type.id()!=ID_empty)
762+
{
763+
DATA_INVARIANT(
764+
parameter_map.empty(), "parameter map should be cleared");
763765
parameter_map["__CPROVER_return_value"]=ret_type;
766+
}
764767
typecheck_spec_expr(contract, ID_C_spec_ensures);
765-
parameter_map.clear();
768+
if(ret_type.id()!=ID_empty)
769+
parameter_map.clear();
766770

767771
if(contract.find(ID_C_spec_requires).is_not_nil())
768772
new_symbol.type.add(ID_C_spec_requires)=

0 commit comments

Comments
 (0)