Yet another fix to the DWARF method "static-ness" detection heuristic
* include/abg-fwd.h (is_pointer, is_qualified_type): Declare new functions. * src/abg-ir.cc (is_pointer, is_qualified_type): Implement these new functions. * src/abg-dwarf-reader.cc (finish_member_function_reading): Sometimes, the this pointer of a non-static method can point to a *qualified* version of its containing type. I am seeing that when comparing libstdc++.so from RHEL 6.5 and RHEL 7. Take that in account when trying to detect that the first parameter of a member function is the this pointer, and thus detect that the function is a non static member function. * tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: New test input. * tests/data/test-read-dwarf/test8-qualified-this-pointer.so: New test input. * tests/data/test-read-dwarf/test8-qualified-this-pointer.cc: Source code of new test input. * tests/test-read-dwarf.cc: Update copyright year. (in_out_spec): Add the new test inputs to this array, so that this test harness runs on them. * tests/Makefile.am: Add the new test inputs to the source distribution. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
06db1895ff
commit
70cb9ba1ae
|
@ -194,6 +194,12 @@ is_class_type(const shared_ptr<type_base>);
|
|||
shared_ptr<class_decl>
|
||||
is_class_type(const shared_ptr<decl_base>);
|
||||
|
||||
shared_ptr<pointer_type_def>
|
||||
is_pointer(const shared_ptr<type_base>);
|
||||
|
||||
shared_ptr<qualified_type_def>
|
||||
is_qualified_type(const shared_ptr<type_base>);
|
||||
|
||||
shared_ptr<class_decl>
|
||||
look_through_decl_only_class(shared_ptr<class_decl>);
|
||||
|
||||
|
|
|
@ -4908,12 +4908,11 @@ finish_member_function_reading(Dwarf_Die* die,
|
|||
die_access_specifier(die, access);
|
||||
bool is_static = false;
|
||||
{
|
||||
// Let's see if the first parameter has the same class
|
||||
// type as the current class has a DW_AT_artificial
|
||||
// attribute flag set. We are not looking at
|
||||
// DW_AT_object_pointer (for DWARF 3) because it
|
||||
// wasn't being emitted in GCC 4_4, which was already
|
||||
// DWARF 3.
|
||||
// Let's see if the first parameter is a pointer to an instance of
|
||||
// the same class type as the current class and has a
|
||||
// DW_AT_artificial attribute flag set. We are not looking at
|
||||
// DW_AT_object_pointer (for DWARF 3) because it wasn't being
|
||||
// emitted in GCC 4_4, which was already DWARF 3.
|
||||
function_decl::parameter_sptr first_parm;
|
||||
if (!f->get_parameters().empty())
|
||||
first_parm = f->get_parameters()[0];
|
||||
|
@ -4921,13 +4920,20 @@ finish_member_function_reading(Dwarf_Die* die,
|
|||
bool is_artificial =
|
||||
first_parm && first_parm->get_artificial();;
|
||||
pointer_type_def_sptr this_ptr_type;
|
||||
type_base_sptr other_klass;
|
||||
|
||||
if (is_artificial)
|
||||
this_ptr_type =
|
||||
dynamic_pointer_cast<pointer_type_def>
|
||||
(first_parm->get_type());
|
||||
if (this_ptr_type && (get_pretty_representation
|
||||
(this_ptr_type->get_pointed_to_type())
|
||||
== klass->get_pretty_representation()))
|
||||
this_ptr_type = is_pointer(first_parm->get_type());
|
||||
if (this_ptr_type)
|
||||
other_klass = this_ptr_type->get_pointed_to_type();
|
||||
// Sometimes, other_klass can be qualified; e.g, volatile. In
|
||||
// that case, let's get the unqualified version of other_klass.
|
||||
if (qualified_type_def_sptr q = is_qualified_type(other_klass))
|
||||
other_klass = q->get_underlying_type();
|
||||
|
||||
if (other_klass
|
||||
&& (ir::get_type_declaration(other_klass)->get_qualified_name()
|
||||
== klass->get_qualified_name()))
|
||||
;
|
||||
else
|
||||
is_static = true;
|
||||
|
|
|
@ -3033,6 +3033,26 @@ class_decl_sptr
|
|||
is_class_type(const decl_base_sptr d)
|
||||
{return is_class_type(is_type(d));}
|
||||
|
||||
/// Test whether a type is a pointer_type_def.
|
||||
///
|
||||
/// @param t the type to test.
|
||||
///
|
||||
/// @return the @ref pointer_type_def_sptr if @p t is a
|
||||
/// pointer_type_def, null otherwise.
|
||||
pointer_type_def_sptr
|
||||
is_pointer(const type_base_sptr t)
|
||||
{return dynamic_pointer_cast<pointer_type_def>(t);}
|
||||
|
||||
/// Test whether a type is a qualified_type_def.
|
||||
///
|
||||
/// @param t the type to test.
|
||||
///
|
||||
/// @return the @ref qualified_type_def_sptr if @p t is a
|
||||
/// qualified_type_def, null otherwise.
|
||||
qualified_type_def_sptr
|
||||
is_qualified_type(const type_base_sptr t)
|
||||
{return dynamic_pointer_cast<qualified_type_def>(t);}
|
||||
|
||||
/// If a class is a decl-only class, get its definition. Otherwise,
|
||||
/// just return the initial class.
|
||||
///
|
||||
|
|
|
@ -232,12 +232,22 @@ tests/data/test-read-dwarf/test2.so \
|
|||
tests/data/test-read-dwarf/test2.so.abi \
|
||||
tests/data/test-read-dwarf/test3.c \
|
||||
tests/data/test-read-dwarf/test3.so \
|
||||
tests/data/test-read-dwarf/test3.so.abi \
|
||||
tests/data/test-read-dwarf/test4.c \
|
||||
tests/data/test-read-dwarf/test4.so \
|
||||
tests/data/test-read-dwarf/test4.so.abi \
|
||||
tests/data/test-read-dwarf/test5.cc \
|
||||
tests/data/test-read-dwarf/test5.so \
|
||||
tests/data/test-read-dwarf/test5.so.abi \
|
||||
tests/data/test-read-dwarf/test6.cc \
|
||||
tests/data/test-read-dwarf/test6.so \
|
||||
tests/data/test-read-dwarf/test6.so.abi \
|
||||
tests/data/test-read-dwarf/test7.cc \
|
||||
tests/data/test-read-dwarf/test7.so \
|
||||
tests/data/test-read-dwarf/test7.so.abi \
|
||||
tests/data/test-read-dwarf/test8-qualified-this-pointer.cc \
|
||||
tests/data/test-read-dwarf/test8-qualified-this-pointer.so \
|
||||
tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi \
|
||||
\
|
||||
data/test-diff-filter/test0-v0.cc \
|
||||
data/test-diff-filter/test0-v1.cc \
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
struct S
|
||||
{
|
||||
int i;
|
||||
|
||||
S()
|
||||
: i(0)
|
||||
{}
|
||||
|
||||
int
|
||||
foo() const;
|
||||
};
|
||||
|
||||
int
|
||||
S::foo() const
|
||||
{return i;}
|
Binary file not shown.
|
@ -0,0 +1,29 @@
|
|||
<abi-corpus path='data/test-read-dwarf/test8-qualified-this-pointer.so'>
|
||||
<elf-function-symbols>
|
||||
<elf-symbol name='_ZNK1S3fooEv' type='func-type' binding='global-binding' is-defined='yes'/>
|
||||
<elf-symbol name='_fini' type='func-type' binding='global-binding' is-defined='yes'/>
|
||||
<elf-symbol name='_init' type='func-type' binding='global-binding' is-defined='yes'/>
|
||||
</elf-function-symbols>
|
||||
<abi-instr version='1.0' address-size='64' path='test8-qualified-this-pointer.cc'>
|
||||
<class-decl name='S' size-in-bits='32' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='1' column='1' id='type-id-1'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='i' type-id='type-id-2' visibility='default' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='3' column='1'/>
|
||||
</data-member>
|
||||
<member-function access='public' constructor='yes'>
|
||||
<function-decl name='S' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='5' column='1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='64'>
|
||||
<parameter type-id='type-id-3' is-artificial='yes'/>
|
||||
</function-decl>
|
||||
</member-function>
|
||||
<member-function access='public'>
|
||||
<function-decl name='foo' mangled-name='_ZNK1S3fooEv' filepath='/home/dodji/git/libabigail/master/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc' line='10' column='1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='64' elf-symbol-id='_ZNK1S3fooEv'>
|
||||
<parameter type-id='type-id-4' is-artificial='yes'/>
|
||||
<return type-id='type-id-2'/>
|
||||
</function-decl>
|
||||
</member-function>
|
||||
</class-decl>
|
||||
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-2'/>
|
||||
<pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/>
|
||||
<qualified-type-def type-id='type-id-1' const='yes' id='type-id-5'/>
|
||||
<pointer-type-def type-id='type-id-5' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/>
|
||||
</abi-instr>
|
||||
</abi-corpus>
|
|
@ -1,6 +1,6 @@
|
|||
// -*- Mode: C++ -*-
|
||||
//
|
||||
// Copyright (C) 2013 Red Hat, Inc.
|
||||
// Copyright (C) 2013-2014 Red Hat, Inc.
|
||||
//
|
||||
// This file is part of the GNU Application Binary Interface Generic
|
||||
// Analysis and Instrumentation Library (libabigail). This library is
|
||||
|
@ -90,6 +90,11 @@ InOutSpec in_out_specs[] =
|
|||
"data/test-read-dwarf/test7.so.abi",
|
||||
"output/test-read-dwarf/test7.so.abi"
|
||||
},
|
||||
{
|
||||
"data/test-read-dwarf/test8-qualified-this-pointer.so",
|
||||
"data/test-read-dwarf/test8-qualified-this-pointer.so.abi",
|
||||
"output/test-read-dwarf/test8-qualified-this-pointer.so.abi"
|
||||
},
|
||||
// This should be the last entry.
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue