@@ -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;
@@ -1814,6 +1828,64 @@ void verilog_typecheck_exprt::implicit_typecast(
18141828 return ;
18151829 }
18161830 }
1831+ else if (src_type.id () == ID_verilog_assignment_pattern)
1832+ {
1833+ DATA_INVARIANT (
1834+ expr.id () == ID_verilog_assignment_pattern,
1835+ " verilog_assignment_pattern expression expected" );
1836+ if (dest_type.id () == ID_struct)
1837+ {
1838+ auto &struct_type = to_struct_type (dest_type);
1839+ auto &components = struct_type.components ();
1840+
1841+ if (expr.operands ().size () != components.size ())
1842+ {
1843+ throw errort ().with_location (expr.source_location ())
1844+ << " number of expressions does not match number of struct members" ;
1845+ }
1846+
1847+ for (std::size_t i = 0 ; i < components.size (); i++)
1848+ {
1849+ // rec. call
1850+ implicit_typecast (expr.operands ()[i], components[i].type ());
1851+ }
1852+
1853+ // turn into struct expression
1854+ expr.id (ID_struct);
1855+ expr.type () = dest_type;
1856+ return ;
1857+ }
1858+ else if (dest_type.id () == ID_array)
1859+ {
1860+ auto &array_type = to_array_type (dest_type);
1861+ auto &element_type = array_type.element_type ();
1862+ auto array_size =
1863+ numeric_cast_v<mp_integer>(to_constant_expr (array_type.size ()));
1864+
1865+ if (array_size != expr.operands ().size ())
1866+ {
1867+ throw errort ().with_location (expr.source_location ())
1868+ << " number of expressions does not match number of array elements" ;
1869+ }
1870+
1871+ for (std::size_t i = 0 ; i < array_size; i++)
1872+ {
1873+ // rec. call
1874+ implicit_typecast (expr.operands ()[i], element_type);
1875+ }
1876+
1877+ // turn into array expression
1878+ expr.id (ID_array);
1879+ expr.type () = dest_type;
1880+ return ;
1881+ }
1882+ else
1883+ {
1884+ throw errort ().with_location (expr.source_location ())
1885+ << " cannot convert assignment pattern to '" << to_string (dest_type)
1886+ << ' \' ' ;
1887+ }
1888+ }
18171889
18181890 throw errort ().with_location (expr.source_location ())
18191891 << " failed to convert `" << to_string (src_type) << " ' to `"
0 commit comments