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:
Dodji Seketeli 2015-10-02 18:27:34 +02:00
parent 21e159a66e
commit 501c514245
2 changed files with 33 additions and 16 deletions

View File

@ -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);

View File

@ -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.