Skip to content

Commit 8d3958a

Browse files
author
Daniel Kroening
committed
Merge pull request #49 from tautschnig/weak-symbols
Linking and type checking for weak symbols
2 parents f1044cf + 84e7611 commit 8d3958a

File tree

4 files changed

+58
-15
lines changed

4 files changed

+58
-15
lines changed

src/ansi-c/c_storage_spec.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ Function: c_storage_spect::read
2424

2525
void c_storage_spect::read(const typet &type)
2626
{
27-
if(type.id()==ID_merged_type)
27+
if(type.id()==ID_merged_type ||
28+
type.id()==ID_code)
2829
{
2930
forall_subtypes(it, type)
3031
read(*it);

src/ansi-c/c_typecheck_base.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -711,13 +711,6 @@ void c_typecheck_baset::typecheck_declaration(
711711
{
712712
// get storage spec
713713
c_storage_spect c_storage_spec(declaration.type());
714-
715-
declaration.set_is_inline(c_storage_spec.is_inline);
716-
declaration.set_is_static(c_storage_spec.is_static);
717-
declaration.set_is_extern(c_storage_spec.is_extern);
718-
declaration.set_is_thread_local(c_storage_spec.is_thread_local);
719-
declaration.set_is_register(c_storage_spec.is_register);
720-
declaration.set_is_typedef(c_storage_spec.is_typedef);
721714

722715
// first typecheck the type of the declaration
723716
typecheck_type(declaration.type());
@@ -743,6 +736,17 @@ void c_typecheck_baset::typecheck_declaration(
743736
d_it!=declaration.declarators().end();
744737
d_it++)
745738
{
739+
c_storage_spect full_spec(declaration.full_type(*d_it));
740+
full_spec|=c_storage_spec;
741+
742+
declaration.set_is_inline(full_spec.is_inline);
743+
declaration.set_is_static(full_spec.is_static);
744+
declaration.set_is_extern(full_spec.is_extern);
745+
declaration.set_is_thread_local(full_spec.is_thread_local);
746+
declaration.set_is_register(full_spec.is_register);
747+
declaration.set_is_typedef(full_spec.is_typedef);
748+
declaration.set_is_weak(full_spec.is_weak);
749+
746750
symbolt symbol;
747751
declaration.to_symbol(*d_it, symbol);
748752
irep_idt identifier=symbol.name;

src/goto-programs/read_goto_binary.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,13 @@ Function: link_functions
281281
static bool link_functions(
282282
symbol_tablet &dest_symbol_table,
283283
goto_functionst &dest_functions,
284-
symbol_tablet &src_symbol_table,
284+
const symbol_tablet &src_symbol_table,
285285
goto_functionst &src_functions,
286-
const rename_symbolt &rename_symbol)
286+
const rename_symbolt &rename_symbol,
287+
const hash_set_cont<irep_idt, irep_id_hash> &weak_symbols)
287288
{
288289
namespacet ns(dest_symbol_table);
290+
namespacet src_ns(src_symbol_table);
289291

290292
// merge functions
291293
Forall_goto_functions(src_it, src_functions)
@@ -320,15 +322,17 @@ static bool link_functions(
320322

321323
goto_functionst::goto_functiont &src_func=src_it->second;
322324

323-
if(in_dest_symbol_table.body.instructions.empty())
325+
if(in_dest_symbol_table.body.instructions.empty() ||
326+
weak_symbols.find(final_id)!=weak_symbols.end())
324327
{
325328
// the one with body wins!
326329
rename_symbols_in_function(src_func, rename_symbol);
327330

328331
in_dest_symbol_table.body.swap(src_func.body);
329332
in_dest_symbol_table.type=src_func.type;
330333
}
331-
else if(src_func.body.instructions.empty())
334+
else if(src_func.body.instructions.empty() ||
335+
src_ns.lookup(src_it->first).is_weak)
332336
{
333337
// just keep the old one in dest
334338
}
@@ -377,6 +381,12 @@ bool read_object_and_link(
377381
message_handler))
378382
return true;
379383

384+
typedef hash_set_cont<irep_idt, irep_id_hash> id_sett;
385+
id_sett weak_symbols;
386+
forall_symbols(it, symbol_table.symbols)
387+
if(it->second.is_weak)
388+
weak_symbols.insert(it->first);
389+
380390
linkingt linking(symbol_table,
381391
temp_model.symbol_table,
382392
message_handler);
@@ -386,7 +396,7 @@ bool read_object_and_link(
386396

387397
if(link_functions(symbol_table, functions,
388398
temp_model.symbol_table, temp_model.goto_functions,
389-
linking.rename_symbol))
399+
linking.rename_symbol, weak_symbols))
390400
return true;
391401

392402
return false;

src/linking/linking.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ void linkingt::duplicate_code_symbol(
576576

577577
old_symbol.type=new_symbol.type;
578578
old_symbol.location=new_symbol.location;
579+
old_symbol.is_weak=new_symbol.is_weak;
579580
}
580581
else if(!new_symbol.location.get_function().empty() &&
581582
new_symbol.value.is_nil())
@@ -595,6 +596,31 @@ void linkingt::duplicate_code_symbol(
595596
{
596597
old_symbol.type=new_symbol.type;
597598
old_symbol.location=new_symbol.location;
599+
old_symbol.is_weak=new_symbol.is_weak;
600+
}
601+
}
602+
// replace weak symbols
603+
else if(old_symbol.is_weak)
604+
{
605+
if(new_symbol.value.is_nil())
606+
link_warning(
607+
old_symbol,
608+
new_symbol,
609+
"function declaration conflicts with with weak definition");
610+
else
611+
old_symbol.value.make_nil();
612+
}
613+
else if(new_symbol.is_weak)
614+
{
615+
if(new_symbol.value.is_nil() ||
616+
old_symbol.value.is_not_nil())
617+
{
618+
new_symbol.value.make_nil();
619+
620+
link_warning(
621+
old_symbol,
622+
new_symbol,
623+
"ignoring conflicting weak function declaration");
598624
}
599625
}
600626
// Linux kernel uses void f(void) as generic prototype
@@ -782,6 +808,7 @@ void linkingt::duplicate_code_symbol(
782808
rename_symbol(new_symbol.type);
783809
old_symbol.value=new_symbol.value;
784810
old_symbol.type=new_symbol.type; // for parameter identifiers
811+
old_symbol.is_weak=new_symbol.is_weak;
785812
}
786813
else if(to_code_type(old_symbol.type).get_inlined())
787814
{
@@ -905,12 +932,13 @@ void linkingt::duplicate_object_symbol(
905932
!new_symbol.value.get_bool(ID_C_zero_initializer))
906933
{
907934
if(old_symbol.value.is_nil() ||
908-
old_symbol.value.get_bool(ID_C_zero_initializer))
935+
old_symbol.value.get_bool(ID_C_zero_initializer) ||
936+
old_symbol.is_weak)
909937
{
910938
// new_symbol wins
911939
old_symbol.value=new_symbol.value;
912940
}
913-
else
941+
else if(!new_symbol.is_weak)
914942
{
915943
// try simplifier
916944
exprt tmp_old=old_symbol.value,

0 commit comments

Comments
 (0)