Skip to content

Commit 0a73e03

Browse files
committed
std_expr.h: add/enable missing can_cast, validate_expr
Some were unnecessarily missing, others were wrongly commented out.
1 parent b61e3f1 commit 0a73e03

File tree

2 files changed

+59
-38
lines changed

2 files changed

+59
-38
lines changed

src/util/std_expr.h

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ inline bool can_cast_expr<unary_exprt>(const exprt &base)
354354
return base.operands().size() == 1;
355355
}
356356

357+
inline void validate_expr(const unary_exprt &value)
358+
{
359+
validate_operands(value, 1, "Unary expressions must have one operand");
360+
}
361+
357362
/// \brief Cast an exprt to a \ref unary_exprt
358363
///
359364
/// \a expr must be known to be \ref unary_exprt.
@@ -774,6 +779,11 @@ inline bool can_cast_expr<binary_exprt>(const exprt &base)
774779
return base.operands().size() == 2;
775780
}
776781

782+
inline void validate_expr(const binary_exprt &value)
783+
{
784+
validate_operands(value, 2, "Binary expressions must have two operands");
785+
}
786+
777787
/// \brief Cast an exprt to a \ref binary_exprt
778788
///
779789
/// \a expr must be known to be \ref binary_exprt.
@@ -912,6 +922,11 @@ inline bool can_cast_expr<binary_relation_exprt>(const exprt &base)
912922
return can_cast_expr<binary_exprt>(base);
913923
}
914924

925+
inline void validate_expr(const binary_relation_exprt &value)
926+
{
927+
validate_operands(value, 2, "Binary relations must have two operands");
928+
}
929+
915930
/// \brief Cast an exprt to a \ref binary_relation_exprt
916931
///
917932
/// \a expr must be known to be \ref binary_relation_exprt.
@@ -2657,10 +2672,10 @@ inline bool can_cast_expr<bitnot_exprt>(const exprt &base)
26572672
return base.id() == ID_bitnot;
26582673
}
26592674

2660-
// inline void validate_expr(const bitnot_exprt &value)
2661-
// {
2662-
// validate_operands(value, 1, "Bit-wise not must have one operand");
2663-
// }
2675+
inline void validate_expr(const bitnot_exprt &value)
2676+
{
2677+
validate_operands(value, 1, "Bit-wise not must have one operand");
2678+
}
26642679

26652680
/// \brief Cast an exprt to a \ref bitnot_exprt
26662681
///
@@ -2671,17 +2686,17 @@ inline bool can_cast_expr<bitnot_exprt>(const exprt &base)
26712686
inline const bitnot_exprt &to_bitnot_expr(const exprt &expr)
26722687
{
26732688
PRECONDITION(expr.id()==ID_bitnot);
2674-
// DATA_INVARIANT(expr.operands().size()==1,
2675-
// "Bit-wise not must have one operand");
2689+
DATA_INVARIANT(
2690+
expr.operands().size() == 1, "Bit-wise not must have one operand");
26762691
return static_cast<const bitnot_exprt &>(expr);
26772692
}
26782693

26792694
/// \copydoc to_bitnot_expr(const exprt &)
26802695
inline bitnot_exprt &to_bitnot_expr(exprt &expr)
26812696
{
26822697
PRECONDITION(expr.id()==ID_bitnot);
2683-
// DATA_INVARIANT(expr.operands().size()==1,
2684-
// "Bit-wise not must have one operand");
2698+
DATA_INVARIANT(
2699+
expr.operands().size() == 1, "Bit-wise not must have one operand");
26852700
return static_cast<bitnot_exprt &>(expr);
26862701
}
26872702

@@ -2900,13 +2915,16 @@ class shift_exprt:public binary_exprt
29002915
}
29012916
};
29022917

2903-
// The to_*_expr function for this type doesn't do any checks before casting,
2904-
// therefore the implementation is essentially a static_cast.
2905-
// Enabling expr_dynamic_cast would hide this; instead use static_cast directly.
2906-
// inline void validate_expr(const shift_exprt &value)
2907-
// {
2908-
// validate_operands(value, 2, "Shifts must have two operands");
2909-
// }
2918+
template <>
2919+
inline bool can_cast_expr<shift_exprt>(const exprt &base)
2920+
{
2921+
return base.id() == ID_shl || base.id() == ID_ashr || base.id() == ID_lshr;
2922+
}
2923+
2924+
inline void validate_expr(const shift_exprt &value)
2925+
{
2926+
validate_operands(value, 2, "Shifts must have two operands");
2927+
}
29102928

29112929
/// \brief Cast an exprt to a \ref shift_exprt
29122930
///
@@ -3516,6 +3534,8 @@ inline bool can_cast_expr<with_exprt>(const exprt &base)
35163534

35173535
inline void validate_expr(const with_exprt &value)
35183536
{
3537+
validate_operands(
3538+
value, 3, "array/structure update must have at least 3 operands", true);
35193539
DATA_INVARIANT(
35203540
value.operands().size() % 2 == 1,
35213541
"array/structure update must have an odd number of operands");
@@ -4286,18 +4306,18 @@ class ieee_float_op_exprt : public ternary_exprt
42864306
}
42874307
};
42884308

4289-
// The to_*_expr function for this type doesn't do any checks before casting,
4290-
// therefore the implementation is essentially a static_cast.
4291-
// Enabling expr_dynamic_cast would hide this; instead use static_cast directly.
4292-
// template<>
4293-
// inline void validate_expr<ieee_float_op_exprt>(
4294-
// const ieee_float_op_exprt &value)
4295-
// {
4296-
// validate_operands(
4297-
// value,
4298-
// 3,
4299-
// "IEEE float operations must have three arguments");
4300-
// }
4309+
template <>
4310+
inline bool can_cast_expr<ieee_float_op_exprt>(const exprt &base)
4311+
{
4312+
return base.id() == ID_floatbv_plus || base.id() == ID_floatbv_minus ||
4313+
base.id() == ID_floatbv_div || base.id() == ID_floatbv_mult;
4314+
}
4315+
4316+
inline void validate_expr(const ieee_float_op_exprt &value)
4317+
{
4318+
validate_operands(
4319+
value, 3, "IEEE float operations must have three arguments");
4320+
}
43014321

43024322
/// \brief Cast an exprt to an \ref ieee_float_op_exprt
43034323
///
@@ -4748,6 +4768,18 @@ class cond_exprt : public multi_ary_exprt
47484768
}
47494769
};
47504770

4771+
template <>
4772+
inline bool can_cast_expr<cond_exprt>(const exprt &base)
4773+
{
4774+
return base.id() == ID_cond;
4775+
}
4776+
4777+
inline void validate_expr(const cond_exprt &value)
4778+
{
4779+
DATA_INVARIANT(
4780+
value.operands().size() % 2 == 0, "cond must have even number of operands");
4781+
}
4782+
47514783
/// \brief Cast an exprt to a \ref cond_exprt
47524784
///
47534785
/// \a expr must be known to be \ref cond_exprt.

unit/util/expr_cast/expr_undefined_casts.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,6 @@ SCENARIO("expr_dynamic_cast",
2626
{
2727
const exprt &expr=symbol_expr;
2828

29-
THEN("Casting from exprt reference to ieee_float_op_exprt "
30-
"should not compile")
31-
{
32-
// This shouldn't compile
33-
expr_dynamic_cast<const ieee_float_op_exprt &>(expr);
34-
}
35-
THEN("Casting from exprt reference to shift_exprt should not compile")
36-
{
37-
// This shouldn't compile
38-
expr_dynamic_cast<const shift_exprt &>(expr);
39-
}
4029
THEN(
4130
"Casting from exprt reference to non-reference should not compile")
4231
{

0 commit comments

Comments
 (0)