Skip to content

Commit 342a2c7

Browse files
authored
Merge pull request #1282 from diffblue/struct_decay
Verilog: introduce struct_decay and enum_decay methods
2 parents 10f9fc4 + 7a63580 commit 342a2c7

File tree

2 files changed

+60
-16
lines changed

2 files changed

+60
-16
lines changed

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,14 +1928,14 @@ void verilog_typecheck_exprt::implicit_typecast(
19281928
if(dest_type.id()==irep_idt())
19291929
return;
19301930

1931-
const typet &src_type = expr.type();
1932-
19331931
auto &verilog_dest_type = dest_type.get(ID_C_verilog_type);
19341932
if(verilog_dest_type == ID_verilog_enum)
19351933
{
19361934
// IEEE 1800-2017 6.19.3: "a variable of type enum cannot be directly
19371935
// assigned a value that lies outside the enumeration set unless an
19381936
// explicit cast is used"
1937+
const typet &src_type = expr.type();
1938+
19391939
if(
19401940
src_type.get(ID_C_verilog_type) != ID_verilog_enum ||
19411941
src_type.get(ID_C_identifier) != dest_type.get(ID_C_identifier))
@@ -1946,9 +1946,16 @@ void verilog_typecheck_exprt::implicit_typecast(
19461946
}
19471947
}
19481948

1949-
if(src_type == dest_type)
1949+
if(expr.type() == dest_type)
19501950
return;
19511951

1952+
// do enum, union and struct decay
1953+
enum_decay(expr);
1954+
struct_decay(expr);
1955+
union_decay(expr);
1956+
1957+
const typet &src_type = expr.type();
1958+
19521959
if(dest_type.id() == ID_integer)
19531960
{
19541961
if(expr.is_constant())
@@ -2072,19 +2079,6 @@ void verilog_typecheck_exprt::implicit_typecast(
20722079
return;
20732080
}
20742081
}
2075-
else if(src_type.id() == ID_struct || src_type.id() == ID_union)
2076-
{
2077-
// packed structs and packed unions can be converted to bits
2078-
if(
2079-
dest_type.id() == ID_bool || dest_type.id() == ID_unsignedbv ||
2080-
dest_type.id() == ID_signedbv ||
2081-
dest_type.id() == ID_verilog_unsignedbv ||
2082-
dest_type.id() == ID_verilog_signedbv)
2083-
{
2084-
expr = typecast_exprt{expr, dest_type};
2085-
return;
2086-
}
2087-
}
20882082
else if(src_type.id() == ID_verilog_assignment_pattern)
20892083
{
20902084
DATA_INVARIANT(
@@ -2312,6 +2306,28 @@ typet verilog_typecheck_exprt::enum_decay(const typet &type)
23122306

23132307
/*******************************************************************\
23142308
2309+
Function: verilog_typecheck_exprt::enum_decay
2310+
2311+
Inputs:
2312+
2313+
Outputs:
2314+
2315+
Purpose:
2316+
2317+
\*******************************************************************/
2318+
2319+
void verilog_typecheck_exprt::enum_decay(exprt &expr) const
2320+
{
2321+
// Verilog enum types decay to their base type when used in relational
2322+
// or arithmetic expressions.
2323+
if(expr.type().get(ID_C_verilog_type) == ID_verilog_enum)
2324+
{
2325+
expr = typecast_exprt{expr, enum_decay(expr.type())};
2326+
}
2327+
}
2328+
2329+
/*******************************************************************\
2330+
23152331
Function: verilog_typecheck_exprt::union_decay
23162332
23172333
Inputs:
@@ -2340,6 +2356,32 @@ void verilog_typecheck_exprt::union_decay(exprt &expr) const
23402356

23412357
/*******************************************************************\
23422358
2359+
Function: verilog_typecheck_exprt::struct_decay
2360+
2361+
Inputs:
2362+
2363+
Outputs:
2364+
2365+
Purpose:
2366+
2367+
\*******************************************************************/
2368+
2369+
void verilog_typecheck_exprt::struct_decay(exprt &expr) const
2370+
{
2371+
// 1800-2017 7.2.1
2372+
// Verilog packed struct types decay to a vector type [$bits(t)-1:0]
2373+
// when used in relational or arithmetic expressions.
2374+
auto &type = expr.type();
2375+
if(type.id() == ID_struct)
2376+
{
2377+
auto new_type =
2378+
unsignedbv_typet{numeric_cast_v<std::size_t>(get_width(type))};
2379+
expr = typecast_exprt{expr, new_type};
2380+
}
2381+
}
2382+
2383+
/*******************************************************************\
2384+
23432385
Function: verilog_typecheck_exprt::tc_binary_expr
23442386
23452387
Inputs:

src/verilog/verilog_typecheck_expr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,9 @@ class verilog_typecheck_exprt:public verilog_typecheck_baset
146146
}
147147

148148
static typet enum_decay(const typet &);
149+
void enum_decay(exprt &) const;
149150
void union_decay(exprt &) const;
151+
void struct_decay(exprt &) const;
150152
typet max_type(const typet &t1, const typet &t2);
151153

152154
// named blocks

0 commit comments

Comments
 (0)