@@ -1635,26 +1635,46 @@ bool verilog_typecheck_exprt::is_constant_expression(
1635
1635
exprt tmp (expr);
1636
1636
1637
1637
convert_expr (tmp);
1638
- ns.follow_macros (tmp);
1639
-
1640
- simplify (tmp, ns);
1641
1638
1642
- if (tmp.is_true ())
1643
- {
1644
- value=1 ;
1645
- return true ;
1646
- }
1647
- else if (tmp.is_false ())
1648
- {
1649
- value=0 ;
1650
- return true ;
1651
- }
1652
- else if (!to_integer_non_constant (tmp, value))
1639
+ auto integer_opt = is_constant_integer_post_convert (tmp);
1640
+ if (integer_opt.has_value ())
1653
1641
{
1642
+ value = integer_opt.value ();
1654
1643
return true ;
1655
1644
}
1645
+ else
1646
+ return false ;
1647
+ }
1648
+
1649
+ /* ******************************************************************\
1650
+
1651
+ Function: verilog_typecheck_exprt::is_constant_integer_post_convert
1652
+
1653
+ Inputs:
1656
1654
1657
- return false ;
1655
+ Outputs:
1656
+
1657
+ Purpose:
1658
+
1659
+ \*******************************************************************/
1660
+
1661
+ std::optional<mp_integer>
1662
+ verilog_typecheck_exprt::is_constant_integer_post_convert (const exprt &expr)
1663
+ {
1664
+ exprt tmp = expr;
1665
+
1666
+ ns.follow_macros (tmp);
1667
+ tmp = simplify_expr (tmp, ns);
1668
+
1669
+ if (!tmp.is_constant ())
1670
+ return {};
1671
+
1672
+ if (tmp.is_true ())
1673
+ return 1 ;
1674
+ else if (tmp.is_false ())
1675
+ return 0 ;
1676
+ else
1677
+ return numeric_cast<mp_integer>(to_constant_expr (tmp));
1658
1678
}
1659
1679
1660
1680
/* ******************************************************************\
@@ -2189,65 +2209,65 @@ exprt verilog_typecheck_exprt::convert_bit_select_expr(binary_exprt expr)
2189
2209
// Verilog's bit select expression may map onto an extractbit
2190
2210
// or an array index expression, depending on the type of the first
2191
2211
// operand.
2192
- exprt &op0 = expr.op0 ();
2212
+ exprt &op0 = expr.op0 (), &op1 = expr. op1 () ;
2193
2213
convert_expr (op0);
2214
+ convert_expr (op1);
2194
2215
2195
2216
if (op0.type ().id () == ID_verilog_real)
2196
2217
{
2197
2218
throw errort ().with_location (op0.source_location ())
2198
2219
<< " bit-select of real is not allowed" ;
2199
2220
}
2200
2221
2201
- if (op0 .type ().id ()==ID_array )
2222
+ if (op1 .type ().id () == ID_verilog_real )
2202
2223
{
2203
- exprt &op1 = expr.op1 ();
2204
- convert_expr (op1);
2205
- if (op1.type ().id () == ID_verilog_real)
2206
- {
2207
- throw errort ().with_location (op1.source_location ())
2208
- << " real number index is not allowed" ;
2209
- }
2224
+ throw errort ().with_location (op1.source_location ())
2225
+ << " real number index is not allowed" ;
2226
+ }
2210
2227
2228
+ if (op0.type ().id () == ID_array)
2229
+ {
2211
2230
typet _index_type = index_type (to_array_type (op0.type ()));
2212
-
2213
- if (_index_type!=op1.type ())
2214
- {
2215
- mp_integer i;
2216
- if (!to_integer_non_constant (op1, i))
2217
- op1=from_integer (i, _index_type);
2218
- else if (op1.is_true () || op1.is_false ())
2219
- op1=from_integer (op1.is_true ()?1 :0 , _index_type);
2220
- else
2221
- op1 = typecast_exprt{op1, _index_type};
2222
- }
2231
+ op1 = typecast_exprt{op1, _index_type};
2223
2232
2224
2233
expr.type () = to_array_type (op0.type ()).element_type ();
2225
2234
expr.id (ID_index);
2226
2235
}
2227
2236
else
2228
2237
{
2229
2238
auto width = get_width (op0.type ());
2230
- auto offset = atoi ( op0.type ().get (ID_C_offset). c_str () );
2239
+ auto offset = op0.type ().get_int (ID_C_offset);
2231
2240
2232
- mp_integer op1;
2241
+ auto op1_opt = is_constant_integer_post_convert ( op1) ;
2233
2242
2234
- if (is_constant_expression (expr. op1 (), op1))
2243
+ if (op1_opt. has_value ()) // constant index
2235
2244
{
2236
2245
// 1800-2017 sec 11.5.1: out-of-bounds bit-select is
2237
2246
// x for 4-state and 0 for 2-state values.
2238
- if (op1 < offset || op1 >= width + offset)
2247
+ auto op1_int = op1_opt.value ();
2248
+
2249
+ if (op1_int < offset || op1_int >= width + offset)
2239
2250
return false_exprt ().with_source_location (expr);
2240
2251
2241
- op1 -= offset;
2242
- expr.op1 () = from_integer (op1, natural_typet ());
2252
+ op1_int -= offset;
2253
+
2254
+ if (op0.type ().get_bool (ID_C_big_endian))
2255
+ op1_int = width - op1_int - 1 ;
2256
+
2257
+ expr.op1 () = from_integer (op1_int, natural_typet ());
2243
2258
}
2244
- else
2259
+ else // non-constant index
2245
2260
{
2246
- convert_expr (expr.op1 ());
2247
- if (expr.op1 ().type ().id () == ID_verilog_real)
2261
+ if (offset != 0 )
2262
+ {
2263
+ expr.op1 () =
2264
+ minus_exprt{expr.op1 (), from_integer (offset, expr.op1 ().type ())};
2265
+ }
2266
+
2267
+ if (op0.type ().get_bool (ID_C_big_endian))
2248
2268
{
2249
- throw errort (). with_location ( expr.op1 (). source_location ())
2250
- << " real number index is not allowed " ;
2269
+ expr.op1 () =
2270
+ minus_exprt{ from_integer (width - 1 , expr. op1 (). type ()), expr. op1 ()} ;
2251
2271
}
2252
2272
}
2253
2273
0 commit comments