Skip to content

Commit 79cf301

Browse files
committed
Linking: fix up all types before handling functions or objects
Function parameters may require application of type fixes: our linking ensures that all types have a unique tag, and some parameter's types may require such tag updates. We used to do this for objects already, but need to apply it to parameters as well. Also, the order matters: all types need to be sorted out first before attempting objects or functions. Spotted while trying to compile a particular version of Xen 4.11.
1 parent 014188e commit 79cf301

File tree

3 files changed

+32
-22
lines changed

3 files changed

+32
-22
lines changed

regression/ansi-c/linking_conflicts2/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ main.c
33
other.c
44
^EXIT=(64|1)$
55
^SIGNAL=0$
6-
error: conflicting function declarations 'foo'
6+
error: duplicate definition of function 'foo'$
77
--
88
^warning: ignoring

regression/cbmc/incomplete-structs/test.desc

-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
CORE new-smt-backend
22
typesmain.c
33
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\)
74
warning: pointer parameter types differ between declaration and definition "bar"
85
warning: pointer parameter types differ between declaration and definition "foo"
96
^VERIFICATION SUCCESSFUL$

src/linking/linking.cpp

+31-18
Original file line numberDiff line numberDiff line change
@@ -678,9 +678,18 @@ void linkingt::duplicate_code_symbol(
678678
n_it!=new_t.parameters().end();
679679
++o_it, ++n_it)
680680
{
681-
if(o_it->type() != n_it->type())
681+
if(o_it->type() == n_it->type())
682+
continue;
683+
684+
adjust_type_infot info(old_symbol, new_symbol);
685+
bool failed = adjust_object_type_rec(o_it->type(), n_it->type(), info);
686+
replace = info.set_to_new;
687+
688+
if(failed)
689+
{
682690
conflicts.push_back(
683691
std::make_pair(o_it->type(), n_it->type()));
692+
}
684693
}
685694
if(o_it!=old_t.parameters().end())
686695
{
@@ -961,22 +970,20 @@ bool linkingt::adjust_object_type_rec(
961970

962971
if(t1.id()==ID_pointer)
963972
{
964-
#if 0
965-
bool s=info.set_to_new;
966-
if(adjust_object_type_rec(t1.subtype(), t2.subtype(), info))
973+
if(info.old_symbol.type.id() == ID_code)
974+
{
975+
link_warning(
976+
info.old_symbol,
977+
info.new_symbol,
978+
"pointer parameter types differ between declaration and definition");
979+
}
980+
else
967981
{
968982
link_warning(
969983
info.old_symbol,
970984
info.new_symbol,
971985
"conflicting pointer types for variable");
972-
info.set_to_new=s;
973986
}
974-
#else
975-
link_warning(
976-
info.old_symbol,
977-
info.new_symbol,
978-
"conflicting pointer types for variable");
979-
#endif
980987

981988
if(info.old_symbol.is_extern && !info.new_symbol.is_extern)
982989
{
@@ -1460,7 +1467,7 @@ void linkingt::copy_symbols(
14601467
}
14611468

14621469
// Move over all the non-colliding ones
1463-
std::unordered_set<irep_idt> collisions;
1470+
std::unordered_set<irep_idt> type_collisions, non_type_collisions;
14641471

14651472
for(const auto &named_symbol : src_symbols)
14661473
{
@@ -1477,21 +1484,27 @@ void linkingt::copy_symbols(
14771484
// new
14781485
main_symbol_table.add(named_symbol.second);
14791486
}
1487+
else if(named_symbol.second.is_type)
1488+
type_collisions.insert(named_symbol.first);
14801489
else
1481-
collisions.insert(named_symbol.first);
1490+
non_type_collisions.insert(named_symbol.first);
14821491
}
14831492
}
14841493

14851494
// Now do the collisions
1486-
for(const irep_idt &collision : collisions)
1495+
for(const irep_idt &collision : type_collisions)
14871496
{
14881497
symbolt &old_symbol = main_symbol_table.get_writeable_ref(collision);
14891498
symbolt &new_symbol=src_symbols.at(collision);
14901499

1491-
if(new_symbol.is_type)
1492-
duplicate_type_symbol(old_symbol, new_symbol);
1493-
else
1494-
duplicate_non_type_symbol(old_symbol, new_symbol);
1500+
duplicate_type_symbol(old_symbol, new_symbol);
1501+
}
1502+
for(const irep_idt &collision : non_type_collisions)
1503+
{
1504+
symbolt &old_symbol = main_symbol_table.get_writeable_ref(collision);
1505+
symbolt &new_symbol = src_symbols.at(collision);
1506+
1507+
duplicate_non_type_symbol(old_symbol, new_symbol);
14951508
}
14961509

14971510
// Apply type updates to initializers

0 commit comments

Comments
 (0)