Skip to content

Commit 934f310

Browse files
author
Daniel Kroening
committed
C/C++ now have frontend_vector type
This enables distinguishing the case of a size that is an arbitary expression from the case where the size is required to be constant.
1 parent 4aa485f commit 934f310

File tree

6 files changed

+35
-16
lines changed

6 files changed

+35
-16
lines changed

src/ansi-c/ansi_c_convert_type.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,8 @@ void ansi_c_convert_typet::write(typet &type)
591591

592592
if(vector_size.is_not_nil())
593593
{
594-
vector_typet new_type(type, vector_size);
594+
type_with_subtypet new_type(ID_frontend_vector, type);
595+
new_type.set(ID_size, vector_size);
595596
new_type.add_source_location()=vector_size.source_location();
596597
type=new_type;
597598
}

src/ansi-c/c_typecheck_base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ class c_typecheck_baset:
213213
virtual void typecheck_c_bit_field_type(c_bit_field_typet &type);
214214
virtual void typecheck_typeof_type(typet &type);
215215
virtual void typecheck_array_type(array_typet &type);
216-
virtual void typecheck_vector_type(vector_typet &type);
216+
virtual void typecheck_vector_type(typet &type);
217217
virtual void typecheck_custom_type(typet &type);
218218
virtual void adjust_function_parameter(typet &type) const;
219219
virtual bool is_complete_type(const typet &type) const;

src/ansi-c/c_typecheck_type.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,13 @@ void c_typecheck_baset::typecheck_type(typet &type)
9999
// nothing to do, these stay as is
100100
}
101101
else if(type.id()==ID_vector)
102-
typecheck_vector_type(to_vector_type(type));
102+
{
103+
// already done
104+
}
105+
else if(type.id() == ID_frontend_vector)
106+
{
107+
typecheck_vector_type(type);
108+
}
103109
else if(type.id()==ID_custom_unsignedbv ||
104110
type.id()==ID_custom_signedbv ||
105111
type.id()==ID_custom_floatbv ||
@@ -655,14 +661,17 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type)
655661
}
656662
}
657663

658-
void c_typecheck_baset::typecheck_vector_type(vector_typet &type)
664+
void c_typecheck_baset::typecheck_vector_type(typet &type)
659665
{
660-
exprt &size=type.size();
661-
source_locationt source_location=size.find_source_location();
666+
// This turns the type with ID_frontend_vector into the type
667+
// with ID_vector; the difference is that the latter has
668+
// a constant as size, which we establish now.
669+
exprt size = static_cast<const exprt &>(type.find(ID_size));
670+
const source_locationt source_location = size.find_source_location();
662671

663672
typecheck_expr(size);
664673

665-
typet &subtype=type.subtype();
674+
typet subtype = type.subtype();
666675
typecheck_type(subtype);
667676

668677
// we are willing to combine 'vector' with various
@@ -699,25 +708,24 @@ void c_typecheck_baset::typecheck_vector_type(vector_typet &type)
699708
}
700709

701710
// the subtype must have constant size
702-
exprt size_expr=size_of_expr(type.subtype(), *this);
711+
exprt sub_size_expr = size_of_expr(subtype, *this);
703712

704-
simplify(size_expr, *this);
713+
simplify(sub_size_expr, *this);
705714

706-
const auto sub_size = numeric_cast<mp_integer>(size_expr);
715+
const auto sub_size = numeric_cast<mp_integer>(sub_size_expr);
707716

708717
if(!sub_size.has_value())
709718
{
710719
error().source_location=source_location;
711720
error() << "failed to determine size of vector base type `"
712-
<< to_string(type.subtype()) << "'" << eom;
721+
<< to_string(subtype) << "'" << eom;
713722
throw 0;
714723
}
715724

716725
if(*sub_size == 0)
717726
{
718727
error().source_location=source_location;
719-
error() << "type had size 0: `"
720-
<< to_string(type.subtype()) << "'" << eom;
728+
error() << "type had size 0: `" << to_string(subtype) << "'" << eom;
721729
throw 0;
722730
}
723731

@@ -733,7 +741,11 @@ void c_typecheck_baset::typecheck_vector_type(vector_typet &type)
733741

734742
s /= *sub_size;
735743

736-
type.size()=from_integer(s, signed_size_type());
744+
// produce the type with ID_vector
745+
vector_typet new_type(subtype, from_integer(s, signed_size_type()));
746+
new_type.add_source_location() = source_location;
747+
new_type.size().add_source_location() = source_location;
748+
type = new_type;
737749
}
738750

739751
void c_typecheck_baset::typecheck_compound_type(struct_union_typet &type)

src/cpp/cpp_typecheck_type.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,11 @@ void cpp_typecheckt::typecheck_type(typet &type)
142142
}
143143
else if(type.id()==ID_vector)
144144
{
145-
typecheck_vector_type(to_vector_type(type));
145+
// already done
146+
}
147+
else if(type.id() == ID_frontend_vector)
148+
{
149+
typecheck_vector_type(type);
146150
}
147151
else if(type.id()==ID_code)
148152
{

src/cpp/parse.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2206,7 +2206,8 @@ bool Parser::rAttribute(typet &t)
22062206
if(lex.get_token(tk3)!=')')
22072207
return false;
22082208

2209-
vector_typet attr(uninitialized_typet{}, exp);
2209+
type_with_subtypet attr(ID_frontend_vector, uninitialized_typet{});
2210+
attr.set(ID_size, exp);
22102211
attr.add_source_location()=exp.source_location();
22112212
merge_types(attr, t);
22122213
break;

src/util/irep_ids.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ IREP_ID_ONE(transparent_union)
470470
IREP_ID_TWO(C_transparent_union, #transparent_union)
471471
IREP_ID_ONE(aligned)
472472
IREP_ID_TWO(C_alignment, #alignment)
473+
IREP_ID_ONE(frontend_vector)
473474
IREP_ID_ONE(vector)
474475
IREP_ID_ONE(abstract)
475476
IREP_ID_ONE(function_application)

0 commit comments

Comments
 (0)