Skip to content

Commit f755e00

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 9c7bccc commit f755e00

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/goto-programs/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>
@@ -1319,12 +1320,24 @@ void goto_convertt::do_function_call_symbol(
13191320
goto_programt::make_assignment(lhs, rhs, function.source_location()));
13201321
}
13211322

1322-
code_assignt assign{
1323-
list_arg, plus_exprt{list_arg, from_integer(1, pointer_diff_type())}};
1324-
assign.rhs().set(
1325-
ID_C_va_arg_type, to_code_type(function.type()).return_type());
1323+
exprt rhs;
1324+
if(list_arg.type() == pointer_type(pointer_type(empty_typet{})))
1325+
rhs = plus_exprt{list_arg, from_integer(1, pointer_diff_type())};
1326+
else
1327+
{
1328+
// handle unexpected va_list types by just enforcing pointer increments by
1329+
// size-of-void*
1330+
rhs = typecast_exprt{
1331+
plus_exprt{
1332+
typecast_exprt{list_arg, pointer_type(char_type())},
1333+
from_integer(
1334+
*pointer_offset_size(pointer_type(empty_typet{}), ns),
1335+
pointer_diff_type())},
1336+
list_arg.type()};
1337+
}
1338+
rhs.set(ID_C_va_arg_type, to_code_type(function.type()).return_type());
13261339
dest.add(goto_programt::make_assignment(
1327-
std::move(assign), function.source_location()));
1340+
list_arg, std::move(rhs), function.source_location()));
13281341
}
13291342
else if(identifier=="__builtin_va_copy")
13301343
{

0 commit comments

Comments
 (0)