mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-22 16:56:57 +00:00
dwarf-reader, ir: Add member fns to exported corpus fns after c14n
There are cases where a member function C::f has a defined & exported ELF symbol in a translation unit TU-2, whereas it has no associated symbol in another translation unit TU-1. The class C from TU-1 and the class C from TU-2 have the same canonical type because they are equivalent. Now, suppose it's C from TU-2 that is the canonical type; that means the canonical type of C from TU-1 is C from TU-2. Today, the only types that are emitted in an ABIXML file are canonical types. So if we want the C::f which has a publicly defined & exported elf symbol to be emitted in the ABIXML file, then the C::f that is defined & exported in the ABI corpus should be the C::f from the canonical class type C i.e, the C::f from TU-2. In other words, the exported C::f should be the member function of the canonical type class C. That means that determining which C::f to export in the ABI corpus should be done *after* type canonicalization. Today however, determining which C::f to export is done during the construction of the IR, in the DWARF reader. That leads to cases where the exported C::f is the one that has no defined & exported ELF symbol. As virtual member functions (in particular) are involved in class type comparison, that could lead to spurious type changes left and right. Oops. This patch implements the export of member functions after type canonicalization in the DWARF reader. Note that CTF and BTF readers are not impacted as they only support the C language which doesn't have member functions. * src/abg-dwarf-reader.cc (reader::fixup_functions_with_no_symbols): Do not export the virtual member function here. (build_ir_node_from_die): For DW_TAG_subprogram DIEs, likewise. * src/abg-ir.cc (maybe_adjust_canonical_type): Walk the member functions of the canonical type and export them in the ABI corpus if they have a defined and exported elf symbol. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
bdce453d8c
commit
202820ea7a
@ -4552,12 +4552,7 @@ public:
|
||||
ABG_ASSERT(is_member_function(i->second));
|
||||
ABG_ASSERT(get_member_function_is_virtual(i->second));
|
||||
i->second->set_symbol(sym);
|
||||
// The function_decl now has an associated (public) ELF symbol so
|
||||
// it ought to be advertised as being public.
|
||||
i->second->set_is_in_public_symbol_table(true);
|
||||
// Add the function to the set of exported decls of the
|
||||
// current corpus.
|
||||
maybe_add_fn_to_exported_decls(i->second.get());
|
||||
|
||||
if (do_log())
|
||||
cerr << "fixed up '"
|
||||
<< i->second->get_pretty_representation()
|
||||
@ -16016,7 +16011,13 @@ build_ir_node_from_die(reader& rdr,
|
||||
|
||||
if (fn)
|
||||
{
|
||||
rdr.maybe_add_fn_to_exported_decls(fn.get());
|
||||
if (!is_member_function(fn)
|
||||
|| !get_member_function_is_virtual(fn))
|
||||
// Virtual member functions are added to the set of
|
||||
// functions exported by the current ABI corpus *after*
|
||||
// the canonicalization of their parent type. So let's
|
||||
// not do it here.
|
||||
rdr.maybe_add_fn_to_exported_decls(fn.get());
|
||||
rdr.associate_die_to_decl(die, fn, where_offset,
|
||||
/*associate_by_repr=*/false);
|
||||
maybe_canonicalize_type(fn->get_type(), rdr);
|
||||
|
@ -15649,18 +15649,15 @@ static void
|
||||
maybe_adjust_canonical_type(const type_base_sptr& canonical,
|
||||
const type_base_sptr& type)
|
||||
{
|
||||
if (!canonical
|
||||
// If 'type' is *NOT* a newly canonicalized type ...
|
||||
|| type->get_naked_canonical_type()
|
||||
// ... or if 'type' is it's own canonical type, then get out.
|
||||
|| type.get() == canonical.get())
|
||||
if (type->get_naked_canonical_type())
|
||||
return;
|
||||
|
||||
class_decl_sptr canonical_class = is_class_type(canonical);
|
||||
|
||||
if (class_decl_sptr cl = is_class_type(type))
|
||||
{
|
||||
class_decl_sptr canonical_class = is_class_type(canonical);
|
||||
|
||||
if (canonical_class)
|
||||
if (canonical_class
|
||||
&& canonical_class.get() != cl.get())
|
||||
{
|
||||
// Set symbols of member functions that might be missing
|
||||
// theirs.
|
||||
@ -15695,6 +15692,37 @@ maybe_adjust_canonical_type(const type_base_sptr& canonical,
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the virtual member functions with exported symbols are
|
||||
// all added to the set of exported functions of the corpus.
|
||||
|
||||
// If we are looking at a non-canonicalized class (for instance, a
|
||||
// decl-only class that has virtual member functoins), let's pretend
|
||||
// it does have a canonical class so that we can perform the
|
||||
// necessary virtual member function adjustments
|
||||
if (class_decl_sptr cl = is_class_type(type))
|
||||
if (is_non_canonicalized_type(cl))
|
||||
{
|
||||
ABG_ASSERT(!canonical_class);
|
||||
canonical_class = cl;
|
||||
}
|
||||
|
||||
if (canonical_class)
|
||||
{
|
||||
if (auto abi_corpus = canonical_class->get_corpus())
|
||||
{
|
||||
for (auto& fn : canonical_class->get_member_functions())
|
||||
{
|
||||
if (elf_symbol_sptr sym = fn->get_symbol())
|
||||
if (sym->is_defined() && sym->is_public())
|
||||
{
|
||||
fn->set_is_in_public_symbol_table(true);
|
||||
auto b = abi_corpus->get_exported_decls_builder();
|
||||
b->maybe_add_fn_to_exported_fns(fn.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If an artificial function type equals a non-artfificial one in
|
||||
// the system, then the canonical type of both should be deemed
|
||||
// non-artificial. This is important because only non-artificial
|
||||
|
@ -4810,7 +4810,7 @@
|
||||
</function-decl>
|
||||
</member-function>
|
||||
<member-function access='public' destructor='yes' vtable-offset='0'>
|
||||
<function-decl name='~system_error' mangled-name='_ZN5boost6system12system_errorD2Ev' filepath='src/third_party/boost-1.56.0/boost/system/system_error.hpp' line='47' column='1' visibility='default' binding='global' size-in-bits='64'>
|
||||
<function-decl name='~system_error' mangled-name='_ZN5boost6system12system_errorD2Ev' filepath='src/third_party/boost-1.56.0/boost/system/system_error.hpp' line='47' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN5boost6system12system_errorD2Ev'>
|
||||
<parameter type-id='type-id-206' is-artificial='yes'/>
|
||||
<return type-id='type-id-118'/>
|
||||
</function-decl>
|
||||
|
Loading…
Reference in New Issue
Block a user