Delay canonicalization for array and qualified types

Array and qualified types can be edited after they are built, e.g, to
fold the qualifiers of the array as those should always apply to the
element types of the array, at least in C and C++.  So we need to
delay the canonicalization of these types until *after* all that type
editing is done.  We were not doing that properly and I suspect this
is the cause of some "heisenregressions" we are seeing on some
platforms intermittently.

This patch does delay the type canonicalization and insures that we
don't edit types that are canonicalized already.

	* src/abg-dwarf-reader.cc (maybe_canonicalize_type): Delay the
	canonicalization of array and qualified types, just like what we
	do for classes and function types already.
	(maybe_strip_qualification):  Do not
	re-canonicalize array and qualified types here because it should
	not be necessary anymore.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2019-04-18 11:26:44 +02:00
parent a074b48f33
commit 5d6af8d549

View File

@ -14403,8 +14403,12 @@ maybe_strip_qualification(const qualified_type_def_sptr t)
quals |= t->get_cv_quals();
element_type->set_cv_quals(quals);
result = is_decl(u);
if (u->get_canonical_type())
re_canonicalize(u);
if (u->get_canonical_type()
|| element_type->get_canonical_type())
// We shouldn't be editing types that were already
// canonicalized. For those, canonicalization should be
// delayed until after all editing is done.
ABG_ASSERT_NOT_REACHED;
}
else if (is_array_type(u) && !is_array_of_qualified_element(is_array_type(u)))
{
@ -14425,7 +14429,10 @@ maybe_strip_qualification(const qualified_type_def_sptr t)
array->set_element_type(qual_type);
result = is_decl(u);
if (u->get_canonical_type())
re_canonicalize(u);
// We shouldn't be editing types that were already
// canonicalized. For those, canonicalization should be
// delayed until after all editing is done.
ABG_ASSERT_NOT_REACHED;
}
return result;
@ -16054,17 +16061,22 @@ maybe_canonicalize_type(Dwarf_Die *die, read_context& ctxt)
if (!t)
return;
type_base_sptr peeled_type = peel_typedef_pointer_or_reference_type(t);
type_base_sptr peeled_type =
peel_typedef_pointer_or_reference_type(t, /*peel_qual_types=*/false);
if (is_class_type(peeled_type)
|| is_union_type(peeled_type)
|| is_function_type(peeled_type))
|| is_function_type(peeled_type)
|| is_array_type(peeled_type)
|| is_qualified_type(peeled_type))
// We delay canonicalization of classes/unions or typedef,
// pointers, references and array to classes/unions. This is
// because the (underlying) class might not be finished yet and we
// might not be able to able detect it here (thinking about
// classes that are work-in-progress, or classes that might be
// later amended by some DWARF construct). So we err on the safe
// side.
// side. We also delay canonicalization for array and qualified
// types because they can be edited (in particular by
// maybe_strip_qualification) after they are initially built.
ctxt.schedule_type_for_late_canonicalization(die);
else if ((is_function_type(t)
&& ctxt.is_wip_function_type_die_offset(die_offset, source))