Skip to content

Commit e4d7411

Browse files
committed
Function pointer removal: argument conversion must use byte extract
Only POD can be handled via type casts, all other cases require reinterpreting the byte sequence. For POD, the simplifier will clean up the byte extract. The same problem had already been fixed for goto-symex' function argument conversion back in bb80cdc. Co-authored-by: Celina G. Val <[email protected]> Fixes: #6956
1 parent a0d4239 commit e4d7411

File tree

5 files changed

+71
-6
lines changed

5 files changed

+71
-6
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <assert.h>
2+
3+
struct PtrWrapperInner
4+
{
5+
int *value;
6+
};
7+
8+
struct PtrWrapper
9+
{
10+
int *value;
11+
struct PtrWrapperInner inner;
12+
};
13+
14+
struct AltPtrWrapperInner
15+
{
16+
int *value;
17+
};
18+
19+
struct AltPtrWrapper
20+
{
21+
unsigned int *value;
22+
// A) Doesn't work
23+
struct AltPtrWrapperInner inner;
24+
// B) Works
25+
// struct PtrWrapperInner inner;
26+
};
27+
28+
void fn(struct PtrWrapper wrapper)
29+
{
30+
assert(*wrapper.value == 10);
31+
assert(*wrapper.inner.value == 10);
32+
}
33+
34+
int main()
35+
{
36+
int ret = 10;
37+
int *ptr = &ret;
38+
39+
struct AltPtrWrapper alt;
40+
alt.inner.value = ptr;
41+
alt.value = ptr;
42+
43+
// Casting the structure itself works.
44+
struct PtrWrapper wrapper = *(struct PtrWrapper *)&alt;
45+
assert(*wrapper.value == 10);
46+
assert(*wrapper.inner.value == 10);
47+
48+
// This only works if there is one level of casting.
49+
int (*alias)(struct AltPtrWrapper) = (int (*)(struct AltPtrWrapper))fn;
50+
alias(alt);
51+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring

regression/cbmc/Linking7/member-name-mismatch.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
main.c
33
module2.c
44
^EXIT=10$

regression/cbmc/Linking7/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
main.c
33
module.c
44
^EXIT=10$

src/goto-programs/remove_function_pointers.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include "remove_function_pointers.h"
1313

14+
#include <util/arith_tools.h>
15+
#include <util/byte_operators.h>
1416
#include <util/c_types.h>
1517
#include <util/fresh_symbol.h>
1618
#include <util/invariant.h>
@@ -195,8 +197,10 @@ static void fix_argument_types(code_function_callt &function_call)
195197
{
196198
if(call_arguments[i].type() != function_parameters[i].type())
197199
{
198-
call_arguments[i] =
199-
typecast_exprt(call_arguments[i], function_parameters[i].type());
200+
call_arguments[i] = make_byte_extract(
201+
call_arguments[i],
202+
from_integer(0, c_index_type()),
203+
function_parameters[i].type());
200204
}
201205
}
202206
}
@@ -235,8 +239,10 @@ static void fix_return_type(
235239
exprt old_lhs=function_call.lhs();
236240
function_call.lhs()=tmp_symbol_expr;
237241

238-
dest.add(goto_programt::make_assignment(
239-
code_assignt(old_lhs, typecast_exprt(tmp_symbol_expr, old_lhs.type()))));
242+
dest.add(goto_programt::make_assignment(code_assignt(
243+
old_lhs,
244+
make_byte_extract(
245+
tmp_symbol_expr, from_integer(0, c_index_type()), old_lhs.type()))));
240246
}
241247

242248
void remove_function_pointerst::remove_function_pointer(

0 commit comments

Comments
 (0)