Skip to content

Commit fe5c1a1

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 2d63a71 commit fe5c1a1

File tree

2 files changed

+32
-19
lines changed

2 files changed

+32
-19
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-
^\S+\.c(:\d+:\d+|\(\d+\)): error: conflicting function declarations 'foo'$
6+
^\S+\.c(:\d+:\d+|\(\d+\)): error: duplicate definition of function 'foo'$
77
--
88
^warning: ignoring

src/linking/linking.cpp

+31-18
Original file line numberDiff line numberDiff line change
@@ -692,9 +692,18 @@ void linkingt::duplicate_code_symbol(
692692
n_it!=new_t.parameters().end();
693693
++o_it, ++n_it)
694694
{
695-
if(o_it->type() != n_it->type())
695+
if(o_it->type() == n_it->type())
696+
continue;
697+
698+
adjust_type_infot info(old_symbol, new_symbol);
699+
bool failed = adjust_object_type_rec(o_it->type(), n_it->type(), info);
700+
replace = info.set_to_new;
701+
702+
if(failed)
703+
{
696704
conflicts.push_back(
697705
std::make_pair(o_it->type(), n_it->type()));
706+
}
698707
}
699708
if(o_it!=old_t.parameters().end())
700709
{
@@ -970,22 +979,20 @@ bool linkingt::adjust_object_type_rec(
970979

971980
if(t1.id()==ID_pointer)
972981
{
973-
#if 0
974-
bool s=info.set_to_new;
975-
if(adjust_object_type_rec(t1.subtype(), t2.subtype(), info))
982+
if(info.old_symbol.type.id() == ID_code)
983+
{
984+
link_warning(
985+
info.old_symbol,
986+
info.new_symbol,
987+
"pointer parameter types differ between declaration and definition");
988+
}
989+
else
976990
{
977991
link_warning(
978992
info.old_symbol,
979993
info.new_symbol,
980994
"conflicting pointer types for variable");
981-
info.set_to_new=s;
982995
}
983-
#else
984-
link_warning(
985-
info.old_symbol,
986-
info.new_symbol,
987-
"conflicting pointer types for variable");
988-
#endif
989996

990997
if(info.old_symbol.is_extern && !info.new_symbol.is_extern)
991998
{
@@ -1490,7 +1497,7 @@ void linkingt::copy_symbols(
14901497
}
14911498

14921499
// Move over all the non-colliding ones
1493-
std::unordered_set<irep_idt> collisions;
1500+
std::unordered_set<irep_idt> type_collisions, non_type_collisions;
14941501

14951502
for(const auto &named_symbol : src_symbols)
14961503
{
@@ -1507,21 +1514,27 @@ void linkingt::copy_symbols(
15071514
// new
15081515
main_symbol_table.add(named_symbol.second);
15091516
}
1517+
else if(named_symbol.second.is_type)
1518+
type_collisions.insert(named_symbol.first);
15101519
else
1511-
collisions.insert(named_symbol.first);
1520+
non_type_collisions.insert(named_symbol.first);
15121521
}
15131522
}
15141523

15151524
// Now do the collisions
1516-
for(const irep_idt &collision : collisions)
1525+
for(const irep_idt &collision : type_collisions)
15171526
{
15181527
symbolt &old_symbol = main_symbol_table.get_writeable_ref(collision);
15191528
symbolt &new_symbol=src_symbols.at(collision);
15201529

1521-
if(new_symbol.is_type)
1522-
duplicate_type_symbol(old_symbol, new_symbol);
1523-
else
1524-
duplicate_non_type_symbol(old_symbol, new_symbol);
1530+
duplicate_type_symbol(old_symbol, new_symbol);
1531+
}
1532+
for(const irep_idt &collision : non_type_collisions)
1533+
{
1534+
symbolt &old_symbol = main_symbol_table.get_writeable_ref(collision);
1535+
symbolt &new_symbol = src_symbols.at(collision);
1536+
1537+
duplicate_non_type_symbol(old_symbol, new_symbol);
15251538
}
15261539

15271540
// Apply type updates to initializers

0 commit comments

Comments
 (0)