Skip to content

Commit a3f9db2

Browse files
committed
Wrap contract expressions in a lambda
This makes sure contracts are self-contained in that any parameter names that may have only existed in the scope of a function declaration are now bound variables.
1 parent 281f750 commit a3f9db2

File tree

3 files changed

+111
-70
lines changed

3 files changed

+111
-70
lines changed

src/ansi-c/c_typecheck_base.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Author: Daniel Kroening, [email protected]
1414
#include <util/c_types.h>
1515
#include <util/config.h>
1616
#include <util/expr_util.h>
17+
#include <util/mathematical_expr.h>
1718
#include <util/std_types.h>
1819

1920
#include "ansi_c_declaration.h"
@@ -745,7 +746,7 @@ void c_typecheck_baset::typecheck_declaration(
745746

746747
// ensure parameter declarations are available for type checking to
747748
// succeed
748-
std::vector<symbol_exprt> temporary_parameter_symbols;
749+
binding_exprt::variablest temporary_parameter_symbols;
749750

750751
const auto &return_type = code_type.return_type();
751752
if(return_type.id() != ID_empty)
@@ -780,16 +781,28 @@ void c_typecheck_baset::typecheck_declaration(
780781
{
781782
typecheck_spec_function_pointer_obeys_contract(expr);
782783
check_history_expr(expr);
784+
lambda_exprt lambda{temporary_parameter_symbols, expr};
785+
lambda.add_source_location() = expr.source_location();
786+
expr.swap(lambda);
783787
}
784788

785789
for(auto &requires : code_type.requires())
786790
{
787791
typecheck_expr(requires);
788792
implicit_typecast_bool(requires);
789793
check_history_expr(requires);
794+
lambda_exprt lambda{temporary_parameter_symbols, requires};
795+
lambda.add_source_location() = requires.source_location();
796+
requires.swap(lambda);
790797
}
791798

792799
typecheck_spec_assigns(code_type.assigns());
800+
for(auto &assigns : code_type.assigns())
801+
{
802+
lambda_exprt lambda{temporary_parameter_symbols, assigns};
803+
lambda.add_source_location() = assigns.source_location();
804+
assigns.swap(lambda);
805+
}
793806

794807
for(auto &expr : code_type.ensures_contract())
795808
{
@@ -798,6 +811,9 @@ void c_typecheck_baset::typecheck_declaration(
798811
expr,
799812
ID_loop_entry,
800813
CPROVER_PREFIX "loop_entry is not allowed in postconditions.");
814+
lambda_exprt lambda{temporary_parameter_symbols, expr};
815+
lambda.add_source_location() = expr.source_location();
816+
expr.swap(lambda);
801817
}
802818

803819
for(auto &ensures : code_type.ensures())
@@ -808,6 +824,9 @@ void c_typecheck_baset::typecheck_declaration(
808824
ensures,
809825
ID_loop_entry,
810826
CPROVER_PREFIX "loop_entry is not allowed in postconditions.");
827+
lambda_exprt lambda{temporary_parameter_symbols, ensures};
828+
lambda.add_source_location() = ensures.source_location();
829+
ensures.swap(lambda);
811830
}
812831

813832
for(const auto &parameter_sym : temporary_parameter_symbols)

0 commit comments

Comments
 (0)