Skip to content

Commit 0430313

Browse files
committed
introduce __CPROVER_map type
This introduces C syntax for a type __CPROVER_map(domain, codomain) where domain is a list of types and codomain is a type. The type is internal, for modeling purposes within our own library only, and hence not added to user-facing documentation. It replaces arrays with size __CPROVER_infinity, which are now deprecated.
1 parent e186314 commit 0430313

File tree

8 files changed

+79
-2
lines changed

8 files changed

+79
-2
lines changed

regression/cbmc/map-type/basic1.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
int main()
2+
{
3+
__CPROVER_map(int, int) my_map;
4+
5+
my_map[1] = 10;
6+
my_map[2] = 20;
7+
8+
__CPROVER_assert(my_map[1] == 10, "[1]");
9+
__CPROVER_assert(my_map[2] == 20, "[2]");
10+
}

regression/cbmc/map-type/basic1.desc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
basic1.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/ansi-c/c_typecheck_base.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Author: Daniel Kroening, [email protected]
2323

2424
class ansi_c_declarationt;
2525
class c_bit_field_typet;
26+
class mathematical_function_typet;
2627
class shift_exprt;
2728

2829
class c_typecheck_baset:
@@ -261,6 +262,7 @@ class c_typecheck_baset:
261262
virtual void typecheck_code_type(code_typet &type);
262263
virtual void typecheck_typedef_type(typet &type);
263264
virtual void typecheck_c_bit_field_type(c_bit_field_typet &type);
265+
virtual void typecheck_map_type(mathematical_function_typet &);
264266
virtual void typecheck_typeof_type(typet &type);
265267
virtual void typecheck_array_type(array_typet &type);
266268
virtual void typecheck_vector_type(typet &type);

src/ansi-c/c_typecheck_type.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ void c_typecheck_baset::typecheck_type(typet &type)
111111
{
112112
typecheck_vector_type(type);
113113
}
114+
else if(type.id() == ID_mathematical_function)
115+
{
116+
typecheck_map_type(to_mathematical_function_type(type));
117+
}
114118
else if(type.id()==ID_custom_unsignedbv ||
115119
type.id()==ID_custom_signedbv ||
116120
type.id()==ID_custom_floatbv ||
@@ -726,6 +730,14 @@ void c_typecheck_baset::typecheck_vector_type(typet &type)
726730
type = new_type.with_source_location(source_location);
727731
}
728732

733+
void c_typecheck_baset::typecheck_map_type(mathematical_function_typet &type)
734+
{
735+
for(auto &t : type.domain())
736+
typecheck_type(t);
737+
738+
typecheck_type(type.codomain());
739+
}
740+
729741
void c_typecheck_baset::typecheck_compound_type(struct_union_typet &type)
730742
{
731743
// These get replaced by symbol types later.

src/ansi-c/expr2c.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,28 @@ std::string expr2ct::convert_rec(
612612

613613
return q+dest+d;
614614
}
615+
else if(src.id() == ID_mathematical_function)
616+
{
617+
const mathematical_function_typet &function_type =
618+
to_mathematical_function_type(src);
619+
std::string dest = CPROVER_PREFIX "map(";
620+
bool first = true;
621+
for(auto &t : function_type.domain())
622+
{
623+
if(first)
624+
first = false;
625+
else
626+
dest += ", ";
627+
628+
dest += convert(t);
629+
}
630+
631+
dest += ", ";
632+
dest += convert(function_type.codomain());
633+
dest += ")";
634+
635+
return q + dest + d;
636+
}
615637
else if(src.id()==ID_constructor ||
616638
src.id()==ID_destructor)
617639
{

src/ansi-c/parser.y

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ int yyansi_cerror(const std::string &error);
206206
%token TOK_CPROVER_BITVECTOR "__CPROVER_bitvector"
207207
%token TOK_CPROVER_FLOATBV "__CPROVER_floatbv"
208208
%token TOK_CPROVER_FIXEDBV "__CPROVER_fixedbv"
209+
%token TOK_CPROVER_MAP "__CPROVER_map"
209210
%token TOK_CPROVER_ATOMIC "__CPROVER_atomic"
210211
%token TOK_CPROVER_BOOL "__CPROVER_bool"
211212
%token TOK_CPROVER_THROW "__CPROVER_throw"
@@ -1111,6 +1112,7 @@ type_specifier:
11111112
| typedef_type_specifier
11121113
| typeof_type_specifier
11131114
| atomic_type_specifier
1115+
| map_type_specifier
11141116
;
11151117

11161118
declaration_qualifier_list:
@@ -1554,6 +1556,18 @@ array_of_construct:
15541556
{ $$=$1; stack_type($$).add_subtype().swap(parser_stack($2)); }
15551557
;
15561558

1559+
map_type_specifier:
1560+
TOK_CPROVER_MAP '(' type_specifier ',' type_specifier ')'
1561+
{
1562+
$$=$1;
1563+
parser_stack($$).id(ID_mathematical_function);
1564+
irept domain{ID_tuple};
1565+
domain.move_to_sub(parser_stack($3));
1566+
parser_stack($$).move_to_sub(domain);
1567+
mts($$, $5);
1568+
}
1569+
;
1570+
15571571
pragma_packed:
15581572
{
15591573
init($$);

src/ansi-c/scanner.l

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,7 @@ __decltype { if(PARSER.cpp98 &&
13241324
{CPROVER_PREFIX}"bitvector" { loc(); return TOK_CPROVER_BITVECTOR; }
13251325
{CPROVER_PREFIX}"floatbv" { loc(); return TOK_CPROVER_FLOATBV; }
13261326
{CPROVER_PREFIX}"fixedbv" { loc(); return TOK_CPROVER_FIXEDBV; }
1327+
{CPROVER_PREFIX}"map" { loc(); return TOK_CPROVER_MAP; }
13271328
{CPROVER_PREFIX}"bool" { loc(); return TOK_CPROVER_BOOL; }
13281329
{CPROVER_PREFIX}"throw" { loc(); return TOK_CPROVER_THROW; }
13291330
{CPROVER_PREFIX}"catch" { loc(); return TOK_CPROVER_CATCH; }

src/util/mathematical_types.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,21 @@ class mathematical_function_typet : public type_with_subtypest
7373
{
7474
public:
7575
// the domain of the function is composed of zero, one, or
76-
// many variables, given by their type
76+
// many arguments, given by their type
7777
using domaint = std::vector<typet>;
7878

7979
mathematical_function_typet(const domaint &_domain, const typet &_codomain)
8080
: type_with_subtypest(
8181
ID_mathematical_function,
82-
{type_with_subtypest(irep_idt(), _domain), _codomain})
82+
{type_with_subtypest(irep_idt{ID_tuple}, _domain), _codomain})
83+
{
84+
}
85+
86+
// sort-hand for the 1-tuple domain
87+
mathematical_function_typet(const typet &_domain, const typet &_codomain)
88+
: type_with_subtypest(
89+
ID_mathematical_function,
90+
{type_with_subtypest(irep_idt{ID_tuple}, {_domain}), _codomain})
8391
{
8492
}
8593

0 commit comments

Comments
 (0)