Skip to content

Commit 9f30ce1

Browse files
authored
Merge pull request #4176 from tautschnig/make-cast-const
Cleanup expression/code cast validation
2 parents 1e3f64d + d4dc77f commit 9f30ce1

File tree

4 files changed

+1225
-1243
lines changed

4 files changed

+1225
-1243
lines changed

src/util/mathematical_expr.h

Lines changed: 104 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -61,35 +61,36 @@ class transt : public ternary_exprt
6161
}
6262
};
6363

64+
template <>
65+
inline bool can_cast_expr<transt>(const exprt &base)
66+
{
67+
return base.id() == ID_trans;
68+
}
69+
70+
inline void validate_expr(const transt &value)
71+
{
72+
validate_operands(value, 3, "Transition systems must have three operands");
73+
}
74+
6475
/// Cast an exprt to a \ref transt
6576
/// \a expr must be known to be \ref transt.
6677
/// \param expr: Source expression
6778
/// \return Object of type \ref transt
6879
inline const transt &to_trans_expr(const exprt &expr)
6980
{
7081
PRECONDITION(expr.id() == ID_trans);
71-
DATA_INVARIANT(
72-
expr.operands().size() == 3, "Transition systems must have three operands");
73-
return static_cast<const transt &>(expr);
82+
const transt &ret = static_cast<const transt &>(expr);
83+
validate_expr(ret);
84+
return ret;
7485
}
7586

7687
/// \copydoc to_trans_expr(const exprt &)
7788
inline transt &to_trans_expr(exprt &expr)
7889
{
7990
PRECONDITION(expr.id() == ID_trans);
80-
DATA_INVARIANT(
81-
expr.operands().size() == 3, "Transition systems must have three operands");
82-
return static_cast<transt &>(expr);
83-
}
84-
85-
template <>
86-
inline bool can_cast_expr<transt>(const exprt &base)
87-
{
88-
return base.id() == ID_trans;
89-
}
90-
inline void validate_expr(const transt &value)
91-
{
92-
validate_operands(value, 3, "Transition systems must have three operands");
91+
transt &ret = static_cast<transt &>(expr);
92+
validate_expr(ret);
93+
return ret;
9394
}
9495

9596
/// \brief Exponentiation
@@ -107,6 +108,17 @@ class power_exprt : public binary_exprt
107108
}
108109
};
109110

111+
template <>
112+
inline bool can_cast_expr<power_exprt>(const exprt &base)
113+
{
114+
return base.id() == ID_power;
115+
}
116+
117+
inline void validate_expr(const power_exprt &value)
118+
{
119+
validate_operands(value, 2, "Power must have two operands");
120+
}
121+
110122
/// \brief Cast an exprt to a \ref power_exprt
111123
///
112124
/// \a expr must be known to be \ref power_exprt.
@@ -116,26 +128,18 @@ class power_exprt : public binary_exprt
116128
inline const power_exprt &to_power_expr(const exprt &expr)
117129
{
118130
PRECONDITION(expr.id() == ID_power);
119-
DATA_INVARIANT(expr.operands().size() == 2, "Power must have two operands");
120-
return static_cast<const power_exprt &>(expr);
131+
const power_exprt &ret = static_cast<const power_exprt &>(expr);
132+
validate_expr(ret);
133+
return ret;
121134
}
122135

123136
/// \copydoc to_power_expr(const exprt &)
124137
inline power_exprt &to_power_expr(exprt &expr)
125138
{
126139
PRECONDITION(expr.id() == ID_power);
127-
DATA_INVARIANT(expr.operands().size() == 2, "Power must have two operands");
128-
return static_cast<power_exprt &>(expr);
129-
}
130-
131-
template <>
132-
inline bool can_cast_expr<power_exprt>(const exprt &base)
133-
{
134-
return base.id() == ID_power;
135-
}
136-
inline void validate_expr(const power_exprt &value)
137-
{
138-
validate_operands(value, 2, "Power must have two operands");
140+
power_exprt &ret = static_cast<power_exprt &>(expr);
141+
validate_expr(ret);
142+
return ret;
139143
}
140144

141145
/// \brief Falling factorial power
@@ -153,6 +157,17 @@ class factorial_power_exprt : public binary_exprt
153157
}
154158
};
155159

160+
template <>
161+
inline bool can_cast_expr<factorial_power_exprt>(const exprt &base)
162+
{
163+
return base.id() == ID_factorial_power;
164+
}
165+
166+
inline void validate_expr(const factorial_power_exprt &value)
167+
{
168+
validate_operands(value, 2, "Factorial power must have two operands");
169+
}
170+
156171
/// \brief Cast an exprt to a \ref factorial_power_exprt
157172
///
158173
/// \a expr must be known to be \ref factorial_power_exprt.
@@ -162,28 +177,19 @@ class factorial_power_exprt : public binary_exprt
162177
inline const factorial_power_exprt &to_factorial_power_expr(const exprt &expr)
163178
{
164179
PRECONDITION(expr.id() == ID_factorial_power);
165-
DATA_INVARIANT(
166-
expr.operands().size() == 2, "Factorial power must have two operands");
167-
return static_cast<const factorial_power_exprt &>(expr);
180+
const factorial_power_exprt &ret =
181+
static_cast<const factorial_power_exprt &>(expr);
182+
validate_expr(ret);
183+
return ret;
168184
}
169185

170186
/// \copydoc to_factorial_power_expr(const exprt &)
171187
inline factorial_power_exprt &to_factorial_expr(exprt &expr)
172188
{
173189
PRECONDITION(expr.id() == ID_factorial_power);
174-
DATA_INVARIANT(
175-
expr.operands().size() == 2, "Factorial power must have two operands");
176-
return static_cast<factorial_power_exprt &>(expr);
177-
}
178-
179-
template <>
180-
inline bool can_cast_expr<factorial_power_exprt>(const exprt &base)
181-
{
182-
return base.id() == ID_factorial_power;
183-
}
184-
inline void validate_expr(const factorial_power_exprt &value)
185-
{
186-
validate_operands(value, 2, "Factorial power must have two operands");
190+
factorial_power_exprt &ret = static_cast<factorial_power_exprt &>(expr);
191+
validate_expr(ret);
192+
return ret;
187193
}
188194

189195
class tuple_exprt : public multi_ary_exprt
@@ -239,6 +245,17 @@ class function_application_exprt : public binary_exprt
239245
}
240246
};
241247

248+
template <>
249+
inline bool can_cast_expr<function_application_exprt>(const exprt &base)
250+
{
251+
return base.id() == ID_function_application;
252+
}
253+
254+
inline void validate_expr(const function_application_exprt &value)
255+
{
256+
validate_operands(value, 2, "Function application must have two operands");
257+
}
258+
242259
/// \brief Cast an exprt to a \ref function_application_exprt
243260
///
244261
/// \a expr must be known to be \ref function_application_exprt.
@@ -249,28 +266,20 @@ inline const function_application_exprt &
249266
to_function_application_expr(const exprt &expr)
250267
{
251268
PRECONDITION(expr.id() == ID_function_application);
252-
DATA_INVARIANT(
253-
expr.operands().size() == 2, "Function application must have two operands");
254-
return static_cast<const function_application_exprt &>(expr);
269+
const function_application_exprt &ret =
270+
static_cast<const function_application_exprt &>(expr);
271+
validate_expr(ret);
272+
return ret;
255273
}
256274

257275
/// \copydoc to_function_application_expr(const exprt &)
258276
inline function_application_exprt &to_function_application_expr(exprt &expr)
259277
{
260278
PRECONDITION(expr.id() == ID_function_application);
261-
DATA_INVARIANT(
262-
expr.operands().size() == 2, "Function application must have two operands");
263-
return static_cast<function_application_exprt &>(expr);
264-
}
265-
266-
template <>
267-
inline bool can_cast_expr<function_application_exprt>(const exprt &base)
268-
{
269-
return base.id() == ID_function_application;
270-
}
271-
inline void validate_expr(const function_application_exprt &value)
272-
{
273-
validate_operands(value, 2, "Function application must have two operands");
279+
function_application_exprt &ret =
280+
static_cast<function_application_exprt &>(expr);
281+
validate_expr(ret);
282+
return ret;
274283
}
275284

276285
/// \brief A base class for quantifier expressions
@@ -306,6 +315,19 @@ class quantifier_exprt : public binary_predicate_exprt
306315
}
307316
};
308317

318+
template <>
319+
inline bool can_cast_expr<quantifier_exprt>(const exprt &base)
320+
{
321+
return base.id() == ID_forall || base.id() == ID_exists;
322+
}
323+
324+
inline void validate_expr(const quantifier_exprt &value)
325+
{
326+
validate_operands(value, 2, "quantifier expressions must have two operands");
327+
DATA_INVARIANT(
328+
value.op0().id() == ID_symbol, "quantified variable shall be a symbol");
329+
}
330+
309331
/// \brief Cast an exprt to a \ref quantifier_exprt
310332
///
311333
/// \a expr must be known to be \ref quantifier_exprt.
@@ -314,34 +336,19 @@ class quantifier_exprt : public binary_predicate_exprt
314336
/// \return Object of type \ref quantifier_exprt
315337
inline const quantifier_exprt &to_quantifier_expr(const exprt &expr)
316338
{
317-
DATA_INVARIANT(
318-
expr.operands().size() == 2,
319-
"quantifier expressions must have two operands");
320-
DATA_INVARIANT(
321-
expr.op0().id() == ID_symbol, "quantified variable shall be a symbol");
322-
return static_cast<const quantifier_exprt &>(expr);
339+
PRECONDITION(can_cast_expr<quantifier_exprt>(expr));
340+
const quantifier_exprt &ret = static_cast<const quantifier_exprt &>(expr);
341+
validate_expr(ret);
342+
return ret;
323343
}
324344

325345
/// \copydoc to_quantifier_expr(const exprt &)
326346
inline quantifier_exprt &to_quantifier_expr(exprt &expr)
327347
{
328-
DATA_INVARIANT(
329-
expr.operands().size() == 2,
330-
"quantifier expressions must have two operands");
331-
DATA_INVARIANT(
332-
expr.op0().id() == ID_symbol, "quantified variable shall be a symbol");
333-
return static_cast<quantifier_exprt &>(expr);
334-
}
335-
336-
template <>
337-
inline bool can_cast_expr<quantifier_exprt>(const exprt &base)
338-
{
339-
return base.id() == ID_forall || base.id() == ID_exists;
340-
}
341-
342-
inline void validate_expr(const quantifier_exprt &value)
343-
{
344-
validate_operands(value, 2, "quantifier expressions must have two operands");
348+
PRECONDITION(can_cast_expr<quantifier_exprt>(expr));
349+
quantifier_exprt &ret = static_cast<quantifier_exprt &>(expr);
350+
validate_expr(ret);
351+
return ret;
345352
}
346353

347354
/// \brief A forall expression
@@ -357,19 +364,17 @@ class forall_exprt : public quantifier_exprt
357364
inline const forall_exprt &to_forall_expr(const exprt &expr)
358365
{
359366
PRECONDITION(expr.id() == ID_forall);
360-
DATA_INVARIANT(
361-
expr.operands().size() == 2,
362-
"forall expressions have exactly two operands");
363-
return static_cast<const forall_exprt &>(expr);
367+
const forall_exprt &ret = static_cast<const forall_exprt &>(expr);
368+
validate_expr(static_cast<const quantifier_exprt &>(ret));
369+
return ret;
364370
}
365371

366372
inline forall_exprt &to_forall_expr(exprt &expr)
367373
{
368374
PRECONDITION(expr.id() == ID_forall);
369-
DATA_INVARIANT(
370-
expr.operands().size() == 2,
371-
"forall expressions have exactly two operands");
372-
return static_cast<forall_exprt &>(expr);
375+
forall_exprt &ret = static_cast<forall_exprt &>(expr);
376+
validate_expr(static_cast<const quantifier_exprt &>(ret));
377+
return ret;
373378
}
374379

375380
/// \brief An exists expression
@@ -385,19 +390,17 @@ class exists_exprt : public quantifier_exprt
385390
inline const exists_exprt &to_exists_expr(const exprt &expr)
386391
{
387392
PRECONDITION(expr.id() == ID_exists);
388-
DATA_INVARIANT(
389-
expr.operands().size() == 2,
390-
"exists expressions have exactly two operands");
391-
return static_cast<const exists_exprt &>(expr);
393+
const exists_exprt &ret = static_cast<const exists_exprt &>(expr);
394+
validate_expr(static_cast<const quantifier_exprt &>(ret));
395+
return ret;
392396
}
393397

394398
inline exists_exprt &to_exists_expr(exprt &expr)
395399
{
396400
PRECONDITION(expr.id() == ID_exists);
397-
DATA_INVARIANT(
398-
expr.operands().size() == 2,
399-
"exists expressions have exactly two operands");
400-
return static_cast<exists_exprt &>(expr);
401+
exists_exprt &ret = static_cast<exists_exprt &>(expr);
402+
validate_expr(static_cast<const quantifier_exprt &>(ret));
403+
return ret;
401404
}
402405

403406
#endif // CPROVER_UTIL_MATHEMATICAL_EXPR_H

0 commit comments

Comments
 (0)