diff --git a/regression/ansi-c/linking_conflicts2/test.desc b/regression/ansi-c/linking_conflicts2/test.desc index aa958cb6476..3d3eb99c6b5 100644 --- a/regression/ansi-c/linking_conflicts2/test.desc +++ b/regression/ansi-c/linking_conflicts2/test.desc @@ -3,6 +3,6 @@ main.c other.c ^EXIT=(64|1)$ ^SIGNAL=0$ -^\S+\.c(:\d+:\d+|\(\d+\)): error: conflicting function declarations 'foo'$ +^\S+\.c(:\d+:\d+|\(\d+\)): error: duplicate definition of function 'foo'$ -- ^warning: ignoring diff --git a/src/linking/linking.cpp b/src/linking/linking.cpp index a5c11955b1e..def12b6ca68 100644 --- a/src/linking/linking.cpp +++ b/src/linking/linking.cpp @@ -692,9 +692,18 @@ void linkingt::duplicate_code_symbol( n_it!=new_t.parameters().end(); ++o_it, ++n_it) { - if(o_it->type() != n_it->type()) + if(o_it->type() == n_it->type()) + continue; + + adjust_type_infot info(old_symbol, new_symbol); + bool failed = adjust_object_type_rec(o_it->type(), n_it->type(), info); + replace = info.set_to_new; + + if(failed) + { conflicts.push_back( std::make_pair(o_it->type(), n_it->type())); + } } if(o_it!=old_t.parameters().end()) { @@ -970,22 +979,20 @@ bool linkingt::adjust_object_type_rec( if(t1.id()==ID_pointer) { - #if 0 - bool s=info.set_to_new; - if(adjust_object_type_rec(t1.subtype(), t2.subtype(), info)) + if(info.old_symbol.type.id() == ID_code) + { + link_warning( + info.old_symbol, + info.new_symbol, + "pointer parameter types differ between declaration and definition"); + } + else { link_warning( info.old_symbol, info.new_symbol, "conflicting pointer types for variable"); - info.set_to_new=s; } - #else - link_warning( - info.old_symbol, - info.new_symbol, - "conflicting pointer types for variable"); - #endif if(info.old_symbol.is_extern && !info.new_symbol.is_extern) { @@ -1490,7 +1497,7 @@ void linkingt::copy_symbols( } // Move over all the non-colliding ones - std::unordered_set collisions; + std::unordered_set type_collisions, non_type_collisions; for(const auto &named_symbol : src_symbols) { @@ -1507,21 +1514,27 @@ void linkingt::copy_symbols( // new main_symbol_table.add(named_symbol.second); } + else if(named_symbol.second.is_type) + type_collisions.insert(named_symbol.first); else - collisions.insert(named_symbol.first); + non_type_collisions.insert(named_symbol.first); } } // Now do the collisions - for(const irep_idt &collision : collisions) + for(const irep_idt &collision : type_collisions) { symbolt &old_symbol = main_symbol_table.get_writeable_ref(collision); symbolt &new_symbol=src_symbols.at(collision); - if(new_symbol.is_type) - duplicate_type_symbol(old_symbol, new_symbol); - else - duplicate_non_type_symbol(old_symbol, new_symbol); + duplicate_type_symbol(old_symbol, new_symbol); + } + for(const irep_idt &collision : non_type_collisions) + { + symbolt &old_symbol = main_symbol_table.get_writeable_ref(collision); + symbolt &new_symbol = src_symbols.at(collision); + + duplicate_non_type_symbol(old_symbol, new_symbol); } // Apply type updates to initializers