Handle aliased function decls when comparing decls in general

When comparing two declarations, we look at their linkage name. When
the linkage names are different, then we infer that the two decls are
different.

But then, for *function* decls, it can happen that two different
linkage names are actually for different symbols that do alias; the
(ELF) symbols are different but they have the same address; so they
point to the same "thing".  The two functions are not different, then.

And we were not supporting this last case of diffent linkage names
that are aliases of each other.

This patch adds support for that.

	* include/abg-ir.h (is_function_decl): Add a const to the
	reference parameter, making it comply with the definition.
	* src/abg-ir.cc (equals): In the overload for decl_base, when the
	two linkage names are different, consider the case of the decls
	being aliased functions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2015-10-14 20:49:55 +02:00
parent 1a6b957401
commit f1c48fe80f
2 changed files with 39 additions and 4 deletions

View File

@ -2141,6 +2141,9 @@ public:
virtual ~function_decl();
}; // end class function_decl
bool
function_decls_alias(const function_decl& f1, const function_decl& f2);
bool
equals(const function_decl::parameter&,
const function_decl::parameter&,

View File

@ -2230,11 +2230,22 @@ equals(const decl_base& l, const decl_base& r, change_kind* k)
{
if (l.get_linkage_name() != r.get_linkage_name())
{
result = false;
if (k)
*k |= LOCAL_CHANGE_KIND;
// Linkage names are different. That usually means the two
// decls are different, unless we are looking at two
// function declarations which have two different symbols
// that are aliases of each other.
const function_decl *f1 = is_function_decl(&l),
*f2 = is_function_decl(&r);
if (f1 && f2 && function_decls_alias(*f1, *f2))
;// The two functions are aliases, so they are not different.
else
return false;
{
result = false;
if (k)
*k |= LOCAL_CHANGE_KIND;
else
return false;
}
}
}
@ -9462,6 +9473,27 @@ function_decl::get_id() const
return priv_->id_;
}
/// Test if two function declarations are aliases.
///
/// Two functions declarations are aliases if their symbols are
/// aliases, in the ELF sense.
///
/// @param f1 the first function to consider.
///
/// @param f2 the second function to consider.
///
/// @return true iff @p f1 is an alias of @p f2
bool
function_decls_alias(const function_decl& f1, const function_decl& f2)
{
elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
if (!s1 || !s2)
return false;
return elf_symbols_alias(s1, s2);
}
/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///