Skip to content

Commit d05703f

Browse files
committed
Variadic args/va_arg: handle unexpected va_list types
Our regression test has `void*` lists when we'd expected `void**`. This, however, went unnoticed as we only tried to access the first element. Attempts to access the second element would have been misaligned, and failed an invariant as of 35cc503 (we don't handle pointer arithmetic over void pointers in the back-end anymore). We now make sure that we always increment by size-of-`void*`. Fixes: #7706
1 parent 7eb77a8 commit d05703f

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

regression/cbmc/va_list2/main.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ void my_f(int first, ...)
1111

1212
int v;
1313
v=__builtin_va_arg(args, int);
14-
assert(v==2);
14+
assert(v == 1);
15+
v = __builtin_va_arg(args, int);
16+
assert(v == 0);
1517

1618
__builtin_va_end(args);
1719
}
1820

1921
int main()
2022
{
21-
my_f(1, 2);
23+
my_f(2, 1, 0);
2224
}
2325

2426
#else

src/ansi-c/goto-conversion/builtin_functions.cpp

+18-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Author: Daniel Kroening, [email protected]
2020
#include <util/mathematical_expr.h>
2121
#include <util/mathematical_types.h>
2222
#include <util/pointer_expr.h>
23+
#include <util/pointer_offset_size.h>
2324
#include <util/rational.h>
2425
#include <util/rational_tools.h>
2526
#include <util/simplify_expr.h>
@@ -1306,12 +1307,24 @@ void goto_convertt::do_function_call_symbol(
13061307
goto_programt::make_assignment(lhs, rhs, function.source_location()));
13071308
}
13081309

1309-
code_assignt assign{
1310-
list_arg, plus_exprt{list_arg, from_integer(1, pointer_diff_type())}};
1311-
assign.rhs().set(
1312-
ID_C_va_arg_type, to_code_type(function.type()).return_type());
1310+
exprt rhs;
1311+
if(list_arg.type() == pointer_type(pointer_type(empty_typet{})))
1312+
rhs = plus_exprt{list_arg, from_integer(1, pointer_diff_type())};
1313+
else
1314+
{
1315+
// handle unexpected va_list types by just enforcing pointer increments by
1316+
// size-of-void*
1317+
rhs = typecast_exprt{
1318+
plus_exprt{
1319+
typecast_exprt{list_arg, pointer_type(char_type())},
1320+
from_integer(
1321+
*pointer_offset_size(pointer_type(empty_typet{}), ns),
1322+
pointer_diff_type())},
1323+
list_arg.type()};
1324+
}
1325+
rhs.set(ID_C_va_arg_type, to_code_type(function.type()).return_type());
13131326
dest.add(goto_programt::make_assignment(
1314-
std::move(assign), function.source_location()));
1327+
list_arg, std::move(rhs), function.source_location()));
13151328
}
13161329
else if(identifier == "__builtin_va_copy")
13171330
{

0 commit comments

Comments
 (0)