Bug 26127 - abidw --annotate emits incomplete function types

Message ID 86r1ucea64.fsf@seketeli.org
State Committed
Headers
Series Bug 26127 - abidw --annotate emits incomplete function types |

Commit Message

Dodji Seketeli June 18, 2020, 2:11 p.m. UTC
  Hello,

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>

Applied to master.

---
 include/abg-ir.h                                   | 13 +++++
 src/abg-ir.cc                                      | 56 ++++++++++++++++++++++
 tests/data/test-annotate/test17-pr19027.so.abi     |  6 +--
 .../test18-pr19037-libvtkRenderingLIC-6.1.so.abi   |  6 +--
 .../test20-pr19025-libvtkParallelCore-6.1.so.abi   |  6 +--
 5 files changed, 78 insertions(+), 9 deletions(-)
  

Patch

diff --git a/include/abg-ir.h b/include/abg-ir.h
index ebcc4b8..d81de21 100644
--- a/include/abg-ir.h
+++ b/include/abg-ir.h
@@ -1392,6 +1392,9 @@  protected:
   peek_qualified_name() const;
 
   void
+  clear_qualified_name();
+
+  void
   set_qualified_name(const interned_string&) const;
 
   const interned_string&
@@ -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;
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index 217d42d..da3716d 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -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.
diff --git a/tests/data/test-annotate/test17-pr19027.so.abi b/tests/data/test-annotate/test17-pr19027.so.abi
index 4937e36..42d5f81 100644
--- a/tests/data/test-annotate/test17-pr19027.so.abi
+++ b/tests/data/test-annotate/test17-pr19027.so.abi
@@ -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'/>
diff --git a/tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi b/tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi
index 0f42c9c..d5ab3e3 100644
--- a/tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi
+++ b/tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi
@@ -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'/>
diff --git a/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi b/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi
index 14178e8..dc009c8 100644
--- a/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi
+++ b/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi
@@ -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'/>