@@ -3925,6 +3925,38 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
3925
3925
throw 0 ;
3926
3926
}
3927
3927
3928
+ class is_compile_time_constantt : public is_constantt
3929
+ {
3930
+ public:
3931
+ explicit is_compile_time_constantt (const namespacet &ns) : ns(ns)
3932
+ {
3933
+ }
3934
+
3935
+ protected:
3936
+ const namespacet &ns;
3937
+
3938
+ bool is_constant (const exprt &e) const override
3939
+ {
3940
+ if (e.id () == ID_infinity)
3941
+ return true ;
3942
+ else
3943
+ return is_constantt::is_constant (e);
3944
+ }
3945
+
3946
+ bool is_constant_address_of (const exprt &e) const override
3947
+ {
3948
+ if (e.id () == ID_symbol)
3949
+ {
3950
+ return e.type ().id () == ID_code ||
3951
+ ns.lookup (to_symbol_expr (e).get_identifier ()).is_static_lifetime ;
3952
+ }
3953
+ else if (e.id () == ID_array && e.get_bool (ID_C_string_constant))
3954
+ return true ;
3955
+ else
3956
+ return is_constantt::is_constant_address_of (e);
3957
+ }
3958
+ };
3959
+
3928
3960
void c_typecheck_baset::make_constant (exprt &expr)
3929
3961
{
3930
3962
// Floating-point expressions may require a rounding mode.
@@ -3936,8 +3968,7 @@ void c_typecheck_baset::make_constant(exprt &expr)
3936
3968
3937
3969
simplify (expr, *this );
3938
3970
3939
- if (!expr.is_constant () &&
3940
- expr.id ()!=ID_infinity)
3971
+ if (!is_compile_time_constantt (*this )(expr))
3941
3972
{
3942
3973
error ().source_location =expr.find_source_location ();
3943
3974
error () << " expected constant expression, but got '" << to_string (expr)
@@ -3952,8 +3983,7 @@ void c_typecheck_baset::make_constant_index(exprt &expr)
3952
3983
make_index_type (expr);
3953
3984
simplify (expr, *this );
3954
3985
3955
- if (!expr.is_constant () &&
3956
- expr.id ()!=ID_infinity)
3986
+ if (!is_compile_time_constantt (*this )(expr))
3957
3987
{
3958
3988
error ().source_location =expr.find_source_location ();
3959
3989
error () << " conversion to integer constant failed" << eom;
0 commit comments