Skip to content

Commit 790222a

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 ba47c86 commit 790222a

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/prefix.h>
2425
#include <util/rational.h>
2526
#include <util/rational_tools.h>
@@ -1299,12 +1300,24 @@ void goto_convertt::do_function_call_symbol(
12991300
goto_programt::make_assignment(lhs, rhs, function.source_location()));
13001301
}
13011302

1302-
code_assignt assign{
1303-
list_arg, plus_exprt{list_arg, from_integer(1, pointer_diff_type())}};
1304-
assign.rhs().set(
1305-
ID_C_va_arg_type, to_code_type(function.type()).return_type());
1303+
exprt rhs;
1304+
if(list_arg.type() == pointer_type(pointer_type(empty_typet{})))
1305+
rhs = plus_exprt{list_arg, from_integer(1, pointer_diff_type())};
1306+
else
1307+
{
1308+
// handle unexpected va_list types by just enforcing pointer increments by
1309+
// size-of-void*
1310+
rhs = typecast_exprt{
1311+
plus_exprt{
1312+
typecast_exprt{list_arg, pointer_type(char_type())},
1313+
from_integer(
1314+
*pointer_offset_size(pointer_type(empty_typet{}), ns),
1315+
pointer_diff_type())},
1316+
list_arg.type()};
1317+
}
1318+
rhs.set(ID_C_va_arg_type, to_code_type(function.type()).return_type());
13061319
dest.add(goto_programt::make_assignment(
1307-
std::move(assign), function.source_location()));
1320+
list_arg, std::move(rhs), function.source_location()));
13081321
}
13091322
else if(identifier=="__builtin_va_copy")
13101323
{

0 commit comments

Comments
 (0)