@@ -1635,26 +1635,46 @@ bool verilog_typecheck_exprt::is_constant_expression(
16351635 exprt tmp (expr);
16361636
16371637 convert_expr (tmp);
1638- ns.follow_macros (tmp);
1639-
1640- simplify (tmp, ns);
16411638
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 ())
16531641 {
1642+ value = integer_opt.value ();
16541643 return true ;
16551644 }
1645+ else
1646+ return false ;
1647+ }
1648+
1649+ /* ******************************************************************\
1650+
1651+ Function: verilog_typecheck_exprt::is_constant_integer_post_convert
1652+
1653+ Inputs:
16561654
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));
16581678}
16591679
16601680/* ******************************************************************\
@@ -2189,65 +2209,65 @@ exprt verilog_typecheck_exprt::convert_bit_select_expr(binary_exprt expr)
21892209 // Verilog's bit select expression may map onto an extractbit
21902210 // or an array index expression, depending on the type of the first
21912211 // operand.
2192- exprt &op0 = expr.op0 ();
2212+ exprt &op0 = expr.op0 (), &op1 = expr. op1 () ;
21932213 convert_expr (op0);
2214+ convert_expr (op1);
21942215
21952216 if (op0.type ().id () == ID_verilog_real)
21962217 {
21972218 throw errort ().with_location (op0.source_location ())
21982219 << " bit-select of real is not allowed" ;
21992220 }
22002221
2201- if (op0 .type ().id ()==ID_array )
2222+ if (op1 .type ().id () == ID_verilog_real )
22022223 {
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+ }
22102227
2228+ if (op0.type ().id () == ID_array)
2229+ {
22112230 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};
22232232
22242233 expr.type () = to_array_type (op0.type ()).element_type ();
22252234 expr.id (ID_index);
22262235 }
22272236 else
22282237 {
22292238 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);
22312240
2232- mp_integer op1;
2241+ auto op1_opt = is_constant_integer_post_convert ( op1) ;
22332242
2234- if (is_constant_expression (expr. op1 (), op1))
2243+ if (op1_opt. has_value ()) // constant index
22352244 {
22362245 // 1800-2017 sec 11.5.1: out-of-bounds bit-select is
22372246 // 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)
22392250 return false_exprt ().with_source_location (expr);
22402251
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 ());
22432258 }
2244- else
2259+ else // non-constant index
22452260 {
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))
22482268 {
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 ()} ;
22512271 }
22522272 }
22532273
0 commit comments