Skip to content

Commit ef76a0f

Browse files
committed
Make is_compile_time_constantt independent of is_constantt
Compile-time constants can only be ones that actually appear in the front-end. In a future commit is_constantt will be further disambiguated and be renamed to can_forward_propagatet.
1 parent b155fb0 commit ef76a0f

File tree

1 file changed

+64
-8
lines changed

1 file changed

+64
-8
lines changed

src/ansi-c/c_typecheck_expr.cpp

+64-8
Original file line numberDiff line numberDiff line change
@@ -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
{
45004503
public:
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+
45054514
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
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

Comments
 (0)