Bug 19023 - Type canonicalization is sensitive to struct-ness

In some debug info of some shared library, the same type can be
present as a struct in some translation units, and as a class in
others.  As we are using the "pretty representation" of types to hash
types during type canonicalization, a "class foo" and "struct foo"
are (wrongly) considered different, because those pretty
representations are different.

This patch changes the canonicalization code to make it independent
from the struct-ness of the class being canonicalized.

	* include/abg-ir.h (class_decl::is_struct): Declare a setter for the
	"is-struct" property.
	* src/abg-ir.cc (class_decl::is_struct): And define that setter
	here.
	(type_base::get_canonical_type_for): Temporarily set the
	'is-struct' flag of the class type to 'false' before building its
	pretty representation.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so:
	New test input binary.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	New test reference output.
	* tests/data/Makefile.am: Add the new test material above to the
	source distribution.
	* tests/test-read-dwarf.cc (in_out_specs): Add the two new test
	inputs to the list of test inputs to consider.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2015-10-07 00:08:46 +02:00
parent ca6a5147c6
commit 0e3416e7e2
7 changed files with 86324 additions and 14389 deletions

View File

@ -2816,6 +2816,9 @@ public:
void
set_is_declaration_only(bool f);
void
is_struct(bool f);
bool
is_struct() const;

View File

@ -5854,21 +5854,40 @@ type_base::get_canonical_type_for(type_base_sptr t)
environment* env = t->get_environment();
assert(env);
class_decl_sptr is_class;
// Look through declaration-only classes
if (class_decl_sptr class_declaration = is_class_type(t))
if (class_declaration->get_is_declaration_only())
{
if (class_decl_sptr def =
class_declaration->get_definition_of_declaration())
t = def;
else
return type_base_sptr();
}
{
if (class_declaration->get_is_declaration_only())
{
if (class_decl_sptr def =
class_declaration->get_definition_of_declaration())
t = def;
else
return type_base_sptr();
}
is_class = is_class_type(t);
}
if (t->get_canonical_type())
return t->get_canonical_type();
bool is_struct = false;
if (is_class)
{
is_struct = is_class->is_struct();
// Make sure the struct-ness of the class doesn't influence the
// pretty representation that we are going to use for hashing
// purposes below.
is_class->is_struct(false);
}
string repr = ir::get_pretty_representation(t);
if (is_class)
// Set the struct-ness of the class back.
is_class->is_struct(is_struct);
environment::canonical_types_map_type& types =
env->get_canonical_types_map();
@ -10053,6 +10072,13 @@ void
class_decl::set_is_declaration_only(bool f)
{priv_->is_declaration_only_ = f;}
/// Set the "is-struct" flag of the class.
///
/// @param f the new value of the flag.
void
class_decl::is_struct(bool f)
{priv_->is_struct_ = f;}
/// Test if the class is a struct.
///
/// @return true iff the class is a struct.

View File

@ -296,6 +296,8 @@ test-read-dwarf/test17-pr19027.so \
test-read-dwarf/test17-pr19027.so.abi \
test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so \
test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi \
test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so \
test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi \
\
test-diff-filter/test0-v0.cc \
test-diff-filter/test0-v1.cc \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -146,6 +146,11 @@ InOutSpec in_out_specs[] =
"data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
"output/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
},
{
"data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so",
"data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
"output/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
},
// This should be the last entry.
{NULL, NULL, NULL}
};