Bug 26127 - abidw --annotate emits incomplete function types

When we get the qualified name of a pointer type, the result is cached
so that subsequent invocations of the getter yields a faster result.

When the pointed-to type is not yet fully constructed at the time of
the first invocation of the getter of the qualified name, what is
cached is the name of the pointer to a non-yet fully qualified type.

Then after the pointed-to type is fully constructed (and
canonicalized), the pointer type also becomes canonicalized (in that
order) and thus, the cache needs to be invalidated so that the
qualified name of the pointer to the fully qualified type is cached
again by a subsequent invocation of the getter.

The problem in this problem report is that the cache doesn't get
invalidated when the pointer type is canonicalized.

This patch fixes that.  A similar issue exists with reference and
qualified types so the patch addresses it for those types as well.

	* include/abg-ir.h (decl_base::clear_qualified_name): Declare new
	protected member function.
	({pointer_type_def, reference_type_def, qualified_type_def,
	function_type}::on_canonical_type_set): Declare virtual member
	functions.
	* src/abg-ir.cc (decl_base::clear_qualified_name): Define new
	protected member function.
	({pointer_type_def, reference_type_def, qualified_type_def,
	function_type}::on_canonical_type_set): Define virtual member
	functions.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2020-06-18 13:29:42 +02:00
parent 84fc161a0b
commit a5d02b95a6
5 changed files with 78 additions and 9 deletions

View File

@ -1391,6 +1391,9 @@ protected:
const interned_string&
peek_qualified_name() const;
void
clear_qualified_name();
void
set_qualified_name(const interned_string&) const;
@ -2024,6 +2027,7 @@ class qualified_type_def : public virtual type_base, public virtual decl_base
protected:
string build_name(bool, bool internal = false) const;
virtual void on_canonical_type_set();
public:
@ -2126,6 +2130,9 @@ class pointer_type_def : public virtual type_base, public virtual decl_base
// Forbidden.
pointer_type_def();
protected:
virtual void on_canonical_type_set();
public:
/// A hasher for instances of pointer_type_def
@ -2180,6 +2187,9 @@ class reference_type_def : public virtual type_base, public virtual decl_base
// Forbidden.
reference_type_def();
protected:
virtual void on_canonical_type_set();
public:
/// Hasher for intances of reference_type_def.
@ -3068,6 +3078,9 @@ class function_type : public virtual type_base
struct priv;
typedef shared_ptr<priv> priv_sptr;
protected:
virtual void on_canonical_type_set();
public:
/// Hasher for an instance of function_type
struct hash;

View File

@ -3535,6 +3535,15 @@ const interned_string&
decl_base::peek_qualified_name() const
{return priv_->qualified_name_;}
/// Clear the qualified name of this decl.
///
/// This is useful to ensure that the cache for the qualified name of
/// the decl is refreshed right after type canonicalization, for
/// instance.
void
decl_base::clear_qualified_name()
{priv_->qualified_name_.clear();}
/// Setter for the qualified name.
///
/// @param n the new qualified name.
@ -13105,6 +13114,17 @@ qualified_type_def::build_name(bool fully_qualified, bool internal) const
fully_qualified, internal);
}
/// This function is automatically invoked whenever an instance of
/// this type is canonicalized.
///
/// It's an overload of the virtual type_base::on_canonical_type_set.
///
/// We put here what is thus meant to be executed only at the point of
/// type canonicalization.
void
qualified_type_def::on_canonical_type_set()
{clear_qualified_name();}
/// Constructor of the qualified_type_def
///
/// @param type the underlying type
@ -13502,6 +13522,17 @@ struct pointer_type_def::priv
{}
}; //end struct pointer_type_def
/// This function is automatically invoked whenever an instance of
/// this type is canonicalized.
///
/// It's an overload of the virtual type_base::on_canonical_type_set.
///
/// We put here what is thus meant to be executed only at the point of
/// type canonicalization.
void
pointer_type_def::on_canonical_type_set()
{clear_qualified_name();}
pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
size_t size_in_bits,
size_t align_in_bits,
@ -13783,6 +13814,17 @@ operator!=(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
// <reference_type_def definitions>
/// This function is automatically invoked whenever an instance of
/// this type is canonicalized.
///
/// It's an overload of the virtual type_base::on_canonical_type_set.
///
/// We put here what is thus meant to be executed only at the point of
/// type canonicalization.
void
reference_type_def::on_canonical_type_set()
{clear_qualified_name();}
reference_type_def::reference_type_def(const type_base_sptr pointed_to,
bool lvalue,
size_t size_in_bits,
@ -16232,6 +16274,20 @@ struct function_type::priv
}
};// end struc function_type::priv
/// This function is automatically invoked whenever an instance of
/// this type is canonicalized.
///
/// It's an overload of the virtual type_base::on_canonical_type_set.
///
/// We put here what is thus meant to be executed only at the point of
/// type canonicalization.
void
function_type::on_canonical_type_set()
{
priv_->cached_name_.clear();
priv_->internal_cached_name_.clear();
}
/// The most straightforward constructor for the function_type class.
///
/// @param return_type the return type of the function type.

View File

@ -36663,7 +36663,7 @@
<var-decl name='normalization_preference' type-id='type-id-1939' visibility='default' filepath='/tmp/legendre/spack-stage/spack-stage-04g73E/harfbuzz-0.9.37/src/hb-ot-shape-complex-private.hh' line='114' column='1'/>
</data-member>
<data-member access='public' layout-offset-in-bits='448'>
<!-- bool ()* hb_ot_complex_shaper_t::decompose -->
<!-- bool (const hb_ot_shape_normalize_context_t*, typedef hb_codepoint_t, hb_codepoint_t*, hb_codepoint_t*)* hb_ot_complex_shaper_t::decompose -->
<var-decl name='decompose' type-id='type-id-1940' visibility='default' filepath='/tmp/legendre/spack-stage/spack-stage-04g73E/harfbuzz-0.9.37/src/hb-ot-shape-complex-private.hh' line='123' column='1'/>
</data-member>
<data-member access='public' layout-offset-in-bits='512'>
@ -36785,7 +36785,7 @@
<var-decl name='unicode' type-id='type-id-86' visibility='default' filepath='/tmp/legendre/spack-stage/spack-stage-04g73E/harfbuzz-0.9.37/src/hb-ot-shape-normalize-private.hh' line='57' column='1'/>
</data-member>
<data-member access='public' layout-offset-in-bits='256'>
<!-- bool ()* hb_ot_shape_normalize_context_t::decompose -->
<!-- bool (const hb_ot_shape_normalize_context_t*, typedef hb_codepoint_t, hb_codepoint_t*, hb_codepoint_t*)* hb_ot_shape_normalize_context_t::decompose -->
<var-decl name='decompose' type-id='type-id-1940' visibility='default' filepath='/tmp/legendre/spack-stage/spack-stage-04g73E/harfbuzz-0.9.37/src/hb-ot-shape-normalize-private.hh' line='61' column='1'/>
</data-member>
<data-member access='public' layout-offset-in-bits='320'>
@ -36802,7 +36802,7 @@
<enumerator name='HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE' value='3'/>
<enumerator name='HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT' value='1'/>
</enum-decl>
<!-- bool ()* -->
<!-- bool (const hb_ot_shape_normalize_context_t*, typedef hb_codepoint_t, hb_codepoint_t*, hb_codepoint_t*)* -->
<pointer-type-def type-id='type-id-1949' size-in-bits='64' id='type-id-1940'/>
<!-- bool (const hb_ot_shape_normalize_context_t*, typedef hb_codepoint_t, typedef hb_codepoint_t, hb_codepoint_t*)* -->
<pointer-type-def type-id='type-id-1950' size-in-bits='64' id='type-id-1941'/>

View File

@ -5095,11 +5095,11 @@
</function-decl>
</member-function>
<member-function access='public'>
<!-- std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::operator<<(void ()*) -->
<!-- std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (std::basic_ostream<char, std::char_traits<char> >&)*) -->
<function-decl name='operator&lt;&lt;' mangled-name='_ZNSolsEPFRSoS_E' filepath='/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ostream' line='108' column='1' visibility='default' binding='global' size-in-bits='64'>
<!-- implicit parameter of type 'std::basic_ostream<char, std::char_traits<char> >*' -->
<parameter type-id='type-id-215' is-artificial='yes'/>
<!-- parameter of type 'void ()*' -->
<!-- parameter of type 'std::basic_ostream<char, std::char_traits<char> >& (std::basic_ostream<char, std::char_traits<char> >&)*' -->
<parameter type-id='type-id-276'/>
<!-- std::basic_ostream<char, std::char_traits<char> >& -->
<return type-id='type-id-214'/>
@ -8298,7 +8298,7 @@
<qualified-type-def type-id='type-id-65' const='yes' id='type-id-307'/>
<!-- const vtkWeakPointer<vtkImageDataLIC2D>* -->
<pointer-type-def type-id='type-id-307' size-in-bits='64' id='type-id-300'/>
<!-- void ()* -->
<!-- std::basic_ostream<char, std::char_traits<char> >& (std::basic_ostream<char, std::char_traits<char> >&)* -->
<pointer-type-def type-id='type-id-308' size-in-bits='64' id='type-id-276'/>
<!-- vtkImageDataLIC2D& -->
<reference-type-def kind='lvalue' type-id='type-id-108' size-in-bits='64' id='type-id-301'/>

View File

@ -6555,7 +6555,7 @@
<pointer-type-def type-id='type-id-260' size-in-bits='64' id='type-id-339'/>
<!-- std::basic_ostream<char, std::char_traits<char> >& -->
<reference-type-def kind='lvalue' type-id='type-id-340' size-in-bits='64' id='type-id-341'/>
<!-- void ()* -->
<!-- std::basic_ostream<char, std::char_traits<char> >& (std::basic_ostream<char, std::char_traits<char> >&)* -->
<pointer-type-def type-id='type-id-342' size-in-bits='64' id='type-id-343'/>
<!-- std::basic_ostream<char, std::char_traits<char> >* -->
<pointer-type-def type-id='type-id-340' size-in-bits='64' id='type-id-344'/>
@ -7693,11 +7693,11 @@
<!-- struct std::basic_ostream<char, std::char_traits<char> > -->
<class-decl name='basic_ostream&lt;char, std::char_traits&lt;char&gt; &gt;' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-340'>
<member-function access='public'>
<!-- std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::operator<<(void ()*) -->
<!-- std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (std::basic_ostream<char, std::char_traits<char> >&)*) -->
<function-decl name='operator&lt;&lt;' mangled-name='_ZNSolsEPFRSoS_E' filepath='/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ostream' line='108' column='1' visibility='default' binding='global' size-in-bits='64'>
<!-- implicit parameter of type 'std::basic_ostream<char, std::char_traits<char> >*' -->
<parameter type-id='type-id-344' is-artificial='yes'/>
<!-- parameter of type 'void ()*' -->
<!-- parameter of type 'std::basic_ostream<char, std::char_traits<char> >& (std::basic_ostream<char, std::char_traits<char> >&)*' -->
<parameter type-id='type-id-343'/>
<!-- std::basic_ostream<char, std::char_traits<char> >& -->
<return type-id='type-id-341'/>