@@ -318,6 +318,20 @@ exprt verilog_typecheck_exprt::convert_expr_rec(exprt expr)
318318 {
319319 return convert_expr_function_call (to_function_call_expr (expr));
320320 }
321+ else if (expr.id () == ID_verilog_assignment_pattern)
322+ {
323+ // multi-ary -- may become a struct or array, depending
324+ // on context.
325+ for (auto &op : expr.operands ())
326+ convert_expr (op);
327+
328+ // Typechecking can only be completed once we know the type
329+ // from the usage context. We record "verilog_assignment_pattern"
330+ // to signal that.
331+ expr.type () = typet (ID_verilog_assignment_pattern);
332+
333+ return expr;
334+ }
321335 else
322336 {
323337 std::size_t no_op;
@@ -1614,6 +1628,64 @@ void verilog_typecheck_exprt::implicit_typecast(
16141628 return ;
16151629 }
16161630 }
1631+ else if (src_type.id () == ID_verilog_assignment_pattern)
1632+ {
1633+ DATA_INVARIANT (
1634+ expr.id () == ID_verilog_assignment_pattern,
1635+ " verilog_assignment_pattern expression expected" );
1636+ if (dest_type.id () == ID_struct)
1637+ {
1638+ auto &struct_type = to_struct_type (dest_type);
1639+ auto &components = struct_type.components ();
1640+
1641+ if (expr.operands ().size () != components.size ())
1642+ {
1643+ throw errort ().with_location (expr.source_location ())
1644+ << " number of expressions does not match number of struct members" ;
1645+ }
1646+
1647+ for (std::size_t i = 0 ; i < components.size (); i++)
1648+ {
1649+ // rec. call
1650+ implicit_typecast (expr.operands ()[i], components[i].type ());
1651+ }
1652+
1653+ // turn into struct expression
1654+ expr.id (ID_struct);
1655+ expr.type () = dest_type;
1656+ return ;
1657+ }
1658+ else if (dest_type.id () == ID_array)
1659+ {
1660+ auto &array_type = to_array_type (dest_type);
1661+ auto &element_type = array_type.element_type ();
1662+ auto array_size =
1663+ numeric_cast_v<mp_integer>(to_constant_expr (array_type.size ()));
1664+
1665+ if (array_size != expr.operands ().size ())
1666+ {
1667+ throw errort ().with_location (expr.source_location ())
1668+ << " number of expressions does not match number of array elements" ;
1669+ }
1670+
1671+ for (std::size_t i = 0 ; i < array_size; i++)
1672+ {
1673+ // rec. call
1674+ implicit_typecast (expr.operands ()[i], element_type);
1675+ }
1676+
1677+ // turn into array expression
1678+ expr.id (ID_array);
1679+ expr.type () = dest_type;
1680+ return ;
1681+ }
1682+ else
1683+ {
1684+ throw errort ().with_location (expr.source_location ())
1685+ << " cannot convert assignment pattern to '" << to_string (dest_type)
1686+ << ' \' ' ;
1687+ }
1688+ }
16171689
16181690 throw errort ().with_location (expr.source_location ())
16191691 << " failed to convert `" << to_string (src_type) << " ' to `"
0 commit comments