Skip to content

Commit 211fd5e

Browse files
Handle the case of null arguments for format
1 parent 770af93 commit 211fd5e

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

src/solvers/strings/string_constraint_generator_format.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,11 @@ add_axioms_for_format_specifier(
285285
return_code = add_axioms_for_string_of_float(
286286
fresh_symbol, res, get_arg(ID_float), array_pool, ns);
287287
return {res, std::move(return_code.second)};
288-
case format_specifiert::CHARACTER:
289-
return_code = add_axioms_from_char(res, get_arg(ID_char));
290-
return {res, std::move(return_code.second)};
288+
case format_specifiert::CHARACTER: {
289+
exprt arg_string = get_arg(ID_char);
290+
array_string_exprt &string_expr = to_array_string_expr(arg_string);
291+
return {std::move(string_expr), {}};
292+
}
291293
case format_specifiert::BOOLEAN:
292294
return_code = add_axioms_from_bool(res, get_arg(ID_boolean));
293295
return {res, std::move(return_code.second)};
@@ -378,23 +380,34 @@ exprt format_arg_from_string(
378380
shl_exprt{typecast_exprt{string[2], type}, 16},
379381
typecast_exprt{string[3], type}}};
380382
}
383+
384+
const and_exprt is_null{
385+
equal_exprt{string.length(), from_integer(4, string.length().type())},
386+
and_exprt{
387+
equal_exprt{string[0], from_integer('n', string[0].type())},
388+
equal_exprt{string[1], from_integer('u', string[0].type())},
389+
equal_exprt{string[2], from_integer('l', string[0].type())},
390+
equal_exprt{string[3], from_integer('l', string[0].type())}}
391+
};
392+
381393
if(id == ID_char)
382394
{
383-
// We assume the string has length exactly 4 and ignore the first 3
384-
// (unsigned16)string.content[3]
385-
const unsignedbv_typet type{16};
386-
return typecast_exprt{
395+
// We assume the string has length exactly 4 and ignore the first 3, and
396+
// construct a string of length 1, which contains (char)string.content[3]
397+
array_string_exprt char_as_string;
398+
char_as_string.type() = array_typet{
399+
string.type().subtype(), from_integer(1, string.length().type())};
400+
char_as_string.operands().push_back(typecast_exprt{
387401
index_exprt{string.content(), from_integer(3, string.length().type())},
388-
type};
402+
string.type().subtype()});
403+
return if_exprt{is_null, string, char_as_string};
389404
}
390405
if(id == ID_boolean)
391406
{
392-
// We assume the string has length exactly 4 and ignore the first 3
393-
// (bool)string.content[3]
394-
const c_bool_typet type{8};
395-
return typecast_exprt{
396-
index_exprt{string.content(), from_integer(3, string.length().type())},
397-
type};
407+
// We assume the string has length exactly 4, if it is "null" return false
408+
// and otherwise ignore the first 3 and return (bool)string.content[3]
409+
return if_exprt{
410+
is_null, false_exprt{}, typecast_exprt{string[3], bool_typet()}};
398411
}
399412
if(id == ID_float)
400413
{

0 commit comments

Comments
 (0)