Skip to content

Commit 5100bb8

Browse files
committed
Fix printf formatting of C strings
We had failed to update printf formatting to accomodate annotated_pointer_constant expressions (#6598). Fixes: #8204
1 parent 1fd7011 commit 5100bb8

File tree

4 files changed

+45
-7
lines changed

4 files changed

+45
-7
lines changed

regression/cbmc/printf2/main.c

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <assert.h>
2+
#include <stdio.h>
3+
4+
int main()
5+
{
6+
printf("results: %s, %d", "five", 5);
7+
assert(0);
8+
}

regression/cbmc/printf2/test.desc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE no-new-smt
2+
main.c
3+
--trace
4+
^results: five, 5$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring

src/goto-programs/printf_formatter.cpp

+22-6
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,29 @@ void printf_formattert::process_format(std::ostream &out)
136136
// this is the address of a string
137137
const exprt &op=*(next_operand++);
138138
if(
139-
op.id() == ID_address_of &&
140-
to_address_of_expr(op).object().id() == ID_index &&
141-
to_index_expr(to_address_of_expr(op).object()).array().id() ==
142-
ID_string_constant)
139+
auto pointer_constant =
140+
expr_try_dynamic_cast<annotated_pointer_constant_exprt>(op))
143141
{
144-
out << format_constant(
145-
to_index_expr(to_address_of_expr(op).object()).array());
142+
if(
143+
auto address_of = expr_try_dynamic_cast<address_of_exprt>(
144+
skip_typecast(pointer_constant->symbolic_pointer())))
145+
{
146+
if(address_of->object().id() == ID_string_constant)
147+
{
148+
out << format_constant(address_of->object());
149+
}
150+
else if(
151+
auto index_expr =
152+
expr_try_dynamic_cast<index_exprt>(address_of->object()))
153+
{
154+
if(
155+
index_expr->index().is_zero() &&
156+
index_expr->array().id() == ID_string_constant)
157+
{
158+
out << format_constant(index_expr->array());
159+
}
160+
}
161+
}
146162
}
147163
}
148164
break;

src/goto-symex/symex_builtin_functions.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -397,10 +397,16 @@ void goto_symext::symex_printf(
397397
return;
398398
}
399399

400+
// Visual Studio has va_list == char*, else we have va_list == void** and
401+
// need to add dereferencing
402+
const bool need_deref =
403+
operands.back().type().id() == ID_pointer &&
404+
to_pointer_type(operands.back().type()).base_type().id() == ID_pointer;
405+
400406
for(const auto &op : va_args->operands())
401407
{
402408
exprt parameter = skip_typecast(op);
403-
if(parameter.id() == ID_address_of)
409+
if(need_deref && parameter.id() == ID_address_of)
404410
parameter = to_address_of_expr(parameter).object();
405411
clean_expr(parameter, state, false);
406412
parameter = state.rename(std::move(parameter), ns).get();

0 commit comments

Comments
 (0)