mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-13 03:57:33 +00:00
Prevent build_function_type from not canonicalizing certain types
I noticed that in some cases in build_function_type, when building the sub-types of the function type, the construction of a function type for the same DIE could be triggered. This happens frequently for aggregate types that happen to be recursive. In those cases, we must arrange for the construction of the function type for the same DIE to return the same type that is being currently built by build_function_type; otherwise, several types are going to be built for the same DIE, and only one of them is going to be canonicalized. build_function_type was just not prepared for this. This patch fixes that. Please note that the patch changes the test output /home/dodji/git/libabigail.git/merge/build/tests/output/test-read-dwarf/test12-pr18844.so.abi but it's a later patch that adjust that file because several patches are going to require an update to that file. We are going to update that patch in one go at the end of the patch series. * src/abg-dwarf-reader.cc (build_function_type): Associate the type being built with its DIE, before starting to build the sub-types. The current type is then amended with the sub-types that are built later. (build_ir_node_from_die): In the case for DW_TAG_subroutine_type, do not associate the type to the DIE here, as it's been done in build_function_type. * src/abg-ir.cc (function_type::set_parameters): Adjust the index of the parameters being set to the function: they start at 1, unless the first parameter is artificial, in which case its index starts at zero. This is just like what is done when the function type is constructed directly with the parameters passed as an argument to the constructor. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
21e159a66e
commit
501c514245
@ -7063,6 +7063,21 @@ build_function_type(read_context& ctxt,
|
||||
return result;
|
||||
}
|
||||
|
||||
// Let's create the type early and record it as being for the DIE
|
||||
// 'die'. This way, when building the sub-type triggers the
|
||||
// creation of a type matching the same 'die', then we'll reuse this
|
||||
// one.
|
||||
result.reset(is_method
|
||||
? new method_type(is_method,
|
||||
tu->get_address_size(),
|
||||
/*alignment=*/0)
|
||||
: new function_type(tu->get_address_size(),
|
||||
/*alignment=*/0));
|
||||
tu->bind_function_type_life_time(result);
|
||||
ctxt.associate_die_to_type(dwarf_dieoffset(die),
|
||||
die_is_from_alt_di,
|
||||
result);
|
||||
|
||||
decl_base_sptr return_type_decl;
|
||||
Dwarf_Die ret_type_die;
|
||||
bool ret_type_die_is_in_alternate_debug_info = false;
|
||||
@ -7075,6 +7090,7 @@ build_function_type(read_context& ctxt,
|
||||
where_offset));
|
||||
if (!return_type_decl)
|
||||
return_type_decl = build_ir_node_for_void_type(ctxt);
|
||||
result->set_return_type(is_type(return_type_decl));
|
||||
|
||||
Dwarf_Die child;
|
||||
function_decl::parameters function_parms;
|
||||
@ -7127,18 +7143,7 @@ build_function_type(read_context& ctxt,
|
||||
}
|
||||
while (dwarf_siblingof(&child, &child) == 0);
|
||||
|
||||
result.reset(is_method
|
||||
? new method_type(is_type(return_type_decl),
|
||||
is_method,
|
||||
function_parms,
|
||||
tu->get_address_size(),
|
||||
/*alignment=*/0)
|
||||
: new function_type(is_type(return_type_decl),
|
||||
function_parms,
|
||||
tu->get_address_size(),
|
||||
/*alignment=*/0));
|
||||
|
||||
tu->bind_function_type_life_time(result);
|
||||
result->set_parameters(function_parms);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -7872,9 +7877,6 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
if (f)
|
||||
{
|
||||
result = f;
|
||||
ctxt.associate_die_to_type(dwarf_dieoffset(die),
|
||||
die_is_from_alt_di,
|
||||
f);
|
||||
maybe_canonicalize_type(dwarf_dieoffset(die),
|
||||
die_is_from_alt_di,
|
||||
ctxt);
|
||||
|
@ -8232,7 +8232,22 @@ function_type::get_parm_at_index_from_first_non_implicit_parm(size_t i) const
|
||||
/// @param p the new vector of parameters to set.
|
||||
void
|
||||
function_type::set_parameters(const parameters &p)
|
||||
{priv_->parms_ = p;}
|
||||
{
|
||||
priv_->parms_ = p;
|
||||
for (parameters::size_type i = 0, j = 1;
|
||||
i < priv_->parms_.size();
|
||||
++i, ++j)
|
||||
{
|
||||
if (i == 0 && priv_->parms_[i]->get_artificial())
|
||||
// If the first parameter is artificial, then it certainly
|
||||
// means that this is a member function, and the first
|
||||
// parameter is the implicit this pointer. In that case, set
|
||||
// the index of that implicit parameter to zero. Otherwise,
|
||||
// the index of the first parameter starts at one.
|
||||
j = 0;
|
||||
priv_->parms_[i]->set_index(j);
|
||||
}
|
||||
}
|
||||
|
||||
/// Append a new parameter to the vector of parameters of the current
|
||||
/// instance of @ref function_type.
|
||||
|
Loading…
Reference in New Issue
Block a user