@@ -4495,23 +4495,60 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
4495
4495
throw 0 ;
4496
4496
}
4497
4497
4498
- class is_compile_time_constantt : public is_constantt
4498
+ // / Architecturally similar to \ref can_forward_propagatet, but specialized for
4499
+ // / what is a constexpr, i.e., an expression that can be fully evaluated at
4500
+ // / compile time.
4501
+ class is_compile_time_constantt
4499
4502
{
4500
4503
public:
4501
- explicit is_compile_time_constantt (const namespacet &ns) : is_constantt (ns)
4504
+ explicit is_compile_time_constantt (const namespacet &ns) : ns (ns)
4502
4505
{
4503
4506
}
4504
4507
4508
+ // / returns true iff the expression can be considered constant
4509
+ bool operator ()(const exprt &e) const
4510
+ {
4511
+ return is_constant (e);
4512
+ }
4513
+
4505
4514
protected:
4506
- bool is_constant (const exprt &e) const override
4515
+ const namespacet &ns;
4516
+
4517
+ // / This function determines what expressions are to be propagated as
4518
+ // / "constants"
4519
+ bool is_constant (const exprt &e) const
4507
4520
{
4508
4521
if (e.id () == ID_infinity)
4509
4522
return true ;
4510
- else
4511
- return is_constantt::is_constant (e);
4523
+
4524
+ if (e.is_constant ())
4525
+ return true ;
4526
+
4527
+ if (e.id () == ID_address_of)
4528
+ {
4529
+ return is_constant_address_of (to_address_of_expr (e).object ());
4530
+ }
4531
+ else if (
4532
+ e.id () == ID_typecast || e.id () == ID_array_of || e.id () == ID_plus ||
4533
+ e.id () == ID_mult || e.id () == ID_array || e.id () == ID_with ||
4534
+ e.id () == ID_struct || e.id () == ID_union || e.id () == ID_empty_union ||
4535
+ e.id () == ID_equal || e.id () == ID_notequal || e.id () == ID_lt ||
4536
+ e.id () == ID_le || e.id () == ID_gt || e.id () == ID_ge ||
4537
+ e.id () == ID_if || e.id () == ID_not || e.id () == ID_and ||
4538
+ e.id () == ID_or || e.id () == ID_bitnot || e.id () == ID_bitand ||
4539
+ e.id () == ID_bitor || e.id () == ID_bitxor)
4540
+ {
4541
+ return std::all_of (
4542
+ e.operands ().begin (), e.operands ().end (), [this ](const exprt &op) {
4543
+ return is_constant (op);
4544
+ });
4545
+ }
4546
+
4547
+ return false ;
4512
4548
}
4513
4549
4514
- bool is_constant_address_of (const exprt &e) const override
4550
+ // / this function determines which reference-typed expressions are constant
4551
+ bool is_constant_address_of (const exprt &e) const
4515
4552
{
4516
4553
if (e.id () == ID_symbol)
4517
4554
{
@@ -4522,8 +4559,27 @@ class is_compile_time_constantt : public is_constantt
4522
4559
return true ;
4523
4560
else if (e.id () == ID_label)
4524
4561
return true ;
4525
- else
4526
- return is_constantt::is_constant_address_of (e);
4562
+ else if (e.id () == ID_index)
4563
+ {
4564
+ const index_exprt &index_expr = to_index_expr (e);
4565
+
4566
+ return is_constant_address_of (index_expr.array ()) &&
4567
+ is_constant (index_expr.index ());
4568
+ }
4569
+ else if (e.id () == ID_member)
4570
+ {
4571
+ return is_constant_address_of (to_member_expr (e).compound ());
4572
+ }
4573
+ else if (e.id () == ID_dereference)
4574
+ {
4575
+ const dereference_exprt &deref = to_dereference_expr (e);
4576
+
4577
+ return is_constant (deref.pointer ());
4578
+ }
4579
+ else if (e.id () == ID_string_constant)
4580
+ return true ;
4581
+
4582
+ return false ;
4527
4583
}
4528
4584
};
4529
4585
0 commit comments