Skip to content

Commit 8a09391

Browse files
authored
Merge pull request #7128 from diffblue/cstrlen_exprt
introduce cstrlen_exprt
2 parents 13db9b9 + 4fe5b9d commit 8a09391

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2441,7 +2441,7 @@ exprt c_typecheck_baset::do_special_functions(
24412441
throw 0;
24422442
}
24432443

2444-
unary_exprt cstrlen_expr("cstrlen", expr.arguments()[0], size_type());
2444+
cstrlen_exprt cstrlen_expr(expr.arguments()[0], size_type());
24452445
cstrlen_expr.add_source_location() = source_location;
24462446

24472447
return std::move(cstrlen_expr);

src/util/irep_ids.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ IREP_ID_ONE(string)
156156
IREP_ID_ONE(is_cstring)
157157
IREP_ID_TWO(C_string_constant, #string_constant)
158158
IREP_ID_ONE(string_constant)
159+
IREP_ID_ONE(cstrlen)
159160
IREP_ID_ONE(width)
160161
IREP_ID_ONE(components)
161162
IREP_ID_ONE(bv)

src/util/pointer_expr.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,63 @@ inline is_cstring_exprt &to_is_cstring_expr(exprt &expr)
11151115
return ret;
11161116
}
11171117

1118+
/// An expression, akin to ISO C's strlen, that denotes the
1119+
/// length of a zero-terminated string that starts at the
1120+
/// given address. The trailing zero is not included in the count.
1121+
class cstrlen_exprt : public unary_exprt
1122+
{
1123+
public:
1124+
cstrlen_exprt(exprt address, typet type)
1125+
: unary_exprt(ID_cstrlen, std::move(address), std::move(type))
1126+
{
1127+
PRECONDITION(as_const(*this).address().type().id() == ID_pointer);
1128+
}
1129+
1130+
exprt &address()
1131+
{
1132+
return op0();
1133+
}
1134+
1135+
const exprt &address() const
1136+
{
1137+
return op0();
1138+
}
1139+
};
1140+
1141+
template <>
1142+
inline bool can_cast_expr<cstrlen_exprt>(const exprt &base)
1143+
{
1144+
return base.id() == ID_cstrlen;
1145+
}
1146+
1147+
inline void validate_expr(const cstrlen_exprt &value)
1148+
{
1149+
validate_operands(value, 1, "cstrlen must have one operand");
1150+
}
1151+
1152+
/// \brief Cast an exprt to a \ref cstrlen_exprt
1153+
///
1154+
/// \a expr must be known to be \ref cstrlen_exprt.
1155+
///
1156+
/// \param expr: Source expression
1157+
/// \return Object of type \ref cstrlen_exprt
1158+
inline const cstrlen_exprt &to_cstrlen_expr(const exprt &expr)
1159+
{
1160+
PRECONDITION(expr.id() == ID_cstrlen);
1161+
const cstrlen_exprt &ret = static_cast<const cstrlen_exprt &>(expr);
1162+
validate_expr(ret);
1163+
return ret;
1164+
}
1165+
1166+
/// \copydoc to_cstrlen_expr(const exprt &)
1167+
inline cstrlen_exprt &to_cstrlen_expr(exprt &expr)
1168+
{
1169+
PRECONDITION(expr.id() == ID_cstrlen);
1170+
cstrlen_exprt &ret = static_cast<cstrlen_exprt &>(expr);
1171+
validate_expr(ret);
1172+
return ret;
1173+
}
1174+
11181175
/// A predicate that indicates that the object pointed to is live
11191176
class live_object_exprt : public unary_predicate_exprt
11201177
{

0 commit comments

Comments
 (0)