@@ -1928,14 +1928,14 @@ void verilog_typecheck_exprt::implicit_typecast(
1928
1928
if (dest_type.id ()==irep_idt ())
1929
1929
return ;
1930
1930
1931
- const typet &src_type = expr.type ();
1932
-
1933
1931
auto &verilog_dest_type = dest_type.get (ID_C_verilog_type);
1934
1932
if (verilog_dest_type == ID_verilog_enum)
1935
1933
{
1936
1934
// IEEE 1800-2017 6.19.3: "a variable of type enum cannot be directly
1937
1935
// assigned a value that lies outside the enumeration set unless an
1938
1936
// explicit cast is used"
1937
+ const typet &src_type = expr.type ();
1938
+
1939
1939
if (
1940
1940
src_type.get (ID_C_verilog_type) != ID_verilog_enum ||
1941
1941
src_type.get (ID_C_identifier) != dest_type.get (ID_C_identifier))
@@ -1946,9 +1946,16 @@ void verilog_typecheck_exprt::implicit_typecast(
1946
1946
}
1947
1947
}
1948
1948
1949
- if (src_type == dest_type)
1949
+ if (expr. type () == dest_type)
1950
1950
return ;
1951
1951
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
+
1952
1959
if (dest_type.id () == ID_integer)
1953
1960
{
1954
1961
if (expr.is_constant ())
@@ -2072,19 +2079,6 @@ void verilog_typecheck_exprt::implicit_typecast(
2072
2079
return ;
2073
2080
}
2074
2081
}
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
- }
2088
2082
else if (src_type.id () == ID_verilog_assignment_pattern)
2089
2083
{
2090
2084
DATA_INVARIANT (
@@ -2312,6 +2306,28 @@ typet verilog_typecheck_exprt::enum_decay(const typet &type)
2312
2306
2313
2307
/* ******************************************************************\
2314
2308
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
+
2315
2331
Function: verilog_typecheck_exprt::union_decay
2316
2332
2317
2333
Inputs:
@@ -2340,6 +2356,32 @@ void verilog_typecheck_exprt::union_decay(exprt &expr) const
2340
2356
2341
2357
/* ******************************************************************\
2342
2358
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
+
2343
2385
Function: verilog_typecheck_exprt::tc_binary_expr
2344
2386
2345
2387
Inputs:
0 commit comments