@@ -228,29 +228,32 @@ const exprt &skip_typecast(const exprt &expr)
228
228
// / "constants"
229
229
bool is_constantt::is_constant (const exprt &expr) const
230
230
{
231
- if (expr.is_constant ())
232
- return true ;
231
+ if (
232
+ expr.id () == ID_symbol || expr.id () == ID_nondet_symbol ||
233
+ expr.id () == ID_side_effect)
234
+ {
235
+ return false ;
236
+ }
233
237
234
238
if (expr.id () == ID_address_of)
235
239
{
236
240
return is_constant_address_of (to_address_of_expr (expr).object ());
237
241
}
238
- else if (
239
- expr.id () == ID_typecast || expr.id () == ID_array_of ||
240
- expr.id () == ID_plus || expr.id () == ID_mult || expr.id () == ID_array ||
241
- expr.id () == ID_with || expr.id () == ID_struct || expr.id () == ID_union ||
242
- expr.id () == ID_empty_union || expr.id () == ID_equal ||
243
- expr.id () == ID_notequal || expr.id () == ID_lt || expr.id () == ID_le ||
244
- expr.id () == ID_gt || expr.id () == ID_ge || expr.id () == ID_if ||
245
- expr.id () == ID_not || expr.id () == ID_and || expr.id () == ID_or ||
246
- expr.id () == ID_bitnot || expr.id () == ID_bitand || expr.id () == ID_bitor ||
247
- expr.id () == ID_bitxor || expr.id () == ID_byte_update_big_endian ||
248
- expr.id () == ID_byte_update_little_endian)
242
+ else if (auto index = expr_try_dynamic_cast<index_exprt>(expr))
249
243
{
250
- return std::all_of (
251
- expr.operands ().begin (), expr.operands ().end (), [this ](const exprt &e) {
252
- return is_constant (e);
253
- });
244
+ if (!is_constant (index ->array ()) || !index ->index ().is_constant ())
245
+ return false ;
246
+
247
+ const auto &array_type = to_array_type (index ->array ().type ());
248
+ if (!array_type.size ().is_constant ())
249
+ return false ;
250
+
251
+ const mp_integer size =
252
+ numeric_cast_v<mp_integer>(to_constant_expr (array_type.size ()));
253
+ const mp_integer index_int =
254
+ numeric_cast_v<mp_integer>(to_constant_expr (index ->index ()));
255
+
256
+ return index_int >= 0 && index_int < size;
254
257
}
255
258
else if (auto be = expr_try_dynamic_cast<byte_extract_exprt>(expr))
256
259
{
@@ -269,7 +272,7 @@ bool is_constantt::is_constant(const exprt &expr) const
269
272
numeric_cast_v<mp_integer>(to_constant_expr (be->offset ())) *
270
273
be->get_bits_per_byte ();
271
274
272
- return offset_bits + *extract_bits <= *op_bits;
275
+ return offset_bits >= 0 && offset_bits + *extract_bits <= *op_bits;
273
276
}
274
277
else if (auto eb = expr_try_dynamic_cast<extractbits_exprt>(expr))
275
278
{
@@ -292,8 +295,14 @@ bool is_constantt::is_constant(const exprt &expr) const
292
295
return lower_bound >= 0 && lower_bound <= upper_bound &&
293
296
upper_bound < src_bits;
294
297
}
295
-
296
- return false ;
298
+ else
299
+ {
300
+ // std::all_of returns true when there are no operands
301
+ return std::all_of (
302
+ expr.operands ().begin (), expr.operands ().end (), [this ](const exprt &e) {
303
+ return is_constant (e);
304
+ });
305
+ }
297
306
}
298
307
299
308
// / this function determines which reference-typed expressions are constant
0 commit comments