Skip to content

Commit 2a9d14c

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 5dd9b8c commit 2a9d14c

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"
@@ -787,7 +788,7 @@ void c_typecheck_baset::typecheck_declaration(
787788

788789
// ensure parameter declarations are available for type checking to
789790
// succeed
790-
std::vector<symbol_exprt> temporary_parameter_symbols;
791+
binding_exprt::variablest temporary_parameter_symbols;
791792

792793
const auto &return_type = code_type.return_type();
793794
if(return_type.id() != ID_empty)
@@ -822,16 +823,28 @@ void c_typecheck_baset::typecheck_declaration(
822823
{
823824
typecheck_spec_function_pointer_obeys_contract(expr);
824825
check_history_expr(expr);
826+
lambda_exprt lambda{temporary_parameter_symbols, expr};
827+
lambda.add_source_location() = expr.source_location();
828+
expr.swap(lambda);
825829
}
826830

827831
for(auto &requires : code_type.requires())
828832
{
829833
typecheck_expr(requires);
830834
implicit_typecast_bool(requires);
831835
check_history_expr(requires);
836+
lambda_exprt lambda{temporary_parameter_symbols, requires};
837+
lambda.add_source_location() = requires.source_location();
838+
requires.swap(lambda);
832839
}
833840

834841
typecheck_spec_assigns(code_type.assigns());
842+
for(auto &assigns : code_type.assigns())
843+
{
844+
lambda_exprt lambda{temporary_parameter_symbols, assigns};
845+
lambda.add_source_location() = assigns.source_location();
846+
assigns.swap(lambda);
847+
}
835848

836849
for(auto &expr : code_type.ensures_contract())
837850
{
@@ -840,6 +853,9 @@ void c_typecheck_baset::typecheck_declaration(
840853
expr,
841854
ID_loop_entry,
842855
CPROVER_PREFIX "loop_entry is not allowed in postconditions.");
856+
lambda_exprt lambda{temporary_parameter_symbols, expr};
857+
lambda.add_source_location() = expr.source_location();
858+
expr.swap(lambda);
843859
}
844860

845861
for(auto &ensures : code_type.ensures())
@@ -850,6 +866,9 @@ void c_typecheck_baset::typecheck_declaration(
850866
ensures,
851867
ID_loop_entry,
852868
CPROVER_PREFIX "loop_entry is not allowed in postconditions.");
869+
lambda_exprt lambda{temporary_parameter_symbols, ensures};
870+
lambda.add_source_location() = ensures.source_location();
871+
ensures.swap(lambda);
853872
}
854873

855874
for(const auto &parameter_sym : temporary_parameter_symbols)

0 commit comments

Comments
 (0)