Skip to content

Commit 389474c

Browse files
authored
Merge pull request #1340 from diffblue/verilog-size-cast
Verilog: explicit casts are assignments
2 parents 445ac04 + 435509b commit 389474c

File tree

8 files changed

+62
-20
lines changed

8 files changed

+62
-20
lines changed

CHANGELOG

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
size_cast3.sv
33
--module main
44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
This is not yet implemented.
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
static_cast3.sv
33
--module main
44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
This is not yet implemented.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
static_cast4.sv
3+
--module main
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
--
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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

src/verilog/verilog_expr.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff 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

25692563
inline 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

26692658
inline const verilog_explicit_type_cast_exprt &

src/verilog/verilog_lowering.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff 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 ||

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff 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(

0 commit comments

Comments
 (0)