Skip to content

Commit bf439bd

Browse files
committed
C front-end: Use is_constantt to recognise further compile-time constants
Arrays and structs (and any nesting thereof) could also be compile-time constants.
1 parent eddc014 commit bf439bd

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3925,6 +3925,38 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
39253925
throw 0;
39263926
}
39273927

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+
39283960
void c_typecheck_baset::make_constant(exprt &expr)
39293961
{
39303962
// Floating-point expressions may require a rounding mode.
@@ -3936,8 +3968,7 @@ void c_typecheck_baset::make_constant(exprt &expr)
39363968

39373969
simplify(expr, *this);
39383970

3939-
if(!expr.is_constant() &&
3940-
expr.id()!=ID_infinity)
3971+
if(!is_compile_time_constantt(*this)(expr))
39413972
{
39423973
error().source_location=expr.find_source_location();
39433974
error() << "expected constant expression, but got '" << to_string(expr)
@@ -3952,8 +3983,7 @@ void c_typecheck_baset::make_constant_index(exprt &expr)
39523983
make_index_type(expr);
39533984
simplify(expr, *this);
39543985

3955-
if(!expr.is_constant() &&
3956-
expr.id()!=ID_infinity)
3986+
if(!is_compile_time_constantt(*this)(expr))
39573987
{
39583988
error().source_location=expr.find_source_location();
39593989
error() << "conversion to integer constant failed" << eom;

src/util/expr_util.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ bool is_constantt::is_constant(const exprt &expr) const
236236
expr.id() == ID_typecast || expr.id() == ID_array_of ||
237237
expr.id() == ID_plus || expr.id() == ID_mult || expr.id() == ID_array ||
238238
expr.id() == ID_with || expr.id() == ID_struct || expr.id() == ID_union ||
239+
expr.id() == ID_empty_union ||
239240
// byte_update works, byte_extract may be out-of-bounds
240241
expr.id() == ID_byte_update_big_endian ||
241242
expr.id() == ID_byte_update_little_endian)

0 commit comments

Comments
 (0)