Skip to content

Commit cccdfd9

Browse files
authored
Merge pull request #4940 from xbauch/fix/function-pointer-init
Stop generating nondet pointees for function pointers
2 parents 8f89f59 + 6647399 commit cccdfd9

File tree

7 files changed

+102
-0
lines changed

7 files changed

+102
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <assert.h>
2+
3+
typedef int (*other_function_type)(int n);
4+
5+
void foo(other_function_type other_function)
6+
{
7+
// returning from the function call is unreachable -> the following assertion
8+
// should succeed
9+
// requesting `pointer-check` will then catch the fact that there is no valid
10+
// candidate function to call resulting in an invalid function pointer
11+
// failure
12+
assert(other_function(4) > 5);
13+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--function foo --pointer-check
4+
^\[foo.assertion.\d+\] line \d+ assertion other_function\(4\) > 5: SUCCESS$
5+
^\[foo.pointer_dereference.\d+\] line \d+ invalid function pointer: FAILURE$
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
^VERIFICATION FAILED
9+
--
10+
^warning: ignoring
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <assert.h>
2+
3+
int identity(int n)
4+
{
5+
return n;
6+
}
7+
8+
typedef int (*other_function_type)(int n);
9+
10+
void foo(other_function_type other_function)
11+
{
12+
// the following assertion is reachable and should fail (the only candidate is identity)
13+
assert(other_function(4) == 5);
14+
// the following assertion should succeed
15+
assert(other_function(4) == 4);
16+
}
17+
18+
int main()
19+
{
20+
foo(&identity);
21+
return 0;
22+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--function foo
4+
^\[foo.assertion.\d+\] line \d+ assertion other_function\(4\) == 5: FAILURE$
5+
^\[foo.assertion.\d+\] line \d+ assertion other_function\(4\) == 4: SUCCESS$
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
^VERIFICATION FAILED
9+
--
10+
^warning: ignoring
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <assert.h>
2+
3+
int identity(int n)
4+
{
5+
return n;
6+
}
7+
int increment(int n)
8+
{
9+
return n + 1;
10+
}
11+
12+
typedef int (*other_function_type)(int n);
13+
14+
void foo(other_function_type other_function)
15+
{
16+
// the following assertion is reachable and should fail (because of the identity case)
17+
assert(other_function(4) == 5);
18+
// the following assertion should succeed (satisfied by both candidates)
19+
assert(other_function(4) >= 4);
20+
}
21+
22+
int main()
23+
{
24+
foo(&identity);
25+
foo(&increment);
26+
return 0;
27+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--function foo
4+
^\[foo.assertion.\d+\] line \d+ assertion other_function\(4\) == 5: FAILURE$
5+
^\[foo.assertion.\d+\] line \d+ assertion other_function\(4\) >= 4: SUCCESS$
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
^VERIFICATION FAILED
9+
--
10+
^warning: ignoring

src/ansi-c/c_nondet_symbol_factory.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ void symbol_factoryt::gen_nondet_init(
5454
const pointer_typet &pointer_type=to_pointer_type(type);
5555
const typet &subtype = pointer_type.subtype();
5656

57+
if(subtype.id() == ID_code)
58+
{
59+
// Handle the pointer-to-code case separately:
60+
// leave as nondet_ptr to allow `remove_function_pointers`
61+
// to replace the pointer.
62+
assignments.add(
63+
code_assignt{expr, side_effect_expr_nondett{pointer_type, loc}});
64+
return;
65+
}
66+
5767
if(subtype.id() == ID_struct_tag)
5868
{
5969
const irep_idt struct_tag = to_struct_tag_type(subtype).get_identifier();

0 commit comments

Comments
 (0)