@@ -4495,23 +4495,60 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
44954495 throw 0 ;
44964496}
44974497
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
44994502{
45004503public:
4501- explicit is_compile_time_constantt (const namespacet &ns) : is_constantt (ns)
4504+ explicit is_compile_time_constantt (const namespacet &ns) : ns (ns)
45024505 {
45034506 }
45044507
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+
45054514protected:
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
45074520 {
45084521 if (e.id () == ID_infinity)
45094522 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 ;
45124548 }
45134549
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
45154552 {
45164553 if (e.id () == ID_symbol)
45174554 {
@@ -4522,8 +4559,27 @@ class is_compile_time_constantt : public is_constantt
45224559 return true ;
45234560 else if (e.id () == ID_label)
45244561 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 ;
45274583 }
45284584};
45294585
0 commit comments