Skip to content

Commit 60b95b2

Browse files
authored
Merge pull request #6547 from tautschnig/pointer-parameter-type-conflict
Fix linking in case of function type conflict
2 parents dcb99a2 + 39e7078 commit 60b95b2

20 files changed

+423
-105
lines changed

regression/ansi-c/undeclared_function/fileB.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
#include <stdlib.h>
1+
void *malloc(__CPROVER_size_t s)
2+
{
3+
return (void *)0 + s;
4+
}
25

36
int f()
47
{

regression/ansi-c/undeclared_function/undeclared_function1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE gcc-only
22
fileA.c
33
fileB.c --validate-goto-model
44
^EXIT=0$
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
typesmain.c
3+
types1.c types2.c types3.c
4+
reason for conflict at \*#this.u: number of members is different \(3/0\)
5+
reason for conflict at \*#this.u: number of members is different \(0/3\)
6+
struct U \(incomplete\)
7+
warning: pointer parameter types differ between declaration and definition "bar"
8+
warning: pointer parameter types differ between declaration and definition "foo"
9+
^VERIFICATION SUCCESSFUL$
10+
^EXIT=0$
11+
^SIGNAL=0$
12+
--
13+
^warning: ignoring
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
struct S
2+
{
3+
int s;
4+
} s_object;
5+
6+
int foobar()
7+
{
8+
return s_object.s;
9+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
struct S
2+
{
3+
struct T *t;
4+
struct U *u;
5+
};
6+
7+
struct U
8+
{
9+
struct S *s;
10+
int j;
11+
};
12+
13+
int bar(struct S *s)
14+
{
15+
return s->u->j;
16+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
struct T
2+
{
3+
int i;
4+
};
5+
6+
struct S
7+
{
8+
struct T *t;
9+
struct U *u;
10+
};
11+
12+
int bar(struct S *);
13+
14+
int foo(struct S *s)
15+
{
16+
return bar(s) + s->t->i;
17+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <assert.h>
2+
3+
struct T
4+
{
5+
int i;
6+
};
7+
8+
struct U
9+
{
10+
struct S *s;
11+
int j;
12+
};
13+
14+
struct S
15+
{
16+
struct T *t;
17+
struct U *u;
18+
};
19+
20+
int foo(struct S *s);
21+
22+
int main()
23+
{
24+
struct T t = {10};
25+
struct U u = {0, 32};
26+
struct S s = {&t, &u};
27+
int res = foo(&s);
28+
assert(res == 42);
29+
}

regression/cbmc/return6/test.desc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
CORE
22
main.c
33
f_def.c
4-
^EXIT=6$
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
56
^SIGNAL=0$
6-
CONVERSION ERROR
77
--
88
^warning: ignoring
9-
^VERIFICATION SUCCESSFUL$

regression/linking-goto-binaries/chain.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ else
2121
$goto_cc "${main}.gb" "${next}.gb" -o "final.gb"
2222
fi
2323

24-
$cbmc "final.gb"
24+
$cbmc --validate-goto-model "final.gb"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
struct S
2+
{
3+
void *a;
4+
void *b;
5+
};
6+
7+
typedef void (*fptr)(struct S);
8+
9+
extern void foo(struct S s);
10+
11+
fptr A[] = {foo};
12+
13+
extern void bar();
14+
15+
int main()
16+
{
17+
bar();
18+
return 0;
19+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <assert.h>
2+
3+
struct S
4+
{
5+
void *a;
6+
void *b;
7+
};
8+
9+
typedef void (*fptr)(struct S);
10+
11+
extern fptr A[1];
12+
13+
struct real_S
14+
{
15+
int *a;
16+
int *b;
17+
};
18+
19+
void foo(struct real_S g)
20+
{
21+
assert(*g.a == 42);
22+
assert(*g.b == 41);
23+
}
24+
25+
void bar()
26+
{
27+
int x = 42;
28+
struct real_S s;
29+
s.a = &x;
30+
s.b = &x;
31+
A[0]((struct S){s.a, s.b});
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <assert.h>
2+
3+
struct S
4+
{
5+
void *a;
6+
void *b;
7+
};
8+
9+
typedef void (*fptr)(struct S);
10+
11+
extern fptr A[1];
12+
13+
struct real_S
14+
{
15+
int *a;
16+
int *c;
17+
};
18+
19+
void foo(struct real_S g)
20+
{
21+
assert(*g.a == 42);
22+
assert(*g.c == 41);
23+
}
24+
25+
void bar()
26+
{
27+
int x = 42;
28+
struct real_S s;
29+
s.a = &x;
30+
s.c = &x;
31+
A[0]((struct S){s.a, s.c});
32+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <assert.h>
2+
3+
struct S
4+
{
5+
int i;
6+
};
7+
8+
struct S *function();
9+
10+
int main()
11+
{
12+
assert(function() != 0);
13+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
struct S
2+
{
3+
int i;
4+
int j; // extra member
5+
} some_var;
6+
7+
struct S *function()
8+
{
9+
return &some_var;
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
Linking7-main.c
3+
Linking7-module2.c
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
line 21 assertion \*g\.a == 42: SUCCESS
8+
line 22 assertion \*g\.c == 41: FAILURE
9+
^\*\* 1 of 3 failed
10+
--
11+
^warning: ignoring
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
Linking7-return_type1.c
3+
Linking7-return_type2.c
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring
9+
--
10+
Note issue #3081
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
Linking7-main.c
3+
Linking7-module.c
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
^\*\* 1 of 3 failed
8+
line 21 assertion \*g\.a == 42: SUCCESS
9+
line 22 assertion \*g\.b == 41: FAILURE
10+
--
11+
^warning: ignoring

src/goto-programs/link_goto_model.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ void finalize_linking(
148148
goto_modelt &dest,
149149
const replace_symbolt::expr_mapt &type_updates)
150150
{
151-
unchecked_replace_symbolt object_type_updates;
151+
casting_replace_symbolt object_type_updates;
152152
object_type_updates.get_expr_map().insert(
153153
type_updates.begin(), type_updates.end());
154154

@@ -196,10 +196,30 @@ void finalize_linking(
196196
{
197197
for(auto &instruction : gf_entry.second.body.instructions)
198198
{
199-
instruction.transform([&object_type_updates](exprt expr) {
200-
object_type_updates(expr);
201-
return expr;
202-
});
199+
if(instruction.is_function_call())
200+
{
201+
const bool changed =
202+
!object_type_updates.replace(instruction.call_function());
203+
if(changed && instruction.call_lhs().is_not_nil())
204+
{
205+
object_type_updates(instruction.call_lhs());
206+
if(
207+
instruction.call_lhs().type() !=
208+
to_code_type(instruction.call_function().type()).return_type())
209+
{
210+
instruction.call_lhs() = typecast_exprt{
211+
instruction.call_lhs(),
212+
to_code_type(instruction.call_function().type()).return_type()};
213+
}
214+
}
215+
}
216+
else
217+
{
218+
instruction.transform([&object_type_updates](exprt expr) {
219+
const bool changed = !object_type_updates.replace(expr);
220+
return changed ? optionalt<exprt>{expr} : nullopt;
221+
});
222+
}
203223
}
204224
}
205225
}

0 commit comments

Comments
 (0)