Skip to content

Commit 833f4cd

Browse files
committed
Linking can safely clean up duplicates of static inline functions
This will avoid some occurrences of function$linkN names that are confusing to users, in particular when specifying loop unwinding limits.
1 parent b46ac4b commit 833f4cd

File tree

9 files changed

+92
-17
lines changed

9 files changed

+92
-17
lines changed

regression/ansi-c/linking1/foo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
static inline void foo(int x)
2+
{
3+
x = x + 1;
4+
}
5+
6+
void bar(int);

regression/ansi-c/linking1/main.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "foo.h"
2+
3+
int main(int argc, char *argv[])
4+
{
5+
foo(argc);
6+
bar(argc);
7+
return 0;
8+
}

regression/ansi-c/linking1/other.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef TEST2
2+
#include "foo.h"
3+
#else
4+
inline void foo(int x)
5+
{
6+
x = 0;
7+
}
8+
#endif
9+
10+
void bar(int y)
11+
{
12+
foo(y);
13+
y = 2;
14+
}

regression/ansi-c/linking1/test1.desc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
other.c --verbosity 10
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^Functions: 5; 5 have a body.$
7+
--
8+
^warning: ignoring
9+
^CONVERSION ERROR$

regression/ansi-c/linking1/test2.desc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
other.c --verbosity 10 -DTEST2
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^Functions: 6; 6 have a body.$
7+
--
8+
^warning: ignoring
9+
^CONVERSION ERROR$

regression/ansi-c/static2/main2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
static int foo(int a)
22
{
3-
return a+1;
3+
return a + 2;
44
}

regression/ansi-c/static3/main2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
static int foo(int a)
22
{
3-
return a+1;
3+
return a + 2;
44
}

src/goto-programs/link_goto_model.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,46 @@ static bool link_functions(
4646
goto_functionst &dest_functions,
4747
const symbol_tablet &src_symbol_table,
4848
goto_functionst &src_functions,
49-
const rename_symbolt &rename_symbol,
49+
rename_symbolt &rename_symbol,
5050
const std::unordered_set<irep_idt, irep_id_hash> &weak_symbols,
5151
const replace_symbolt &object_type_updates)
5252
{
5353
namespacet ns(dest_symbol_table);
5454
namespacet src_ns(src_symbol_table);
5555

56+
// remove any unnecessary duplicates
57+
std::unordered_set<irep_idt, irep_id_hash> duplicates;
58+
for(const auto &f_pair : src_functions.function_map)
59+
{
60+
rename_symbolt::expr_mapt::iterator rename_it =
61+
rename_symbol.expr_map.find(f_pair.first);
62+
if(rename_it == rename_symbol.expr_map.end())
63+
continue;
64+
65+
std::string new_name = id2string(rename_it->second);
66+
std::string::size_type suffix_pos = new_name.find("$link");
67+
if(suffix_pos == std::string::npos)
68+
continue;
69+
70+
irep_idt original_name = new_name.substr(0, suffix_pos);
71+
goto_functionst::function_mapt::iterator existing_func =
72+
dest_functions.function_map.find(original_name);
73+
if(existing_func == dest_functions.function_map.end())
74+
continue;
75+
76+
if(f_pair.second.body.equal(existing_func->second.body))
77+
{
78+
duplicates.insert(f_pair.first);
79+
rename_symbol.expr_map.erase(rename_it);
80+
}
81+
}
82+
5683
// merge functions
5784
Forall_goto_functions(src_it, src_functions)
5885
{
86+
if(duplicates.find(src_it->first) != duplicates.end())
87+
continue;
88+
5989
// the function might have been renamed
6090
rename_symbolt::expr_mapt::const_iterator e_it=
6191
rename_symbol.expr_map.find(src_it->first);

src/linking/linking.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -435,11 +435,10 @@ bool linkingt::needs_renaming_non_type(
435435
// We first take care of file-local non-type symbols.
436436
// These are static functions, or static variables
437437
// inside static function bodies.
438-
if(new_symbol.is_file_local ||
439-
old_symbol.is_file_local)
440-
return true;
441-
442-
return false;
438+
return (new_symbol.is_file_local || old_symbol.is_file_local) &&
439+
(new_symbol.type.id() != ID_code ||
440+
new_symbol.value == exprt("compiled") ||
441+
new_symbol.value != old_symbol.value);
443442
}
444443

445444
void linkingt::duplicate_code_symbol(
@@ -736,18 +735,18 @@ void linkingt::duplicate_code_symbol(
736735
old_symbol.location=new_symbol.location;
737736
old_symbol.is_macro=new_symbol.is_macro;
738737
}
739-
else if(to_code_type(old_symbol.type).get_inlined())
740-
{
741-
// ok, silently ignore
742-
}
743738
else if(base_type_eq(old_symbol.type, new_symbol.type, ns))
744739
{
745-
// keep the one in old_symbol -- libraries come last!
746-
warning().source_location=new_symbol.location;
740+
if(!new_symbol.is_file_local || !old_symbol.is_file_local)
741+
{
742+
// keep the one in old_symbol -- libraries come last!
743+
warning().source_location = new_symbol.location;
747744

748-
warning() << "function `" << old_symbol.name << "' in module `"
749-
<< new_symbol.module << "' is shadowed by a definition in module `"
750-
<< old_symbol.module << "'" << eom;
745+
warning() << "function `" << old_symbol.name << "' in module `"
746+
<< new_symbol.module
747+
<< "' is shadowed by a definition in module `"
748+
<< old_symbol.module << "'" << eom;
749+
}
751750
}
752751
else
753752
link_error(

0 commit comments

Comments
 (0)