[04/13] suppression: Support the has_size_change property for suppress_type

Message ID 87fsanq8ts.fsf_-_@redhat.com
State New
Headers
Series Support negative suppression specifications |

Commit Message

Dodji Seketeli March 2, 2023, 6:58 p.m. UTC
  Hello,

The "has_data_member_inserted_between" and
"has_data_members_inserted_between" properties of the [suppress_type]
directive allows the suppression of type changes when a data member is
inserted in a given range.  It turns out that suppressing type changes
that incur a change in the size of the type might not be what the user
wants by default, because the type size in itself might actually be an
incompatible ABI change that would then fly under the radar because of
this suppression specification.

An arguably better default behavior in this case would be to NOT
suppress the type change if the data member insertion does incur a
change in the size of the type.

But then, there would be cases where the user would really want to
suppress the type change due to data member insertion in a given range
even if it incurs a change in the type size.  This is where this patch
enters into play.

The patch introduces the "has_size_change" property of the
[suppress_type] directive.  In the presence of
"has_data_members_inserted_between" or
"has_data_member_inserted_between" properties, if the
"has_size_change" property is set to "yes", then the type change would
be suppressed if data members are inserted in the given range even if
the insertion incurs a type size change.

Otherwise, with this patch, in the absence of the "has_size_change"
property, the "has_data_member_inserted_between" and
"has_data_members_inserted_between" properties won't trigger the type
change suppression if the data member insertion incurs a type size
change.

	* doc/manuals/libabigail-concepts.rst: Document the new
	has_size_change property.
	* include/abg-suppression.h
	(type_suppression::{g,s}et_has_size_change): Declare new accessors.
	* src/abg-suppression-priv.h
	(type_suppression::priv::has_size_change_): Define new data
	member.
	(type_suppression::priv::priv): Initialize the new data member.
	* src/abg-suppression.cc
	(type_suppression::{g,s}et_has_size_change): Define new accessors.
	(type_suppression::suppresses_diff): Make the
	has_data_member_inserted_* clauses have effect only if the class
	size hasn't changed, unless the class has as the "has_size_change"
	property.  Also, allow members to be deleted in the right
	insertion range if the resulting size stays the same or if the
	has_size_change property is present.  This allows some custom
	behaviours where "padding" data members would be removed while
	some new data members would be added, resulting in a type which
	size would not change.
	(read_type_suppression): Support parsing the "has_size_change"
	property.
	* tests/data/test-diff-suppr/test11-add-data-member-0.1.suppr: New
	test suppression specification.
	* tests/data/test-diff-suppr/test11-add-data-member-1.1.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test11-add-data-member-2.1.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test11-add-data-member-3.1.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test11-add-data-member-4.1.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test11-add-data-member-report-1.1.txt:
	Likewise.
	* tests/data/test-diff-suppr/test12-add-data-member-0.1.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test12-add-data-member-report-1.1.txt:
	New test reference output.
	* tests/data/test-diff-suppr/test13-suppr-through-pointer-0.1.suppr:
	New test suppression specification.
	* tests/data/test-diff-suppr/test13-suppr-through-pointer-report-1.1.txt:
	New test reference output.
	* tests/data/test-diff-suppr/test35-leaf-report-0.1.txt: Likewise.
	* tests/data/test-diff-suppr/test35-leaf.1.suppr: New test
	suppression specification.
	* tests/data/Makefile.am: Add the new testing material to source
	distribution.
	* tests/data/test-diff-suppr/test11-add-data-member-1.suppr: Add
	the has_size_change property to explicitly allow suppressing type
	changes involving data member insertion even when the type size
	changes.
	* tests/data/test-diff-suppr/test11-add-data-member-0.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test11-add-data-member-2.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test11-add-data-member-3.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test11-add-data-member-4.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test12-add-data-member-0.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test13-suppr-through-pointer-0.suppr:
	Likewise.
	* tests/data/test-diff-suppr/test35-leaf.suppr: Likewise.
	* tests/test-diff-suppr.cc (in_out_specs): Add the new test input
	to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
 doc/manuals/libabigail-concepts.rst           | 50 +++++++++--
 include/abg-suppression.h                     |  6 ++
 src/abg-suppression-priv.h                    |  4 +-
 src/abg-suppression.cc                        | 51 +++++++++++-
 tests/data/Makefile.am                        | 12 +++
 .../test11-add-data-member-0.1.suppr          |  3 +
 .../test11-add-data-member-0.suppr            |  1 +
 .../test11-add-data-member-1.1.suppr          |  3 +
 .../test11-add-data-member-1.suppr            |  1 +
 .../test11-add-data-member-2.1.suppr          |  3 +
 .../test11-add-data-member-2.suppr            |  1 +
 .../test11-add-data-member-3.1.suppr          |  3 +
 .../test11-add-data-member-3.suppr            |  1 +
 .../test11-add-data-member-4.1.suppr          |  3 +
 .../test11-add-data-member-4.suppr            |  1 +
 .../test11-add-data-member-report-1.1.txt     | 13 +++
 .../test12-add-data-member-0.1.suppr          |  3 +
 .../test12-add-data-member-0.suppr            |  1 +
 .../test12-add-data-member-report-1.1.txt     | 13 +++
 .../test13-suppr-through-pointer-0.1.suppr    |  4 +
 .../test13-suppr-through-pointer-0.suppr      |  1 +
 ...est13-suppr-through-pointer-report-1.1.txt | 16 ++++
 .../test35-leaf-report-0.1.txt                | 18 ++++
 .../data/test-diff-suppr/test35-leaf.1.suppr  |  8 ++
 tests/data/test-diff-suppr/test35-leaf.suppr  |  1 +
 tests/test-diff-suppr.cc                      | 82 ++++++++++++++++++-
 26 files changed, 288 insertions(+), 15 deletions(-)
 create mode 100644 tests/data/test-diff-suppr/test11-add-data-member-0.1.suppr
 create mode 100644 tests/data/test-diff-suppr/test11-add-data-member-1.1.suppr
 create mode 100644 tests/data/test-diff-suppr/test11-add-data-member-2.1.suppr
 create mode 100644 tests/data/test-diff-suppr/test11-add-data-member-3.1.suppr
 create mode 100644 tests/data/test-diff-suppr/test11-add-data-member-4.1.suppr
 create mode 100644 tests/data/test-diff-suppr/test11-add-data-member-report-1.1.txt
 create mode 100644 tests/data/test-diff-suppr/test12-add-data-member-0.1.suppr
 create mode 100644 tests/data/test-diff-suppr/test12-add-data-member-report-1.1.txt
 create mode 100644 tests/data/test-diff-suppr/test13-suppr-through-pointer-0.1.suppr
 create mode 100644 tests/data/test-diff-suppr/test13-suppr-through-pointer-report-1.1.txt
 create mode 100644 tests/data/test-diff-suppr/test35-leaf-report-0.1.txt
 create mode 100644 tests/data/test-diff-suppr/test35-leaf.1.suppr
  

Patch

diff --git a/doc/manuals/libabigail-concepts.rst b/doc/manuals/libabigail-concepts.rst
index 2824b216..dc5a4a5c 100644
--- a/doc/manuals/libabigail-concepts.rst
+++ b/doc/manuals/libabigail-concepts.rst
@@ -481,9 +481,11 @@  names start with the string "private_data_member".
 
  Suppresses change reports involving a type which has at least one
  data member inserted at an offset specified by the property value
- ``offset-in-bit``.  Please note that if a type has a change in which
- at least one of its data members is removed or its size is reduced,
- the type will *NOT* be suppressed by the evaluation of this property.
+ ``offset-in-bit``.  Please note that if the size of the type changed,
+ then the type change will *NOT* be suppressed by the evaluation of
+ this property, unless the
+ :ref:`has_size_change<suppr_has_size_change_property_label>` property
+ is present and set to ``yes``.
 
  The value ``offset-in-bit`` is either:
 
@@ -525,9 +527,16 @@  names start with the string "private_data_member".
  the values ``range-begin`` and ``range-end`` can be of the same form
  as the :ref:`has_data_member_inserted_at
  <suppr_has_data_member_inserted_at_label>` property above.  Please
- also note that if a type has a change in which at least one of its
- data members is removed or its size is reduced, the type will *NOT* be
- suppressed by the evaluation of this property.
+ also note that if the size of the type changed, then the type change
+ will *NOT* be suppressed by the evaluation of this property, unless
+ the :ref:`has_size_change<suppr_has_size_change_property_label>`
+ property is present and set to ``yes``.  Note that data member
+ deletions happening in the range between ``range-begin`` and
+ ``range-end`` won't prevent the type change from being suppressed by
+ the evaluation of this property if the size of the type doesn't
+ change or if the
+ :ref:`has_size_change<suppr_has_size_change_property_label>` property
+ is present and set to ``yes``.
 
  Usage examples of this properties are: ::
 
@@ -564,9 +573,15 @@  names start with the string "private_data_member".
  the ranges are of the same kind as for the
  :ref:`has_data_member_inserted_at
  <suppr_has_data_member_inserted_at_label>` property above.  Please
- note that if a type has a change in which at least one of its data
- members is removed or its size is reduced, the type will *NOT* be
- suppressed by the evaluation of this property.
+ also note that if the size of the type changed, then the type will
+ *NOT* be suppressed by the evaluation of this property, unless the
+ :ref:`has_size_change<suppr_has_size_change_property_label>` property
+ is present and set to ``yes``.  Note that data member deletions
+ happening in the defined ranges won't prevent the type change from
+ being suppressed by the evaluation of this property if the size of
+ the type doesn't change or if the
+ :ref:`has_size_change<suppr_has_size_change_property_label>` property
+ is present and set to ``yes``.
 
  Another usage example of this property is thus: ::
 
@@ -576,6 +591,23 @@  names start with the string "private_data_member".
 	  {72, end}
      }
 
+
+ .. _suppr_has_size_change_property_label:
+* ``has_size_change``
+
+ Usage:
+
+   ``has_size_change`` ``=`` yes | no
+
+
+This property is to be used in conjunction with the properties
+:ref:`has_data_member_inserted_between<suppr_has_data_member_inserted_between_label>`
+and
+:ref:`has_data_members_inserted_between<suppr_has_data_members_inserted_between_label>`.
+Those properties will not match a type change if the size of the type
+changes, unless the ``has_size_changes`` property is set to ``yes``.
+
+
  .. _suppr_accessed_through_property_label:
 
 * ``accessed_through``
diff --git a/include/abg-suppression.h b/include/abg-suppression.h
index b13bb9fb..a51fdc5a 100644
--- a/include/abg-suppression.h
+++ b/include/abg-suppression.h
@@ -243,6 +243,12 @@  public:
   void
   set_reach_kind(reach_kind k);
 
+  bool
+  get_has_size_change() const;
+
+  void
+  set_has_size_change(bool flag);
+
   const string_set_type&
   get_potential_data_member_names() const;
 
diff --git a/src/abg-suppression-priv.h b/src/abg-suppression-priv.h
index 5fc1ec52..dcc5cc53 100644
--- a/src/abg-suppression-priv.h
+++ b/src/abg-suppression-priv.h
@@ -570,6 +570,7 @@  class type_suppression::priv
   type_suppression::type_kind		type_kind_;
   bool					consider_reach_kind_;
   type_suppression::reach_kind		reach_kind_;
+  bool					has_size_change_;
   // The data members a class needs to have to match this suppression
   // specification.  These might be selected by a regular expression.
   string_set_type			potential_data_members_;
@@ -599,7 +600,8 @@  public:
       consider_type_kind_(consider_type_kind),
       type_kind_(type_kind),
       consider_reach_kind_(consider_reach_kind),
-      reach_kind_(reach_kind)
+      reach_kind_(reach_kind),
+      has_size_change_(false)
   {}
 
   /// Get the regular expression object associated to the 'type_name_regex'
diff --git a/src/abg-suppression.cc b/src/abg-suppression.cc
index b596e0d5..54d2d917 100644
--- a/src/abg-suppression.cc
+++ b/src/abg-suppression.cc
@@ -569,6 +569,20 @@  void
 type_suppression::set_reach_kind(reach_kind k)
 {priv_->reach_kind_ = k;}
 
+/// Getter of the "has_size_change" property.
+///
+/// @return the value of the "has_size_change" property.
+bool
+type_suppression::get_has_size_change() const
+{return priv_->has_size_change_;}
+
+/// Setter of the "has_size_change" property.
+///
+/// @param flag the new value of the "has_size_change" property.
+void
+type_suppression::set_has_size_change(bool flag)
+{priv_->has_size_change_ = flag;}
+
 /// Getter of the "potential_data_member_names" property.
 ///
 /// @return the set of potential data member names of this
@@ -855,12 +869,14 @@  type_suppression::suppresses_diff(const diff* diff) const
 	{
 	  // ... and the suppr spec contains a
 	  // "has_data_member_inserted_*" clause ...
-	  if (klass_diff->deleted_data_members().empty()
-	      && (klass_diff->first_class_decl()->get_size_in_bits()
-		  <= klass_diff->second_class_decl()->get_size_in_bits()))
+	  if ((klass_diff->first_class_decl()->get_size_in_bits()
+	       == klass_diff->second_class_decl()->get_size_in_bits())
+	      || get_has_size_change())
 	    {
 	      // That "has_data_member_inserted_*" clause doesn't hold
-	      // if the class has deleted data members or shrunk.
+	      // if the class changed size, unless the user specified
+	      // that suppression applies to types that have size
+	      // change.
 
 	      const class_decl_sptr& first_type_decl =
 		klass_diff->first_class_decl();
@@ -881,6 +897,23 @@  type_suppression::suppresses_diff(const diff* diff) const
 		  if (!matched)
 		    return false;
 		}
+
+	      // Similarly, all deleted data members must be in an
+	      // allowed insertion range.
+	      for (const auto& m : klass_diff->deleted_data_members())
+		{
+		  decl_base_sptr member = m.second;
+		  bool matched = false;
+
+		  for (const auto& range : get_data_member_insertion_ranges())
+		    if (is_data_member_offset_in_range(is_var_decl(member),
+						       range,
+						       first_type_decl.get()))
+		      matched = true;
+
+		  if (!matched)
+		    return false;
+		}
 	    }
 	  else
 	    return false;
@@ -1649,6 +1682,13 @@  read_type_suppression(const ini::config::section& section)
     ? drop_artifact->get_value()->as_string()
     : "";
 
+  ini::simple_property_sptr has_size_change =
+    is_simple_property(section.find_property("has_size_change"));
+
+  string has_size_change_str = has_size_change
+    ? has_size_change->get_value()->as_string()
+    : "";
+
   ini::simple_property_sptr label =
     is_simple_property(section.find_property("label"));
   string label_str = label ? label->get_value()->as_string() : "";
@@ -2030,6 +2070,9 @@  read_type_suppression(const ini::config::section& section)
 	   || !srcloc_not_in.empty())))
     result->set_drops_artifact_from_ir(true);
 
+  if (has_size_change_str == "yes" || has_size_change_str == "true")
+    result->set_has_size_change(true);
+
   if (result->get_type_kind() == type_suppression::ENUM_TYPE_KIND
       && !changed_enumerator_names.empty())
     result->set_changed_enumerator_names(changed_enumerator_names);
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 57abf7a9..a37a364b 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -1294,28 +1294,38 @@  test-diff-suppr/test10-changed-parm-c-v1.c \
 test-diff-suppr/libtest11-add-data-member-v0.so \
 test-diff-suppr/libtest11-add-data-member-v1.so \
 test-diff-suppr/test11-add-data-member-0.suppr \
+test-diff-suppr/test11-add-data-member-0.1.suppr \
 test-diff-suppr/test11-add-data-member-1.suppr \
+test-diff-suppr/test11-add-data-member-1.1.suppr \
 test-diff-suppr/test11-add-data-member-2.suppr \
+test-diff-suppr/test11-add-data-member-2.1.suppr \
 test-diff-suppr/test11-add-data-member-3.suppr \
+test-diff-suppr/test11-add-data-member-3.1.suppr \
 test-diff-suppr/test11-add-data-member-4.suppr \
+test-diff-suppr/test11-add-data-member-4.1.suppr \
 test-diff-suppr/test11-add-data-member-report-0.txt \
 test-diff-suppr/test11-add-data-member-report-1.txt \
+test-diff-suppr/test11-add-data-member-report-1.1.txt \
 test-diff-suppr/test11-add-data-member-v0.cc \
 test-diff-suppr/test11-add-data-member-v1.cc \
 test-diff-suppr/libtest12-add-data-member-v0.so \
 test-diff-suppr/libtest12-add-data-member-v1.so \
 test-diff-suppr/test12-add-data-member-0.suppr \
+test-diff-suppr/test12-add-data-member-0.1.suppr \
 test-diff-suppr/test12-add-data-member-1.suppr \
 test-diff-suppr/test12-add-data-member-report-0.txt \
 test-diff-suppr/test12-add-data-member-report-1.txt \
+test-diff-suppr/test12-add-data-member-report-1.1.txt \
 test-diff-suppr/test12-add-data-member-report-2.txt \
 test-diff-suppr/test12-add-data-member-v0.cc \
 test-diff-suppr/test12-add-data-member-v1.cc \
 test-diff-suppr/libtest13-suppr-through-pointer-v0.so \
 test-diff-suppr/libtest13-suppr-through-pointer-v1.so \
 test-diff-suppr/test13-suppr-through-pointer-0.suppr \
+test-diff-suppr/test13-suppr-through-pointer-0.1.suppr \
 test-diff-suppr/test13-suppr-through-pointer-report-0.txt \
 test-diff-suppr/test13-suppr-through-pointer-report-1.txt \
+test-diff-suppr/test13-suppr-through-pointer-report-1.1.txt \
 test-diff-suppr/test13-suppr-through-pointer-v0.cc \
 test-diff-suppr/test13-suppr-through-pointer-v1.cc \
 test-diff-suppr/test14-suppr-non-redundant-v0.o \
@@ -1618,9 +1628,11 @@  test-diff-suppr/test34-v1.c \
 test-diff-suppr/libtest35-leaf-v0.so \
 test-diff-suppr/libtest35-leaf-v1.so \
 test-diff-suppr/test35-leaf-report-0.txt \
+test-diff-suppr/test35-leaf-report-0.1.txt \
 test-diff-suppr/test35-leaf-v0.cc \
 test-diff-suppr/test35-leaf-v1.cc \
 test-diff-suppr/test35-leaf.suppr \
+test-diff-suppr/test35-leaf.1.suppr \
 test-diff-suppr/libtest36-leaf-v0.so \
 test-diff-suppr/libtest36-leaf-v1.so \
 test-diff-suppr/test36-leaf-report-0.txt \
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-0.1.suppr b/tests/data/test-diff-suppr/test11-add-data-member-0.1.suppr
new file mode 100644
index 00000000..eb5d971d
--- /dev/null
+++ b/tests/data/test-diff-suppr/test11-add-data-member-0.1.suppr
@@ -0,0 +1,3 @@ 
+[suppress_type]
+	name = S
+	has_data_member_inserted_between = {8, end}
\ No newline at end of file
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-0.suppr b/tests/data/test-diff-suppr/test11-add-data-member-0.suppr
index 9dd993d0..bf997347 100644
--- a/tests/data/test-diff-suppr/test11-add-data-member-0.suppr
+++ b/tests/data/test-diff-suppr/test11-add-data-member-0.suppr
@@ -1,3 +1,4 @@ 
 [suppress_type]
 	name = S
 	has_data_member_inserted_between = {8, end}
+	has_size_change = true
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-1.1.suppr b/tests/data/test-diff-suppr/test11-add-data-member-1.1.suppr
new file mode 100644
index 00000000..966c3f3a
--- /dev/null
+++ b/tests/data/test-diff-suppr/test11-add-data-member-1.1.suppr
@@ -0,0 +1,3 @@ 
+[suppress_type]
+	name = S
+	has_data_member_inserted_between = {offset_after(m0), end}
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-1.suppr b/tests/data/test-diff-suppr/test11-add-data-member-1.suppr
index 966c3f3a..8ff1063d 100644
--- a/tests/data/test-diff-suppr/test11-add-data-member-1.suppr
+++ b/tests/data/test-diff-suppr/test11-add-data-member-1.suppr
@@ -1,3 +1,4 @@ 
 [suppress_type]
 	name = S
 	has_data_member_inserted_between = {offset_after(m0), end}
+	has_size_change = true
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-2.1.suppr b/tests/data/test-diff-suppr/test11-add-data-member-2.1.suppr
new file mode 100644
index 00000000..241d21da
--- /dev/null
+++ b/tests/data/test-diff-suppr/test11-add-data-member-2.1.suppr
@@ -0,0 +1,3 @@ 
+[suppress_type]
+	name = S
+	has_data_member_inserted_at = 8
\ No newline at end of file
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-2.suppr b/tests/data/test-diff-suppr/test11-add-data-member-2.suppr
index c8ea26ea..017fb88d 100644
--- a/tests/data/test-diff-suppr/test11-add-data-member-2.suppr
+++ b/tests/data/test-diff-suppr/test11-add-data-member-2.suppr
@@ -1,3 +1,4 @@ 
 [suppress_type]
 	name = S
 	has_data_member_inserted_at = 8
+	has_size_change = true
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-3.1.suppr b/tests/data/test-diff-suppr/test11-add-data-member-3.1.suppr
new file mode 100644
index 00000000..28b0e7cf
--- /dev/null
+++ b/tests/data/test-diff-suppr/test11-add-data-member-3.1.suppr
@@ -0,0 +1,3 @@ 
+[suppress_type]
+	name = S
+	has_data_member_inserted_at = end
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-3.suppr b/tests/data/test-diff-suppr/test11-add-data-member-3.suppr
index 28b0e7cf..66a5a7c1 100644
--- a/tests/data/test-diff-suppr/test11-add-data-member-3.suppr
+++ b/tests/data/test-diff-suppr/test11-add-data-member-3.suppr
@@ -1,3 +1,4 @@ 
 [suppress_type]
 	name = S
 	has_data_member_inserted_at = end
+	has_size_change = true
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-4.1.suppr b/tests/data/test-diff-suppr/test11-add-data-member-4.1.suppr
new file mode 100644
index 00000000..d824450d
--- /dev/null
+++ b/tests/data/test-diff-suppr/test11-add-data-member-4.1.suppr
@@ -0,0 +1,3 @@ 
+[suppress_type]
+	name = S
+	has_data_member_inserted_at = offset_after(m0)
\ No newline at end of file
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-4.suppr b/tests/data/test-diff-suppr/test11-add-data-member-4.suppr
index a99f6f49..82c53312 100644
--- a/tests/data/test-diff-suppr/test11-add-data-member-4.suppr
+++ b/tests/data/test-diff-suppr/test11-add-data-member-4.suppr
@@ -1,3 +1,4 @@ 
 [suppress_type]
 	name = S
 	has_data_member_inserted_at = offset_after(m0)
+	has_size_change = true
diff --git a/tests/data/test-diff-suppr/test11-add-data-member-report-1.1.txt b/tests/data/test-diff-suppr/test11-add-data-member-report-1.1.txt
new file mode 100644
index 00000000..8e5cd6a4
--- /dev/null
+++ b/tests/data/test-diff-suppr/test11-add-data-member-report-1.1.txt
@@ -0,0 +1,13 @@ 
+Functions changes summary: 0 Removed, 1 Changed, 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+1 function with some indirect sub-type change:
+
+  [C] 'function int foo(S*)' has some indirect sub-type changes:
+    parameter 1 of type 'S*' has sub-type changes:
+      in pointed to type 'struct S':
+        type size changed from 8 to 64 (in bits)
+        2 data member insertions:
+          'char m1', at offset 8 (in bits)
+          'int m2', at offset 32 (in bits)
+
diff --git a/tests/data/test-diff-suppr/test12-add-data-member-0.1.suppr b/tests/data/test-diff-suppr/test12-add-data-member-0.1.suppr
new file mode 100644
index 00000000..795bf09d
--- /dev/null
+++ b/tests/data/test-diff-suppr/test12-add-data-member-0.1.suppr
@@ -0,0 +1,3 @@ 
+[suppress_type]
+	name = S
+	has_data_members_inserted_between = {{8, 31}, {64, end}}
\ No newline at end of file
diff --git a/tests/data/test-diff-suppr/test12-add-data-member-0.suppr b/tests/data/test-diff-suppr/test12-add-data-member-0.suppr
index b45d5d49..fb558caf 100644
--- a/tests/data/test-diff-suppr/test12-add-data-member-0.suppr
+++ b/tests/data/test-diff-suppr/test12-add-data-member-0.suppr
@@ -1,3 +1,4 @@ 
 [suppress_type]
 	name = S
 	has_data_members_inserted_between = {{8, 31}, {64, end}}
+	has_size_change = true;
diff --git a/tests/data/test-diff-suppr/test12-add-data-member-report-1.1.txt b/tests/data/test-diff-suppr/test12-add-data-member-report-1.1.txt
new file mode 100644
index 00000000..d7456d7e
--- /dev/null
+++ b/tests/data/test-diff-suppr/test12-add-data-member-report-1.1.txt
@@ -0,0 +1,13 @@ 
+Functions changes summary: 0 Removed, 1 Changed, 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+1 function with some indirect sub-type change:
+
+  [C] 'function int foo(S*)' has some indirect sub-type changes:
+    parameter 1 of type 'S*' has sub-type changes:
+      in pointed to type 'struct S':
+        type size changed from 64 to 96 (in bits)
+        2 data member insertions:
+          'char m_inserted1', at offset 8 (in bits)
+          'char m_inserted2', at offset 64 (in bits)
+
diff --git a/tests/data/test-diff-suppr/test13-suppr-through-pointer-0.1.suppr b/tests/data/test-diff-suppr/test13-suppr-through-pointer-0.1.suppr
new file mode 100644
index 00000000..b8f5ae9b
--- /dev/null
+++ b/tests/data/test-diff-suppr/test13-suppr-through-pointer-0.1.suppr
@@ -0,0 +1,4 @@ 
+[suppress_type]
+  name = S
+  accessed_through = pointer
+  has_data_member_inserted_at = end
\ No newline at end of file
diff --git a/tests/data/test-diff-suppr/test13-suppr-through-pointer-0.suppr b/tests/data/test-diff-suppr/test13-suppr-through-pointer-0.suppr
index f88c46df..aadaaf77 100644
--- a/tests/data/test-diff-suppr/test13-suppr-through-pointer-0.suppr
+++ b/tests/data/test-diff-suppr/test13-suppr-through-pointer-0.suppr
@@ -2,3 +2,4 @@ 
   name = S
   accessed_through = pointer
   has_data_member_inserted_at = end
+  has_size_change = true
diff --git a/tests/data/test-diff-suppr/test13-suppr-through-pointer-report-1.1.txt b/tests/data/test-diff-suppr/test13-suppr-through-pointer-report-1.1.txt
new file mode 100644
index 00000000..f408f2dd
--- /dev/null
+++ b/tests/data/test-diff-suppr/test13-suppr-through-pointer-report-1.1.txt
@@ -0,0 +1,16 @@ 
+Functions changes summary: 0 Removed, 2 Changed (1 filtered out), 0 Added functions
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+2 functions with some indirect sub-type change:
+
+  [C] 'function void bar(S*)' has some indirect sub-type changes:
+    parameter 1 of type 'S*' has sub-type changes:
+      in pointed to type 'struct S':
+        type size changed from 32 to 64 (in bits)
+        1 data member insertion:
+          'char m1', at offset 32 (in bits)
+
+  [C] 'function void foo(S)' has some indirect sub-type changes:
+    parameter 1 of type 'struct S' has sub-type changes:
+      details were reported earlier
+
diff --git a/tests/data/test-diff-suppr/test35-leaf-report-0.1.txt b/tests/data/test-diff-suppr/test35-leaf-report-0.1.txt
new file mode 100644
index 00000000..17361c52
--- /dev/null
+++ b/tests/data/test-diff-suppr/test35-leaf-report-0.1.txt
@@ -0,0 +1,18 @@ 
+Leaf changes summary: 2 artifacts changed
+Changed leaf types summary: 2 leaf types changed
+Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 0 Added function
+Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable
+
+'struct leaf at test35-leaf-v0.cc:5:1' changed:
+  type size changed from 32 to 64 (in bits)
+  1 data member insertion:
+    'char m1', at offset 32 (in bits) at test35-leaf-v1.cc:8:1
+  one impacted interface:
+    function void fn(C&)
+
+'struct leaf_to_filter at test35-leaf-v0.cc:10:1' changed:
+  type size changed from 32 to 64 (in bits)
+  1 data member insertion:
+    'int added', at offset 32 (in bits) at test35-leaf-v1.cc:14:1
+  one impacted interface:
+    function void fn(C&)
diff --git a/tests/data/test-diff-suppr/test35-leaf.1.suppr b/tests/data/test-diff-suppr/test35-leaf.1.suppr
new file mode 100644
index 00000000..b49293ec
--- /dev/null
+++ b/tests/data/test-diff-suppr/test35-leaf.1.suppr
@@ -0,0 +1,8 @@ 
+[suppress_type]
+
+  # Suppress the type that had a data member inserted after the data
+  # member named 'member0'.  That would be the type named
+  # leaf_to_filter.
+
+  name_regexp = .*
+  has_data_member_inserted_between = {offset_after(member0), end}
diff --git a/tests/data/test-diff-suppr/test35-leaf.suppr b/tests/data/test-diff-suppr/test35-leaf.suppr
index b49293ec..830529bf 100644
--- a/tests/data/test-diff-suppr/test35-leaf.suppr
+++ b/tests/data/test-diff-suppr/test35-leaf.suppr
@@ -6,3 +6,4 @@ 
 
   name_regexp = .*
   has_data_member_inserted_between = {offset_after(member0), end}
+  has_size_change = true
diff --git a/tests/test-diff-suppr.cc b/tests/test-diff-suppr.cc
index 645afe53..a463b341 100644
--- a/tests/test-diff-suppr.cc
+++ b/tests/test-diff-suppr.cc
@@ -514,7 +514,17 @@  InOutSpec in_out_specs[] =
     "data/test-diff-suppr/test11-add-data-member-0.suppr",
     "--no-default-suppression --no-show-locs --no-redundant",
     "data/test-diff-suppr/test11-add-data-member-report-1.txt",
-    "output/test-diff-suppr/test11-add-data-member-report-1_0.txt"
+    "output/test-diff-suppr/test11-add-data-member-report-0_0.txt"
+  },
+    {
+    "data/test-diff-suppr/libtest11-add-data-member-v0.so",
+    "data/test-diff-suppr/libtest11-add-data-member-v1.so",
+    "",
+    "",
+    "data/test-diff-suppr/test11-add-data-member-0.1.suppr",
+    "--no-default-suppression --no-show-locs --no-redundant",
+    "data/test-diff-suppr/test11-add-data-member-report-1.1.txt",
+    "output/test-diff-suppr/test11-add-data-member-report-0.1_0.txt"
   },
   {
     "data/test-diff-suppr/libtest11-add-data-member-v0.so",
@@ -526,6 +536,16 @@  InOutSpec in_out_specs[] =
     "data/test-diff-suppr/test11-add-data-member-report-1.txt",
     "output/test-diff-suppr/test11-add-data-member-report-1_1.txt"
   },
+  {
+    "data/test-diff-suppr/libtest11-add-data-member-v0.so",
+    "data/test-diff-suppr/libtest11-add-data-member-v1.so",
+    "",
+    "",
+    "data/test-diff-suppr/test11-add-data-member-1.1.suppr",
+    "--no-default-suppression --no-show-locs --no-redundant",
+    "data/test-diff-suppr/test11-add-data-member-report-1.1.txt",
+    "output/test-diff-suppr/test11-add-data-member-report-1.1_1.txt"
+  },
   {
     "data/test-diff-suppr/libtest11-add-data-member-v0.so",
     "data/test-diff-suppr/libtest11-add-data-member-v1.so",
@@ -536,6 +556,16 @@  InOutSpec in_out_specs[] =
     "data/test-diff-suppr/test11-add-data-member-report-1.txt",
     "output/test-diff-suppr/test11-add-data-member-report-1_2.txt"
   },
+  {
+    "data/test-diff-suppr/libtest11-add-data-member-v0.so",
+    "data/test-diff-suppr/libtest11-add-data-member-v1.so",
+    "",
+    "",
+    "data/test-diff-suppr/test11-add-data-member-2.1.suppr",
+    "--no-default-suppression --no-show-locs --no-redundant",
+    "data/test-diff-suppr/test11-add-data-member-report-1.1.txt",
+    "output/test-diff-suppr/test11-add-data-member-report-1.1_2.txt"
+  },
   {
     "data/test-diff-suppr/libtest11-add-data-member-v0.so",
     "data/test-diff-suppr/libtest11-add-data-member-v1.so",
@@ -546,6 +576,16 @@  InOutSpec in_out_specs[] =
     "data/test-diff-suppr/test11-add-data-member-report-1.txt",
     "output/test-diff-suppr/test11-add-data-member-report-1_3.txt"
   },
+  {
+    "data/test-diff-suppr/libtest11-add-data-member-v0.so",
+    "data/test-diff-suppr/libtest11-add-data-member-v1.so",
+    "",
+    "",
+    "data/test-diff-suppr/test11-add-data-member-3.1.suppr",
+    "--no-default-suppression --no-show-locs --no-redundant",
+    "data/test-diff-suppr/test11-add-data-member-report-1.1.txt",
+    "output/test-diff-suppr/test11-add-data-member-report-1.1_3.txt"
+  },
   {
     "data/test-diff-suppr/libtest11-add-data-member-v0.so",
     "data/test-diff-suppr/libtest11-add-data-member-v1.so",
@@ -556,6 +596,16 @@  InOutSpec in_out_specs[] =
     "data/test-diff-suppr/test11-add-data-member-report-1.txt",
     "output/test-diff-suppr/test11-add-data-member-report-1_4.txt"
   },
+  {
+    "data/test-diff-suppr/libtest11-add-data-member-v0.so",
+    "data/test-diff-suppr/libtest11-add-data-member-v1.so",
+    "",
+    "",
+    "data/test-diff-suppr/test11-add-data-member-4.1.suppr",
+    "--no-default-suppression --no-show-locs --no-redundant",
+    "data/test-diff-suppr/test11-add-data-member-report-1.1.txt",
+    "output/test-diff-suppr/test11-add-data-member-report-1.1_4.txt"
+  },
   {
     "data/test-diff-suppr/libtest12-add-data-member-v0.so",
     "data/test-diff-suppr/libtest12-add-data-member-v1.so",
@@ -576,6 +626,16 @@  InOutSpec in_out_specs[] =
     "data/test-diff-suppr/test12-add-data-member-report-1.txt",
     "output/test-diff-suppr/test12-add-data-member-report-1.txt"
   },
+  {
+    "data/test-diff-suppr/libtest12-add-data-member-v0.so",
+    "data/test-diff-suppr/libtest12-add-data-member-v1.so",
+    "",
+    "",
+    "data/test-diff-suppr/test12-add-data-member-0.1.suppr",
+    "--no-default-suppression --no-show-locs --no-redundant",
+    "data/test-diff-suppr/test12-add-data-member-report-1.1.txt",
+    "output/test-diff-suppr/test12-add-data-member-report-1.1.txt"
+  },
   {
     "data/test-diff-suppr/libtest12-add-data-member-v0.so",
     "data/test-diff-suppr/libtest12-add-data-member-v1.so",
@@ -605,6 +665,16 @@  InOutSpec in_out_specs[] =
     "--no-default-suppression --no-show-locs --no-redundant",
     "data/test-diff-suppr/test13-suppr-through-pointer-report-1.txt",
     "output/test-diff-suppr/test13-suppr-through-pointer-report-1.txt"
+  },
+    {
+    "data/test-diff-suppr/libtest13-suppr-through-pointer-v0.so",
+    "data/test-diff-suppr/libtest13-suppr-through-pointer-v1.so",
+    "",
+    "",
+    "data/test-diff-suppr/test13-suppr-through-pointer-0.1.suppr",
+    "--no-default-suppression --no-show-locs --no-redundant",
+    "data/test-diff-suppr/test13-suppr-through-pointer-report-1.1.txt",
+    "output/test-diff-suppr/test13-suppr-through-pointer-report-1.1.txt"
   },
   {
     "data/test-diff-suppr/test14-suppr-non-redundant-v0.o",
@@ -1706,6 +1776,16 @@  InOutSpec in_out_specs[] =
     "data/test-diff-suppr/test35-leaf-report-0.txt",
     "output/test-diff-suppr/test35-leaf-report-0.txt"
   },
+  {
+    "data/test-diff-suppr/libtest35-leaf-v0.so",
+    "data/test-diff-suppr/libtest35-leaf-v1.so",
+    "",
+    "",
+    "data/test-diff-suppr/test35-leaf.1.suppr",
+    "--no-default-suppression --leaf-changes-only --impacted-interfaces",
+    "data/test-diff-suppr/test35-leaf-report-0.1.txt",
+    "output/test-diff-suppr/test35-leaf-report-0.1.txt"
+  },
   {
     "data/test-diff-suppr/libtest36-leaf-v0.so",
     "data/test-diff-suppr/libtest36-leaf-v1.so",