@@ -27,219 +27,6 @@ Author: Daniel Kroening, kroening@kroening.com
2727
2828/* ******************************************************************\
2929
30- Function: verilog_typecheckt::assignment_conversion
31-
32- Inputs:
33-
34- Outputs:
35-
36- Purpose:
37-
38- \*******************************************************************/
39-
40- void verilog_typecheckt::assignment_conversion (
41- exprt &rhs,
42- const typet &lhs_type)
43- {
44- // 1800-2017 10.9
45- if (rhs.type ().id () == ID_verilog_assignment_pattern)
46- {
47- DATA_INVARIANT (
48- rhs.id () == ID_verilog_assignment_pattern,
49- " verilog_assignment_pattern expression expected" );
50-
51- if (lhs_type.id () == ID_struct)
52- {
53- auto &struct_type = to_struct_type (lhs_type);
54- auto &components = struct_type.components ();
55-
56- if (
57- !rhs.operands ().empty () &&
58- rhs.operands ().front ().id () == ID_member_initializer)
59- {
60- exprt::operandst initializers{components.size (), nil_exprt{}};
61-
62- for (auto &op : rhs.operands ())
63- {
64- PRECONDITION (op.id () == ID_member_initializer);
65- auto member_name = op.get (ID_member_name);
66- if (!struct_type.has_component (member_name))
67- {
68- throw errort ().with_location (op.source_location ())
69- << " struct does not have a member `" << member_name << " '" ;
70- }
71- auto nr = struct_type.component_number (member_name);
72- auto value = to_unary_expr (op).op ();
73- // rec. call
74- assignment_conversion (value, components[nr].type ());
75- initializers[nr] = std::move (value);
76- }
77-
78- // Is every member covered?
79- for (std::size_t i = 0 ; i < components.size (); i++)
80- if (initializers[i].is_nil ())
81- {
82- throw errort ().with_location (rhs.source_location ())
83- << " assignment pattern does not assign member `"
84- << components[i].get_name () << " '" ;
85- }
86-
87- rhs = struct_exprt{std::move (initializers), struct_type}
88- .with_source_location (rhs.source_location ());
89- }
90- else
91- {
92- if (rhs.operands ().size () != components.size ())
93- {
94- throw errort ().with_location (rhs.source_location ())
95- << " number of expressions does not match number of struct members" ;
96- }
97-
98- for (std::size_t i = 0 ; i < components.size (); i++)
99- {
100- // rec. call
101- assignment_conversion (rhs.operands ()[i], components[i].type ());
102- }
103-
104- // turn into struct expression
105- rhs.id (ID_struct);
106- rhs.type () = lhs_type;
107- }
108-
109- return ;
110- }
111- else if (lhs_type.id () == ID_array)
112- {
113- auto &array_type = to_array_type (lhs_type);
114- auto &element_type = array_type.element_type ();
115- auto array_size =
116- numeric_cast_v<mp_integer>(to_constant_expr (array_type.size ()));
117-
118- if (array_size != rhs.operands ().size ())
119- {
120- throw errort ().with_location (rhs.source_location ())
121- << " number of expressions does not match number of array elements" ;
122- }
123-
124- for (std::size_t i = 0 ; i < array_size; i++)
125- {
126- // rec. call
127- assignment_conversion (rhs.operands ()[i], element_type);
128- }
129-
130- // turn into array expression
131- rhs.id (ID_array);
132- rhs.type () = lhs_type;
133- return ;
134- }
135- else
136- {
137- throw errort ().with_location (rhs.source_location ())
138- << " cannot convert assignment pattern to '" << to_string (lhs_type)
139- << ' \' ' ;
140- }
141- }
142-
143- auto original_rhs_type = rhs.type (); // copy
144-
145- auto &verilog_dest_type = lhs_type.get (ID_C_verilog_type);
146- if (verilog_dest_type == ID_verilog_enum)
147- {
148- // IEEE 1800-2017 6.19.3: "a variable of type enum cannot be directly
149- // assigned a value that lies outside the enumeration set unless an
150- // explicit cast is used"
151- if (
152- rhs.type ().get (ID_C_verilog_type) != ID_verilog_enum ||
153- rhs.type ().get (ID_C_identifier) != lhs_type.get (ID_C_identifier))
154- {
155- throw errort ().with_location (rhs.source_location ())
156- << " assignment to enum requires enum of the same type, but got "
157- << to_string (rhs.type ());
158- }
159- }
160-
161- if (lhs_type == rhs.type ())
162- return ;
163-
164- // do enum, union and struct decay
165- enum_decay (rhs);
166- struct_decay (rhs);
167- union_decay (rhs);
168-
169- if (rhs.type ().id () == ID_struct || rhs.type ().id () == ID_union)
170- {
171- // not decayed, not equal
172- throw errort ().with_location (rhs.source_location ())
173- << " failed to convert `" << to_string (original_rhs_type) << " ' to `"
174- << to_string (lhs_type) << " '" ;
175- }
176-
177- // Implements 1800-2017 10.7 and 1800-2017 11.8.3.
178-
179- if (
180- lhs_type.id () == ID_verilog_real || lhs_type.id () == ID_verilog_shortreal ||
181- lhs_type.id () == ID_verilog_realtime ||
182- rhs.type ().id () == ID_verilog_real ||
183- rhs.type ().id () == ID_verilog_shortreal)
184- {
185- // from/to real is just a cast
186- rhs = typecast_exprt::conditional_cast (rhs, lhs_type);
187- return ;
188- }
189-
190- if (rhs.type ().id () == ID_verilog_null)
191- {
192- if (
193- lhs_type.id () == ID_verilog_chandle ||
194- lhs_type.id () == ID_verilog_class_type ||
195- lhs_type.id () == ID_verilog_event)
196- {
197- rhs = typecast_exprt{rhs, lhs_type};
198- return ;
199- }
200- }
201-
202- // "The size of the left-hand side of an assignment forms
203- // the context for the right-hand expression."
204-
205- // Get the width of LHS and RHS
206- auto lhs_width = get_width (lhs_type);
207- auto rhs_width = get_width (rhs.type ());
208-
209- if (lhs_width > rhs_width)
210- {
211- // Need to enlarge the RHS.
212- //
213- // "If needed, extend the size of the right-hand side,
214- // performing sign extension if, and only if, the type
215- // of the right-hand side is signed.
216- if (
217- (rhs.type ().id () == ID_signedbv ||
218- rhs.type ().id () == ID_verilog_signedbv) &&
219- (lhs_type.id () == ID_unsignedbv ||
220- lhs_type.id () == ID_verilog_unsignedbv))
221- {
222- // LHS is unsigned, RHS is signed. Must sign-extend.
223- auto new_rhs_type = to_bitvector_type (rhs.type ());
224- new_rhs_type.set_width (numeric_cast_v<std::size_t >(lhs_width));
225-
226- downwards_type_propagation (rhs, new_rhs_type);
227-
228- // then cast
229- rhs = typecast_exprt::conditional_cast (rhs, lhs_type);
230- }
231- else
232- downwards_type_propagation (rhs, lhs_type);
233- }
234- else
235- {
236- // no need to enlarge
237- rhs = typecast_exprt::conditional_cast (rhs, lhs_type);
238- }
239- }
240-
241- /* ******************************************************************\
242-
24330Function: verilog_typecheckt::typecheck_port_connection
24431
24532 Inputs:
0 commit comments