Skip to content

Commit 29d432c

Browse files
authored
Merge pull request #7140 from diffblue/array_index_type
add index type to the array type
2 parents e64de21 + 80f9834 commit 29d432c

File tree

5 files changed

+40
-19
lines changed

5 files changed

+40
-19
lines changed

src/ansi-c/c_typecheck_type.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -524,21 +524,18 @@ void c_typecheck_baset::typecheck_code_type(code_typet &type)
524524

525525
void c_typecheck_baset::typecheck_array_type(array_typet &type)
526526
{
527-
exprt &size=type.size();
528-
const source_locationt size_source_location = size.find_source_location();
529-
530-
// check subtype
527+
// Typecheck the element type.
531528
typecheck_type(type.element_type());
532529

533-
// we don't allow void as subtype
530+
// We don't allow void as the element type.
534531
if(type.element_type().id() == ID_empty)
535532
{
536533
error().source_location=type.source_location();
537534
error() << "array of voids" << eom;
538535
throw 0;
539536
}
540537

541-
// we don't allow incomplete structs or unions as subtype
538+
// We don't allow incomplete structs or unions as element type.
542539
const typet &followed_subtype = follow(type.element_type());
543540

544541
if(
@@ -551,7 +548,7 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type)
551548
throw 0;
552549
}
553550

554-
// we don't allow functions as subtype
551+
// We don't allow functions as element type.
555552
if(type.element_type().id() == ID_code)
556553
{
557554
// ISO/IEC 9899 6.7.5.2
@@ -560,10 +557,14 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type)
560557
throw 0;
561558
}
562559

563-
// check size, if any
560+
// We add the index type.
561+
type.index_type_nonconst() = c_index_type();
564562

565-
if(size.is_not_nil())
563+
// Check the array size, if given.
564+
if(type.is_complete())
566565
{
566+
exprt &size = type.size();
567+
const source_locationt size_source_location = size.find_source_location();
567568
typecheck_expr(size);
568569
make_index_type(size);
569570

src/solvers/smt2/smt2_conv.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3097,7 +3097,7 @@ void smt2_convt::flatten_array(const exprt &expr)
30973097
if(i!=1)
30983098
out << "(concat ";
30993099
out << "(select ?far ";
3100-
convert_expr(from_integer(i-1, array_type.size().type()));
3100+
convert_expr(from_integer(i - 1, array_type.index_type()));
31013101
out << ")";
31023102
if(i!=1)
31033103
out << " ";
@@ -4041,7 +4041,7 @@ void smt2_convt::convert_with(const with_exprt &expr)
40414041
out << "(store ";
40424042
convert_expr(expr.old());
40434043
out << " ";
4044-
convert_expr(typecast_exprt(expr.where(), array_type.size().type()));
4044+
convert_expr(typecast_exprt(expr.where(), array_type.index_type()));
40454045
out << " ";
40464046
convert_expr(expr.new_value());
40474047
out << ")";
@@ -4267,7 +4267,7 @@ void smt2_convt::convert_index(const index_exprt &expr)
42674267
out << "(select ";
42684268
convert_expr(expr.array());
42694269
out << " ";
4270-
convert_expr(typecast_exprt(expr.index(), array_type.size().type()));
4270+
convert_expr(typecast_exprt(expr.index(), array_type.index_type()));
42714271
out << ")";
42724272
out << " #b1)";
42734273
}
@@ -4276,7 +4276,7 @@ void smt2_convt::convert_index(const index_exprt &expr)
42764276
out << "(select ";
42774277
convert_expr(expr.array());
42784278
out << " ";
4279-
convert_expr(typecast_exprt(expr.index(), array_type.size().type()));
4279+
convert_expr(typecast_exprt(expr.index(), array_type.index_type()));
42804280
out << ")";
42814281
}
42824282
}
@@ -4891,7 +4891,7 @@ void smt2_convt::find_symbols(const exprt &expr)
48914891

48924892
// use a quantifier-based initialization instead of lambda
48934893
out << "(assert (forall ((i ";
4894-
convert_type(array_type.size().type());
4894+
convert_type(array_type.index_type());
48954895
out << ")) (= (select " << id << " i) ";
48964896
if(array_type.element_type().id() == ID_bool && !use_array_of_bool)
48974897
{
@@ -4972,7 +4972,7 @@ void smt2_convt::find_symbols(const exprt &expr)
49724972
for(std::size_t i=0; i<expr.operands().size(); i++)
49734973
{
49744974
out << "(assert (= (select " << id << " ";
4975-
convert_expr(from_integer(i, array_type.size().type()));
4975+
convert_expr(from_integer(i, array_type.index_type()));
49764976
out << ") "; // select
49774977
if(array_type.element_type().id() == ID_bool && !use_array_of_bool)
49784978
{
@@ -5008,7 +5008,7 @@ void smt2_convt::find_symbols(const exprt &expr)
50085008
for(std::size_t i=0; i<tmp.operands().size(); i++)
50095009
{
50105010
out << "(assert (= (select " << id << ' ';
5011-
convert_expr(from_integer(i, array_type.size().type()));
5011+
convert_expr(from_integer(i, array_type.index_type()));
50125012
out << ") "; // select
50135013
convert_expr(tmp.operands()[i]);
50145014
out << "))" << "\n";
@@ -5127,8 +5127,9 @@ void smt2_convt::convert_type(const typet &type)
51275127
// we always use array theory for top-level arrays
51285128
const typet &subtype = array_type.element_type();
51295129

5130+
// Arrays map the index type to the element type.
51305131
out << "(Array ";
5131-
convert_type(array_type.size().type());
5132+
convert_type(array_type.index_type());
51325133
out << " ";
51335134

51345135
if(subtype.id()==ID_bool && !use_array_of_bool)

src/util/irep_ids.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ IREP_ID_ONE(return)
101101
IREP_ID_ONE(skip)
102102
IREP_ID_ONE(arguments)
103103
IREP_ID_ONE(array)
104+
IREP_ID_TWO(C_index_type, #index_type)
104105
IREP_ID_ONE(size)
105106
IREP_ID_ONE(frontend_pointer)
106107
IREP_ID_ONE(pointer)

src/util/std_types.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,14 @@ void array_typet::check(const typet &type, const validation_modet vm)
3232

3333
typet array_typet::index_type() const
3434
{
35-
// we may wish to make the index type part of the array type
36-
return c_index_type();
35+
// For backwards compatibility, allow the case that the array type is
36+
// not annotated with an index type.
37+
const auto &annotated_type =
38+
static_cast<const typet &>(find(ID_C_index_type));
39+
if(annotated_type.is_nil())
40+
return c_index_type();
41+
else
42+
return annotated_type;
3743
}
3844

3945
/// Return the sequence number of the component with given name.

src/util/std_types.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,14 @@ class array_typet:public type_with_subtypet
771771
/// The type of the index expressions into any instance of this type.
772772
typet index_type() const;
773773

774+
/// The type of the index expressions into any instance of this type.
775+
/// This is added as a comment now for backwards compatibility, but will
776+
/// eventually be the first subtype.
777+
typet &index_type_nonconst()
778+
{
779+
return static_cast<typet &>(add(ID_C_index_type));
780+
}
781+
774782
/// The type of the elements of the array.
775783
/// This method is preferred over .subtype(),
776784
/// which will eventually be deprecated.
@@ -787,11 +795,15 @@ class array_typet:public type_with_subtypet
787795
return subtype();
788796
}
789797

798+
// We will eventually enforce that the type of the size
799+
// is the same as the index type.
790800
const exprt &size() const
791801
{
792802
return static_cast<const exprt &>(find(ID_size));
793803
}
794804

805+
// We will eventually enforce that the type of the size
806+
// is the same as the index type.
795807
exprt &size()
796808
{
797809
return static_cast<exprt &>(add(ID_size));

0 commit comments

Comments
 (0)