Skip to content

Commit 5bce1c3

Browse files
authored
Merge pull request #8167 from tautschnig/bugfixes/linking-rename-local
Linking: only rename file-local symbols
2 parents 19fc213 + 1dbf32f commit 5bce1c3

File tree

7 files changed

+144
-51
lines changed

7 files changed

+144
-51
lines changed

regression/cbmc/Linking9/f1.c

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
static void f()
2+
{
3+
}
4+
void g()
5+
{
6+
f();
7+
int x = 42;
8+
}

regression/cbmc/Linking9/f2.c

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
void f()
2+
{
3+
__CPROVER_assert(0, "unreachable");
4+
}

regression/cbmc/Linking9/f3.c

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extern void f();
2+
extern void g();
3+
4+
int main()
5+
{
6+
g();
7+
f();
8+
return 0;
9+
}

regression/cbmc/Linking9/test.desc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
f3.c
3+
f1.c f2.c
4+
^VERIFICATION FAILED$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring

src/goto-programs/link_goto_model.cpp

+25-11
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ Author: Michael Tautschnig, Daniel Kroening
2222

2323
static void rename_symbols_in_function(
2424
goto_functionst::goto_functiont &function,
25-
irep_idt &new_function_name,
2625
const rename_symbolt &rename_symbol)
2726
{
2827
for(auto &identifier : function.parameter_identifiers)
@@ -48,22 +47,39 @@ static bool link_functions(
4847
goto_functionst &dest_functions,
4948
const symbol_tablet &src_symbol_table,
5049
goto_functionst &src_functions,
51-
const rename_symbolt &rename_symbol,
50+
const rename_symbolt &rename_dest_symbol,
51+
const rename_symbolt &rename_src_symbol,
5252
const std::unordered_set<irep_idt> &weak_symbols)
5353
{
5454
namespacet ns(dest_symbol_table);
5555
namespacet src_ns(src_symbol_table);
5656

57+
// rename existing functions if linking requires us to do so
58+
for(const auto &rename_entry : rename_dest_symbol.expr_map)
59+
{
60+
auto fn_candidate = dest_functions.function_map.find(rename_entry.first);
61+
if(fn_candidate == dest_functions.function_map.end())
62+
continue;
63+
64+
dest_functions.function_map.insert(
65+
{rename_entry.second, std::move(fn_candidate->second)});
66+
dest_functions.function_map.erase(fn_candidate);
67+
}
68+
69+
// rename symbols in existing functions
70+
for(auto &dest_entry : dest_functions.function_map)
71+
rename_symbols_in_function(dest_entry.second, rename_dest_symbol);
72+
5773
// merge functions
5874
for(auto &gf_entry : src_functions.function_map)
5975
{
6076
// the function might have been renamed
6177
rename_symbolt::expr_mapt::const_iterator e_it =
62-
rename_symbol.expr_map.find(gf_entry.first);
78+
rename_src_symbol.expr_map.find(gf_entry.first);
6379

6480
irep_idt final_id = gf_entry.first;
6581

66-
if(e_it!=rename_symbol.expr_map.end())
82+
if(e_it != rename_src_symbol.expr_map.end())
6783
final_id=e_it->second;
6884

6985
// already there?
@@ -73,7 +89,7 @@ static bool link_functions(
7389
goto_functionst::goto_functiont &src_func = gf_entry.second;
7490
if(dest_f_it==dest_functions.function_map.end()) // not there yet
7591
{
76-
rename_symbols_in_function(src_func, final_id, rename_symbol);
92+
rename_symbols_in_function(src_func, rename_src_symbol);
7793
dest_functions.function_map.emplace(final_id, std::move(src_func));
7894
}
7995
else // collision!
@@ -84,7 +100,7 @@ static bool link_functions(
84100
weak_symbols.find(final_id)!=weak_symbols.end())
85101
{
86102
// the one with body wins!
87-
rename_symbols_in_function(src_func, final_id, rename_symbol);
103+
rename_symbols_in_function(src_func, rename_src_symbol);
88104

89105
in_dest_symbol_table.body.swap(src_func.body);
90106
in_dest_symbol_table.parameter_identifiers.swap(
@@ -133,7 +149,8 @@ std::optional<replace_symbolt::expr_mapt> link_goto_model(
133149
dest.goto_functions,
134150
src.symbol_table,
135151
src.goto_functions,
136-
linking.rename_symbol,
152+
linking.rename_main_symbol,
153+
linking.rename_new_symbol,
137154
weak_symbols))
138155
{
139156
messaget log{message_handler};
@@ -184,10 +201,7 @@ void finalize_linking(
184201
if(!macro_application.expr_map.empty())
185202
{
186203
for(auto &gf_entry : dest_functions.function_map)
187-
{
188-
irep_idt final_id = gf_entry.first;
189-
rename_symbols_in_function(gf_entry.second, final_id, macro_application);
190-
}
204+
rename_symbols_in_function(gf_entry.second, macro_application);
191205
}
192206

193207
if(!object_type_updates.empty())

src/linking/linking.cpp

+77-30
Original file line numberDiff line numberDiff line change
@@ -539,18 +539,19 @@ linkingt::rename(const symbol_table_baset &src_symbol_table, const irep_idt &id)
539539
}
540540
}
541541

542-
bool linkingt::needs_renaming_non_type(
542+
linkingt::renamingt linkingt::needs_renaming_non_type(
543543
const symbolt &old_symbol,
544544
const symbolt &new_symbol)
545545
{
546546
// We first take care of file-local non-type symbols.
547547
// These are static functions, or static variables
548548
// inside static function bodies.
549-
if(new_symbol.is_file_local ||
550-
old_symbol.is_file_local)
551-
return true;
552-
553-
return false;
549+
if(new_symbol.is_file_local)
550+
return renamingt::RENAME_NEW;
551+
else if(old_symbol.is_file_local)
552+
return renamingt::RENAME_OLD;
553+
else
554+
return renamingt::NO_RENAMING;
554555
}
555556

556557
void linkingt::duplicate_code_symbol(
@@ -839,8 +840,8 @@ void linkingt::duplicate_code_symbol(
839840
if(old_symbol.value.is_nil())
840841
{
841842
// the one with body wins!
842-
rename_symbol(new_symbol.value);
843-
rename_symbol(new_symbol.type);
843+
rename_new_symbol(new_symbol.value);
844+
rename_new_symbol(new_symbol.type);
844845
old_symbol.value=new_symbol.value;
845846
old_symbol.type=new_symbol.type; // for parameter identifiers
846847
old_symbol.is_weak=new_symbol.is_weak;
@@ -1312,45 +1313,53 @@ void linkingt::duplicate_type_symbol(
13121313
"unexpected difference between type symbols");
13131314
}
13141315

1315-
bool linkingt::needs_renaming_type(
1316+
linkingt::renamingt linkingt::needs_renaming_type(
13161317
const symbolt &old_symbol,
13171318
const symbolt &new_symbol)
13181319
{
13191320
PRECONDITION(new_symbol.is_type);
13201321

13211322
if(!old_symbol.is_type)
1322-
return true;
1323+
return renamingt::RENAME_NEW;
13231324

13241325
if(old_symbol.type==new_symbol.type)
1325-
return false;
1326+
return renamingt::NO_RENAMING;
13261327

13271328
if(
13281329
old_symbol.type.id() == ID_struct &&
13291330
to_struct_type(old_symbol.type).is_incomplete() &&
13301331
new_symbol.type.id() == ID_struct &&
13311332
!to_struct_type(new_symbol.type).is_incomplete())
1332-
return false; // not different
1333+
{
1334+
return renamingt::NO_RENAMING; // not different
1335+
}
13331336

13341337
if(
13351338
old_symbol.type.id() == ID_struct &&
13361339
!to_struct_type(old_symbol.type).is_incomplete() &&
13371340
new_symbol.type.id() == ID_struct &&
13381341
to_struct_type(new_symbol.type).is_incomplete())
1339-
return false; // not different
1342+
{
1343+
return renamingt::NO_RENAMING; // not different
1344+
}
13401345

13411346
if(
13421347
old_symbol.type.id() == ID_union &&
13431348
to_union_type(old_symbol.type).is_incomplete() &&
13441349
new_symbol.type.id() == ID_union &&
13451350
!to_union_type(new_symbol.type).is_incomplete())
1346-
return false; // not different
1351+
{
1352+
return renamingt::NO_RENAMING; // not different
1353+
}
13471354

13481355
if(
13491356
old_symbol.type.id() == ID_union &&
13501357
!to_union_type(old_symbol.type).is_incomplete() &&
13511358
new_symbol.type.id() == ID_union &&
13521359
to_union_type(new_symbol.type).is_incomplete())
1353-
return false; // not different
1360+
{
1361+
return renamingt::NO_RENAMING; // not different
1362+
}
13541363

13551364
if(
13561365
old_symbol.type.id() == ID_array && new_symbol.type.id() == ID_array &&
@@ -1359,14 +1368,18 @@ bool linkingt::needs_renaming_type(
13591368
{
13601369
if(to_array_type(old_symbol.type).size().is_nil() &&
13611370
to_array_type(new_symbol.type).size().is_not_nil())
1362-
return false; // not different
1371+
{
1372+
return renamingt::NO_RENAMING; // not different
1373+
}
13631374

13641375
if(to_array_type(new_symbol.type).size().is_nil() &&
13651376
to_array_type(old_symbol.type).size().is_not_nil())
1366-
return false; // not different
1377+
{
1378+
return renamingt::NO_RENAMING; // not different
1379+
}
13671380
}
13681381

1369-
return true; // different
1382+
return renamingt::RENAME_NEW; // different
13701383
}
13711384

13721385
static void do_type_dependencies(
@@ -1445,9 +1458,9 @@ std::unordered_map<irep_idt, irep_idt> linkingt::rename_symbols(
14451458
#endif
14461459

14471460
if(new_symbol.is_type)
1448-
rename_symbol.insert_type(id, new_identifier);
1461+
rename_new_symbol.insert_type(id, new_identifier);
14491462
else
1450-
rename_symbol.insert_expr(id, new_identifier);
1463+
rename_new_symbol.insert_expr(id, new_identifier);
14511464
}
14521465

14531466
return new_identifiers;
@@ -1463,8 +1476,8 @@ void linkingt::copy_symbols(
14631476
{
14641477
symbolt symbol=named_symbol.second;
14651478
// apply the renaming
1466-
rename_symbol(symbol.type);
1467-
rename_symbol(symbol.value);
1479+
rename_new_symbol(symbol.type);
1480+
rename_new_symbol(symbol.value);
14681481
auto it = new_identifiers.find(named_symbol.first);
14691482
if(it != new_identifiers.end())
14701483
symbol.name = it->second;
@@ -1537,16 +1550,50 @@ bool linkingt::link(const symbol_table_baset &src_symbol_table)
15371550
symbol_table_baset::symbolst::const_iterator m_it =
15381551
main_symbol_table.symbols.find(symbol_pair.first);
15391552

1540-
if(
1541-
m_it != main_symbol_table.symbols.end() && // duplicate
1542-
needs_renaming(m_it->second, symbol_pair.second))
1553+
if(m_it != main_symbol_table.symbols.end())
15431554
{
1544-
needs_to_be_renamed.insert(symbol_pair.first);
1545-
#ifdef DEBUG
1546-
messaget log{message_handler};
1547-
log.debug() << "LINKING: needs to be renamed: " << symbol_pair.first
1548-
<< messaget::eom;
1555+
// duplicate
1556+
switch(needs_renaming(m_it->second, symbol_pair.second))
1557+
{
1558+
case renamingt::NO_RENAMING:
1559+
break;
1560+
case renamingt::RENAME_OLD:
1561+
{
1562+
symbolt renamed_symbol = m_it->second;
1563+
renamed_symbol.name = rename(src_symbol_table, symbol_pair.first);
1564+
if(m_it->second.is_type)
1565+
rename_main_symbol.insert_type(m_it->first, renamed_symbol.name);
1566+
else
1567+
rename_main_symbol.insert_expr(m_it->first, renamed_symbol.name);
1568+
main_symbol_table.erase(m_it);
1569+
main_symbol_table.insert(std::move(renamed_symbol));
1570+
break;
1571+
}
1572+
case renamingt::RENAME_NEW:
1573+
{
1574+
needs_to_be_renamed.insert(symbol_pair.first);
1575+
#ifdef DEBUG
1576+
messaget log{message_handler};
1577+
log.debug() << "LINKING: needs to be renamed: " << symbol_pair.first
1578+
<< messaget::eom;
15491579
#endif
1580+
break;
1581+
}
1582+
}
1583+
}
1584+
}
1585+
1586+
// rename within main symbol table
1587+
for(auto &symbol_pair : main_symbol_table)
1588+
{
1589+
symbolt tmp = symbol_pair.second;
1590+
bool unmodified = rename_main_symbol(tmp.value);
1591+
unmodified &= rename_main_symbol(tmp.type);
1592+
if(!unmodified)
1593+
{
1594+
symbolt *sym_ptr = main_symbol_table.get_writeable(symbol_pair.first);
1595+
CHECK_RETURN(sym_ptr);
1596+
*sym_ptr = std::move(tmp);
15501597
}
15511598
}
15521599

src/linking/linking_class.h

+13-10
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,24 @@ class linkingt
4848
/// \return True, iff linking failed with unresolvable conflicts.
4949
bool link(const symbol_table_baset &src_symbol_table);
5050

51-
rename_symbolt rename_symbol;
51+
rename_symbolt rename_main_symbol, rename_new_symbol;
5252
casting_replace_symbolt object_type_updates;
5353

5454
protected:
55-
bool needs_renaming_type(
56-
const symbolt &old_symbol,
57-
const symbolt &new_symbol);
55+
enum renamingt
56+
{
57+
NO_RENAMING,
58+
RENAME_OLD,
59+
RENAME_NEW
60+
};
5861

59-
bool needs_renaming_non_type(
60-
const symbolt &old_symbol,
61-
const symbolt &new_symbol);
62+
renamingt
63+
needs_renaming_type(const symbolt &old_symbol, const symbolt &new_symbol);
6264

63-
bool needs_renaming(
64-
const symbolt &old_symbol,
65-
const symbolt &new_symbol)
65+
renamingt
66+
needs_renaming_non_type(const symbolt &old_symbol, const symbolt &new_symbol);
67+
68+
renamingt needs_renaming(const symbolt &old_symbol, const symbolt &new_symbol)
6669
{
6770
if(new_symbol.is_type)
6871
return needs_renaming_type(old_symbol, new_symbol);

0 commit comments

Comments
 (0)