@@ -1276,4 +1276,60 @@ inline separate_exprt &to_separate_expr(exprt &expr)
1276
1276
return ret;
1277
1277
}
1278
1278
1279
+ // / A predicate that indicates that a zero-terminated string
1280
+ // / starts at the given address
1281
+ class is_cstring_exprt : public unary_predicate_exprt
1282
+ {
1283
+ public:
1284
+ explicit is_cstring_exprt (exprt address)
1285
+ : unary_predicate_exprt(ID_is_cstring, std::move(address))
1286
+ {
1287
+ PRECONDITION (this ->address ().type ().id () == ID_pointer);
1288
+ }
1289
+
1290
+ exprt &address ()
1291
+ {
1292
+ return op0 ();
1293
+ }
1294
+
1295
+ const exprt &address () const
1296
+ {
1297
+ return op0 ();
1298
+ }
1299
+ };
1300
+
1301
+ template <>
1302
+ inline bool can_cast_expr<is_cstring_exprt>(const exprt &base)
1303
+ {
1304
+ return base.id () == ID_is_cstring;
1305
+ }
1306
+
1307
+ inline void validate_expr (const is_cstring_exprt &value)
1308
+ {
1309
+ validate_operands (value, 1 , " is_cstring must have one operand" );
1310
+ }
1311
+
1312
+ // / \brief Cast an exprt to a \ref is_cstring_exprt
1313
+ // /
1314
+ // / \a expr must be known to be \ref is_cstring_exprt.
1315
+ // /
1316
+ // / \param expr: Source expression
1317
+ // / \return Object of type \ref is_cstring_exprt
1318
+ inline const is_cstring_exprt &to_is_cstring_expr (const exprt &expr)
1319
+ {
1320
+ PRECONDITION (expr.id () == ID_is_cstring);
1321
+ const is_cstring_exprt &ret = static_cast <const is_cstring_exprt &>(expr);
1322
+ validate_expr (ret);
1323
+ return ret;
1324
+ }
1325
+
1326
+ // / \copydoc to_is_cstring_expr(const exprt &)
1327
+ inline is_cstring_exprt &to_is_cstring_expr (exprt &expr)
1328
+ {
1329
+ PRECONDITION (expr.id () == ID_is_cstring);
1330
+ is_cstring_exprt &ret = static_cast <is_cstring_exprt &>(expr);
1331
+ validate_expr (ret);
1332
+ return ret;
1333
+ }
1334
+
1279
1335
#endif // CPROVER_UTIL_POINTER_EXPR_H
0 commit comments