Don't canonicalize types not added to their context in abixml reader

This is the first patch of a series which aims at fixing bug
libabigail/19097.

The problem in that report is a result of several underlying issues.
This patch series address them in isolation.  The patches do not
update the reference output of the regression test as they should,
because they are all needed to get to a sane working state.  The test
reference output are thus adjusted in the last patch of the series.
Here are the short titles of the patches of the set, including this
one:

    Don't canonicalize types not added to their context in abixml reader
    Support updating a class in the abixml reader
    Fix emitting of referenced type in abixml writer
    Use abidw --abidiff in test-read-dwarf.cc
    Adjust regression tests reference output for the current patch set

Below is the cover letter of the first patch of the set.

The abixml reader sometimes (wrongly) canonicalizes types that are not
(yet) added to their context.  This can lead to comparison issues
because some information carried by some types are dependant on their
context (e.g, access specifiers) and can be important for type
comparison.  Right now, access specifiers for member types are no more
taken into account when comparing member types because DWARF emitters
do not necessarily keep a correct track of those; but when they do, we
better be prepared.  And in any case, it's wrong to have type
canonicalization happen on half backed types anyway.

So this patch fixes several spots where type canonicalization happens
on types that are not added to their scope.

	* src/abg-reader.cc (read_context::maybe_canonicalize_type):
	Assert that a class type that is scheduled for canonicalization
	must be in a scope.  We do this only for classes, for now.  The
	assert here helped to spot (and fix)  a lot of places where we
	were canonicalizing types without scope.
	(read_context::build_or_get_type_decl):  Canonicalize types here,
	when they are built and (hopefully) added to their scope.  There
	might be cases here where we try to canonicalize types that are
	not added to their scope.  That should bomb in the assert above,
	at least for class types, for now.  We'll then fix the places where
	the types are created, to make them properly scoped.
	(build_type_decl, build_qualified_type_decl)
	(build_pointer_type_def, build_reference_type_def)
	(build_array_type_def, build_enum_type_decl, build_typedef_decl):
	Do not try to canonicalize the types early, right when they are
	created.  Canonicalization should happen at the point where (or
	after) they are added to their scope.
	(build_class_decl): Likewise.  Also, schedule member types for
	canonicalization once they've been added to their scope.
	(build_class_tdecl): Schedule the pattern of the class template
	for canonicalization once it has been added to its scope.  I am
	not sure I should do this, as the pattern is not yet a real type,
	but I am taking my bet.
	(build_type_composition): Schedule the composed type for
	canonicalization once it's been added to its scope.
	(handle_type_decl, handle_qualified_type_decl)
	(handle_pointer_type_def, handle_reference_type_def)
	(handle_function_type, handle_array_type_def)
	(handle_enum_type_decl, handle_typedef_decl, handle_class_decl):
	At this point, we should know if the type is to be added to a
	scope or not.  If it's in a scope, then schedule for
	canonicalization.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2015-10-17 12:48:11 +02:00
parent 09de4435ce
commit 065247c14c

View File

@ -791,7 +791,14 @@ public:
&& !is_enum_type(t))
canonicalize(t);
else
schedule_type_for_late_canonicalizing(t);
{
// We do not want to try to canonicalize a class type that
// hasn't been properly added to its context.
if (class_decl_sptr c = is_class_type(t))
assert(c->get_scope());
schedule_type_for_late_canonicalizing(t);
}
}
/// Schedule a type for being canonicalized after the current
@ -1061,6 +1068,8 @@ read_context::build_or_get_type_decl(const string& id,
if (add_decl_to_scope)
pop_scope_or_abort(scope);
maybe_canonicalize_type(t, !add_decl_to_scope);
}
return t;
}
@ -2578,7 +2587,6 @@ build_type_decl(read_context& ctxt,
if (ctxt.push_and_key_type_decl(decl, id, add_to_current_scope))
{
ctxt.map_xml_node_to_decl(node, decl);
canonicalize(decl);
return decl;
}
@ -2678,7 +2686,6 @@ build_qualified_type_decl(read_context& ctxt,
if (ctxt.push_and_key_type_decl(decl, id, add_to_current_scope))
{
ctxt.map_xml_node_to_decl(node, decl);
ctxt.maybe_canonicalize_type(decl, !add_to_current_scope);
return decl;
}
@ -2762,7 +2769,6 @@ build_pointer_type_def(read_context& ctxt,
if (ctxt.push_and_key_type_decl(t, id, add_to_current_scope))
{
ctxt.map_xml_node_to_decl(node, t);
ctxt.maybe_canonicalize_type(t, !add_to_current_scope);
return t;
}
@ -2852,7 +2858,6 @@ build_reference_type_def(read_context& ctxt,
if (ctxt.push_and_key_type_decl(t, id, add_to_current_scope))
{
ctxt.map_xml_node_to_decl(node, t);
ctxt.maybe_canonicalize_type(t, !add_to_current_scope);
return t;
}
@ -2918,8 +2923,6 @@ build_function_type(read_context& ctxt,
ctxt.get_translation_unit()->bind_function_type_life_time(fn_type);
ctxt.maybe_canonicalize_type(fn_type, /*force_delay=true*/true);
return fn_type;
}
@ -3089,7 +3092,6 @@ build_array_type_def(read_context& ctxt,
if (ctxt.push_and_key_type_decl(ar_type, id, add_to_current_scope))
{
ctxt.map_xml_node_to_decl(node, ar_type);
ctxt.maybe_canonicalize_type(ar_type, !add_to_current_scope);
return ar_type;
}
@ -3191,7 +3193,6 @@ build_enum_type_decl(read_context& ctxt,
if (ctxt.push_and_key_type_decl(t, id, add_to_current_scope))
{
ctxt.map_xml_node_to_decl(node, t);
ctxt.maybe_canonicalize_type(t, !add_to_current_scope);
return t;
}
@ -3265,7 +3266,6 @@ build_typedef_decl(read_context& ctxt,
if (ctxt.push_and_key_type_decl(t, id, add_to_current_scope))
{
ctxt.map_xml_node_to_decl(node, t);
ctxt.maybe_canonicalize_type(t, /*force_late_canonicalizing=*/true);
return t;
}
@ -3493,7 +3493,7 @@ build_class_decl(read_context& ctxt,
{
type_base_sptr m =
decl->add_member_type(t, access);
ctxt.maybe_canonicalize_type(m, !add_to_current_scope);
xml_char_sptr i= XML_NODE_GET_ATTRIBUTE(p, "id");
string id = CHAR_STR(i);
assert(!id.empty());
@ -3633,7 +3633,6 @@ build_class_decl(read_context& ctxt,
ctxt.pop_scope_or_abort(decl);
ctxt.unmark_type_as_wip(decl);
ctxt.maybe_canonicalize_type(decl, !add_to_current_scope);
return decl;
}
@ -3754,7 +3753,11 @@ build_class_tdecl(read_context& ctxt,
}
else if (shared_ptr<class_decl> c =
build_class_decl(ctxt, n, add_to_current_scope))
class_tmpl->set_pattern(c);
{
if (c->get_scope())
ctxt.maybe_canonicalize_type(c, /*force_delay=*/false);
class_tmpl->set_pattern(c);
}
}
ctxt.key_class_tmpl_decl(class_tmpl, id);
@ -3873,6 +3876,8 @@ build_type_composition(read_context& ctxt,
build_qualified_type_decl(ctxt, n,
/*add_to_current_scope=*/true)))
{
ctxt.maybe_canonicalize_type(composed_type,
/*force_delay=*/true);
result->set_composed_type(composed_type);
break;
}
@ -4074,6 +4079,8 @@ handle_type_decl(read_context& ctxt,
bool add_to_current_scope)
{
type_decl_sptr decl = build_type_decl(ctxt, node, add_to_current_scope);
if (decl && decl->get_scope())
ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
return decl;
}
@ -4105,6 +4112,8 @@ handle_qualified_type_decl(read_context& ctxt,
qualified_type_def_sptr decl =
build_qualified_type_decl(ctxt, node,
add_to_current_scope);
if (decl && decl->get_scope())
ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
return decl;
}
@ -4120,6 +4129,8 @@ handle_pointer_type_def(read_context& ctxt,
{
pointer_type_def_sptr decl = build_pointer_type_def(ctxt, node,
add_to_current_scope);
if (decl && decl->get_scope())
ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
return decl;
}
@ -4135,6 +4146,8 @@ handle_reference_type_def(read_context& ctxt,
{
reference_type_def_sptr decl = build_reference_type_def(ctxt, node,
add_to_current_scope);
if (decl && decl->get_scope())
ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
return decl;
}
@ -4150,6 +4163,7 @@ handle_function_type(read_context& ctxt,
{
function_type_sptr type = build_function_type(ctxt, node,
add_to_current_scope);
ctxt.maybe_canonicalize_type(type, /*force_delay=*/true);
return type;
}
@ -4165,6 +4179,7 @@ handle_array_type_def(read_context& ctxt,
{
array_type_def_sptr decl = build_array_type_def(ctxt, node,
add_to_current_scope);
ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
return decl;
}
@ -4178,6 +4193,8 @@ handle_enum_type_decl(read_context& ctxt,
{
enum_type_decl_sptr decl = build_enum_type_decl(ctxt, node,
add_to_current_scope);
if (decl && decl->get_scope())
ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
return decl;
}
@ -4191,6 +4208,8 @@ handle_typedef_decl(read_context& ctxt,
{
typedef_decl_sptr decl = build_typedef_decl(ctxt, node,
add_to_current_scope);
if (decl && decl->get_scope())
ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
return decl;
}
@ -4242,6 +4261,8 @@ handle_class_decl(read_context& ctxt,
{
class_decl_sptr decl = build_class_decl(ctxt, node,
add_to_current_scope);
if (decl && decl->get_scope())
ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
return decl;
}