@@ -2019,21 +2019,59 @@ void verilog_typecheck_exprt::implicit_typecast(
20192019 auto &struct_type = to_struct_type (dest_type);
20202020 auto &components = struct_type.components ();
20212021
2022- if (expr.operands ().size () != components.size ())
2022+ if (
2023+ !expr.operands ().empty () &&
2024+ expr.operands ().front ().id () == ID_member_initializer)
20232025 {
2024- throw errort ().with_location (expr.source_location ())
2025- << " number of expressions does not match number of struct members" ;
2026- }
2026+ exprt::operandst initializers{components.size (), nil_exprt{}};
2027+
2028+ for (auto &op : expr.operands ())
2029+ {
2030+ PRECONDITION (op.id () == ID_member_initializer);
2031+ auto member_name = op.get (ID_member_name);
2032+ if (!struct_type.has_component (member_name))
2033+ {
2034+ throw errort ().with_location (op.source_location ())
2035+ << " struct does not have a member `" << member_name << " '" ;
2036+ }
2037+ auto nr = struct_type.component_number (member_name);
2038+ auto value = to_unary_expr (op).op ();
2039+ // rec. call
2040+ implicit_typecast (value, components[nr].type ());
2041+ initializers[nr] = std::move (value);
2042+ }
20272043
2028- for (std::size_t i = 0 ; i < components.size (); i++)
2044+ // Is every member covered?
2045+ for (std::size_t i = 0 ; i < components.size (); i++)
2046+ if (initializers[i].is_nil ())
2047+ {
2048+ throw errort ().with_location (expr.source_location ())
2049+ << " assignment pattern does not assign member `"
2050+ << components[i].get_name () << " '" ;
2051+ }
2052+
2053+ expr = struct_exprt{std::move (initializers), struct_type}
2054+ .with_source_location (expr.source_location ());
2055+ }
2056+ else
20292057 {
2030- // rec. call
2031- implicit_typecast (expr.operands ()[i], components[i].type ());
2058+ if (expr.operands ().size () != components.size ())
2059+ {
2060+ throw errort ().with_location (expr.source_location ())
2061+ << " number of expressions does not match number of struct members" ;
2062+ }
2063+
2064+ for (std::size_t i = 0 ; i < components.size (); i++)
2065+ {
2066+ // rec. call
2067+ implicit_typecast (expr.operands ()[i], components[i].type ());
2068+ }
2069+
2070+ // turn into struct expression
2071+ expr.id (ID_struct);
2072+ expr.type () = dest_type;
20322073 }
20332074
2034- // turn into struct expression
2035- expr.id (ID_struct);
2036- expr.type () = dest_type;
20372075 return ;
20382076 }
20392077 else if (dest_type.id () == ID_array)
@@ -2620,6 +2658,11 @@ exprt verilog_typecheck_exprt::convert_unary_expr(unary_exprt expr)
26202658 // The type of these expressions is determined by their context.
26212659 expr.type () = typet (ID_verilog_new);
26222660 }
2661+ else if (expr.id () == ID_member_initializer)
2662+ {
2663+ // assignment patterns, 1800 2017 10.9
2664+ convert_expr (expr.op ());
2665+ }
26232666 else
26242667 {
26252668 throw errort () << " no conversion for unary expression " << expr.id ();
0 commit comments