@@ -222,6 +222,118 @@ void verilog_typecheck_exprt::propagate_type(
222
222
223
223
/* ******************************************************************\
224
224
225
+ Function: verilog_typecheck_exprt::downwards_type_progatation
226
+
227
+ Inputs:
228
+
229
+ Outputs:
230
+
231
+ Purpose:
232
+
233
+ \*******************************************************************/
234
+
235
+ void verilog_typecheck_exprt::downwards_type_propagation (
236
+ exprt &expr,
237
+ const typet &type)
238
+ {
239
+ // This implements the step "propagate the type and size down to
240
+ // the context-determined operands" in 1800-2017 11.8.2
241
+
242
+ // Any context-determined operand of an operator shall be the
243
+ // same type and size as the result of the operator.
244
+ // Exceptions:
245
+ // * result type real -- just cast
246
+ // * relational operators are always 1 bit unsigned
247
+
248
+ if (expr.type () == type)
249
+ return ;
250
+
251
+ vtypet vt_from = vtypet (expr.type ());
252
+ vtypet vt_to = vtypet (type);
253
+
254
+ if (!vt_from.is_other () && !vt_to.is_other () && expr.has_operands ())
255
+ {
256
+ // arithmetic
257
+
258
+ if (
259
+ expr.id () == ID_plus || expr.id () == ID_minus || expr.id () == ID_mult ||
260
+ expr.id () == ID_div || expr.id () == ID_unary_minus ||
261
+ expr.id () == ID_unary_plus)
262
+ {
263
+ if (type.id () != ID_bool)
264
+ {
265
+ Forall_operands (it, expr)
266
+ propagate_type (*it, type);
267
+
268
+ expr.type () = type;
269
+
270
+ return ;
271
+ }
272
+ }
273
+ else if (
274
+ expr.id () == ID_bitand || expr.id () == ID_bitor ||
275
+ expr.id () == ID_bitnand || expr.id () == ID_bitnor ||
276
+ expr.id () == ID_bitxor || expr.id () == ID_bitxnor ||
277
+ expr.id () == ID_bitnot)
278
+ {
279
+ Forall_operands (it, expr)
280
+ propagate_type (*it, type);
281
+
282
+ expr.type () = type;
283
+
284
+ if (type.id () == ID_bool)
285
+ {
286
+ if (expr.id () == ID_bitand)
287
+ expr.id (ID_and);
288
+ else if (expr.id () == ID_bitor)
289
+ expr.id (ID_or);
290
+ else if (expr.id () == ID_bitnand)
291
+ expr.id (ID_nand);
292
+ else if (expr.id () == ID_bitnor)
293
+ expr.id (ID_nor);
294
+ else if (expr.id () == ID_bitxor)
295
+ expr.id (ID_xor);
296
+ else if (expr.id () == ID_bitxnor)
297
+ expr.id (ID_xnor);
298
+ else if (expr.id () == ID_bitnot)
299
+ expr.id (ID_not);
300
+ }
301
+
302
+ return ;
303
+ }
304
+ else if (expr.id () == ID_if)
305
+ {
306
+ if (expr.operands ().size () == 3 )
307
+ {
308
+ propagate_type (to_if_expr (expr).true_case (), type);
309
+ propagate_type (to_if_expr (expr).false_case (), type);
310
+
311
+ expr.type () = type;
312
+ return ;
313
+ }
314
+ }
315
+ else if (expr.id () == ID_shl) // does not work with shr
316
+ {
317
+ // does not work with boolean
318
+ if (type.id () != ID_bool)
319
+ {
320
+ if (expr.operands ().size () == 2 )
321
+ {
322
+ propagate_type (to_binary_expr (expr).op0 (), type);
323
+ // not applicable to second operand
324
+
325
+ expr.type () = type;
326
+ return ;
327
+ }
328
+ }
329
+ }
330
+ }
331
+
332
+ implicit_typecast (expr, type);
333
+ }
334
+
335
+ /* ******************************************************************\
336
+
225
337
Function: verilog_typecheck_exprt::no_bool_ops
226
338
227
339
Inputs:
@@ -2396,12 +2508,20 @@ void verilog_typecheck_exprt::tc_binary_expr(
2396
2508
const exprt &expr,
2397
2509
exprt &op0, exprt &op1)
2398
2510
{
2511
+ // Follows 1800-2017 11.8.2.
2512
+
2513
+ // First get the self-determined type and size of both operands
2399
2514
union_decay (op0);
2400
2515
union_decay (op1);
2401
2516
2402
- // follows 1800-2017 11.8.2
2403
- const typet new_type =
2404
- max_type (enum_decay (op0.type ()), enum_decay (op1.type ()));
2517
+ enum_decay (op0);
2518
+ enum_decay (op1);
2519
+
2520
+ struct_decay (op0);
2521
+ struct_decay (op1);
2522
+
2523
+ // Now get the max
2524
+ const typet new_type = max_type (op0.type (), op1.type ());
2405
2525
2406
2526
if (new_type.is_nil ())
2407
2527
{
@@ -2411,8 +2531,9 @@ void verilog_typecheck_exprt::tc_binary_expr(
2411
2531
<< " " << to_string (op1.type ());
2412
2532
}
2413
2533
2414
- propagate_type (op0, new_type);
2415
- propagate_type (op1, new_type);
2534
+ // Now do downwards propagation
2535
+ downwards_type_propagation (op0, new_type);
2536
+ downwards_type_propagation (op1, new_type);
2416
2537
}
2417
2538
2418
2539
/* ******************************************************************\
0 commit comments