File tree Expand file tree Collapse file tree 8 files changed +62
-20
lines changed
regression/verilog/expressions Expand file tree Collapse file tree 8 files changed +62
-20
lines changed Original file line number Diff line number Diff line change 11# EBMC 5.8
22
3- * SystemVerilog: cover sequence
43* Verilog: semantic fix for output register ports
4+ * SystemVerilog: cover sequence
5+ * SystemVerilog: semantics fix for explicit casts
56
67# EBMC 5.7
78
Original file line number Diff line number Diff line change 1- KNOWNBUG
1+ CORE
22size_cast3.sv
33--module main
44^EXIT=0$
55^SIGNAL=0$
66--
77^warning: ignoring
88--
9- This is not yet implemented.
Original file line number Diff line number Diff line change 1- KNOWNBUG
1+ CORE
22static_cast3.sv
33--module main
44^EXIT=0$
55^SIGNAL=0$
66--
77^warning: ignoring
88--
9- This is not yet implemented.
Original file line number Diff line number Diff line change 1+ CORE
2+ static_cast4.sv
3+ --module main
4+ ^EXIT=0$
5+ ^SIGNAL=0$
6+ --
7+ ^warning: ignoring
8+ --
Original file line number Diff line number Diff line change 1+ module main ;
2+
3+ // The standard suggests that casts can be applied to assignment patterns.
4+ // VCS, Icarus Verilog and Xcelium error this.
5+ // Questa allows it.
6+ // Riviera throws an internal error.
7+
8+ typedef struct packed { int a, b; } S ;
9+
10+ initial begin
11+ S some_struct;
12+ some_struct.a = 1 ;
13+ some_struct.b = 2 ;
14+ assert ((S ' ('{ a: 1 , b: 2 } )) == some_struct);
15+ end
16+
17+ endmodule
Original file line number Diff line number Diff line change @@ -2558,12 +2558,6 @@ class verilog_explicit_size_cast_exprt : public binary_exprt
25582558 {
25592559 return op1 ();
25602560 }
2561-
2562- // lower to typecast
2563- exprt lower () const
2564- {
2565- return typecast_exprt{op (), type ()};
2566- }
25672561};
25682562
25692563inline const verilog_explicit_size_cast_exprt &
@@ -2659,11 +2653,6 @@ class verilog_explicit_type_cast_exprt : public unary_exprt
26592653 std::move(__type))
26602654 {
26612655 }
2662-
2663- exprt lower () const
2664- {
2665- return typecast_exprt{op (), type ()};
2666- }
26672656};
26682657
26692658inline const verilog_explicit_type_cast_exprt &
Original file line number Diff line number Diff line change @@ -471,16 +471,27 @@ exprt verilog_lowering(exprt expr)
471471 }
472472 else if (expr.id () == ID_verilog_explicit_type_cast)
473473 {
474- return verilog_lowering_cast (
475- to_typecast_expr (to_verilog_explicit_type_cast_expr (expr).lower ()));
474+ // These act like an assignment, and hence, the type checker
475+ // has already converted the argument to the target type.
476+ auto &type_cast = to_verilog_explicit_type_cast_expr (expr);
477+ expr.type () = verilog_lowering (expr.type ());
478+ DATA_INVARIANT (
479+ type_cast.op ().type () == type_cast.type (), " type cast type consistency" );
480+ return type_cast.op ();
476481 }
477482 else if (expr.id () == ID_verilog_explicit_signing_cast)
478483 {
479484 return to_verilog_explicit_signing_cast_expr (expr).lower ();
480485 }
481486 else if (expr.id () == ID_verilog_explicit_size_cast)
482487 {
483- return verilog_lowering (to_verilog_explicit_size_cast_expr (expr).lower ());
488+ // These act like an assignment, and hence, the type checker
489+ // has already converted the argument to the target type.
490+ auto &size_cast = to_verilog_explicit_size_cast_expr (expr);
491+ expr.type () = verilog_lowering (expr.type ());
492+ DATA_INVARIANT (
493+ size_cast.op ().type () == size_cast.type (), " size cast type consistency" );
494+ return size_cast.op ();
484495 }
485496 else if (
486497 expr.id () == ID_verilog_streaming_concatenation_left_to_right ||
Original file line number Diff line number Diff line change @@ -2694,9 +2694,22 @@ exprt verilog_typecheck_exprt::convert_unary_expr(unary_exprt expr)
26942694 else if (expr.id () == ID_verilog_explicit_type_cast)
26952695 {
26962696 // SystemVerilog has got type'(expr). This is an explicit
2697- // type cast.
2697+ // type cast. These are assignment contexts.
26982698 convert_expr (expr.op ());
26992699 expr.type () = elaborate_type (expr.type ());
2700+
2701+ // In contrast to assignments, these can turn integers into enums
2702+ // (1800-2017 6.19.3).
2703+ if (expr.type ().get (ID_C_verilog_type) == ID_verilog_enum)
2704+ {
2705+ expr.op () = typecast_exprt::conditional_cast (expr.op (), expr.type ());
2706+ }
2707+ else
2708+ {
2709+ assignment_conversion (expr.op (), expr.type ());
2710+ }
2711+
2712+ CHECK_RETURN (expr.op ().type () == expr.type ());
27002713 }
27012714 else if (expr.id () == ID_verilog_explicit_signing_cast)
27022715 {
@@ -3327,6 +3340,11 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
33273340 << " cannot perform size cast on " << to_string (op_type);
33283341 }
33293342
3343+ // These act like an assignment (1800-2017 6.24.1)
3344+ assignment_conversion (expr.rhs (), expr.type ());
3345+
3346+ CHECK_RETURN (expr.rhs ().type () == expr.type ());
3347+
33303348 return std::move (expr);
33313349 }
33323350 else if (
You can’t perform that action at this time.
0 commit comments