Skip to content

Commit 374151c

Browse files
committed
Verilog: add checks for operators that require integral types
This adds checks to the typechecker to enforce that the operands have an integral type.
1 parent 51fa81e commit 374151c

File tree

8 files changed

+87
-20
lines changed

8 files changed

+87
-20
lines changed
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
equality3.v
33
--bound 0
4-
^EXIT=0$
4+
^EXIT=2$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
This should be errored.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
mod2.v
33
--bound 0
4-
^EXIT=0$
4+
^file .* line 4: operand 1\.1 must be integral$
5+
^EXIT=2$
56
^SIGNAL=0$
67
--
78
^warning: ignoring
89
--
9-
This should be errored.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
KNOWNBUG
2+
replication3.v
3+
--bound 0
4+
^file .* line 4: operand 1\.1 must be integral$
5+
^EXIT=2$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring
9+
--
10+
Should be errored.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module main;
2+
3+
wire [31:0] x = {4{1.1}};
4+
5+
endmodule
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
shr2.v
33
--bound 0
4-
^EXIT=0$
4+
^file .* line 4: operand 1\.1 must be integral$
5+
^EXIT=2$
56
^SIGNAL=0$
67
--
78
^warning: ignoring
89
--
9-
This should be errored.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
wildcard_equality2.v
33
--bound 0
4-
^EXIT=0$
4+
^file .* line 4: operand 1\.1 must be integral$
5+
^EXIT=2$
56
^SIGNAL=0$
67
--
78
^warning: ignoring
89
--
9-
This should be errored.

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,37 @@ void verilog_typecheck_exprt::no_bool_ops(exprt &expr)
226226

227227
/*******************************************************************\
228228
229+
Function: verilog_typecheck_exprt::must_be_integral
230+
231+
Inputs:
232+
233+
Outputs:
234+
235+
Purpose:
236+
237+
\*******************************************************************/
238+
239+
void verilog_typecheck_exprt::must_be_integral(exprt &expr)
240+
{
241+
// Throw an error if the given expression doesn't have an integral type.
242+
const auto &type = expr.type();
243+
if(type.id() == ID_bool)
244+
{
245+
expr = typecast_exprt{expr, unsignedbv_typet{1}};
246+
}
247+
else if(
248+
type.id() == ID_unsignedbv || type.id() == ID_signedbv ||
249+
type.id() == ID_verilog_unsignedbv || type.id() == ID_verilog_signedbv)
250+
{
251+
// ok as is
252+
}
253+
else
254+
throw errort().with_location(expr.source_location())
255+
<< "operand " << to_string(expr) << " must be integral";
256+
}
257+
258+
/*******************************************************************\
259+
229260
Function: verilog_typecheck_exprt::convert_expr_rec
230261
231262
Inputs:
@@ -3020,11 +3051,14 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
30203051
// a proper equality is performed.
30213052
expr.type()=bool_typet();
30223053

3023-
Forall_operands(it, expr)
3024-
convert_expr(*it);
3025-
3054+
convert_expr(expr.lhs());
3055+
convert_expr(expr.rhs());
30263056
typecheck_relation(expr);
30273057

3058+
// integral operands only
3059+
must_be_integral(expr.lhs());
3060+
must_be_integral(expr.rhs());
3061+
30283062
return std::move(expr);
30293063
}
30303064
else if(expr.id()==ID_lt || expr.id()==ID_gt ||
@@ -3049,8 +3083,10 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
30493083
// This is the >>> expression, which turns into ID_lshr or ID_ashr
30503084
// depending on type of first operand.
30513085

3052-
convert_expr(expr.op0());
3053-
convert_expr(expr.op1());
3086+
convert_expr(expr.lhs());
3087+
convert_expr(expr.rhs());
3088+
must_be_integral(expr.lhs());
3089+
must_be_integral(expr.rhs());
30543090
no_bool_ops(expr);
30553091

30563092
const typet &op0_type = expr.op0().type();
@@ -3074,14 +3110,16 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
30743110
else if(expr.id()==ID_lshr)
30753111
{
30763112
// logical right shift >>
3077-
convert_expr(expr.op0());
3078-
convert_expr(expr.op1());
3113+
convert_expr(expr.lhs());
3114+
convert_expr(expr.rhs());
3115+
must_be_integral(expr.lhs());
3116+
must_be_integral(expr.rhs());
30793117
no_bool_ops(expr);
30803118
expr.type()=expr.op0().type();
30813119

30823120
return std::move(expr);
30833121
}
3084-
else if(expr.id()==ID_div || expr.id()==ID_mod)
3122+
else if(expr.id()==ID_div)
30853123
{
30863124
Forall_operands(it, expr)
30873125
convert_expr(*it);
@@ -3093,6 +3131,20 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
30933131

30943132
return std::move(expr);
30953133
}
3134+
else if(expr.id()==ID_mod)
3135+
{
3136+
convert_expr(expr.lhs());
3137+
convert_expr(expr.rhs());
3138+
must_be_integral(expr.lhs());
3139+
must_be_integral(expr.rhs());
3140+
3141+
tc_binary_expr(expr);
3142+
no_bool_ops(expr);
3143+
3144+
expr.type()=expr.lhs().type();
3145+
3146+
return std::move(expr);
3147+
}
30963148
else if(expr.id()==ID_hierarchical_identifier)
30973149
{
30983150
return convert_hierarchical_identifier(

src/verilog/verilog_typecheck_expr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ class verilog_typecheck_exprt:public verilog_typecheck_baset
187187
void tc_binary_expr(const exprt &expr, exprt &op0, exprt &op1);
188188
void typecheck_relation(binary_exprt &);
189189
void no_bool_ops(exprt &);
190+
void must_be_integral(exprt &);
190191

191192
// SVA
192193
void convert_sva(exprt &expr)

0 commit comments

Comments
 (0)