[6/7,applied] Support suppressing data member insertion before a flexible array member

Message ID 87mswd6272.fsf@redhat.com
State New
Headers
Series Support the Linux Kernel UAPI checker project |

Commit Message

Dodji Seketeli Oct. 20, 2023, 10:03 a.m. UTC
  Hello,

Consider this code example:

    $ cat test-v0.c
     1	struct foo
     2	{
     3	  int member0;
     4	  char pad[]; /* <-- flexible array member.  */
     5	};
     6
     7	void
     8	foo(struct foo * p __attribute__((unused)))
     9	{
    10	}
    $

Consider this new version of the code where a data member has been
added right before the flexible array member:

    $ cat -n test-v1.c
     1	struct foo
     2	{
     3	  int member0;
     4	  char member1; /*<-- added member.  */
     5	  char pad[]; /* <-- flexible array member.  */
     6	};
     7
     8	void
     9	foo(struct foo * p __attribute__((unused)))
    10	{
    11	}
    $

Here is what abidiff reports about the change:

    $ abidiff test-v0.o test-v1.o || echo "returned value: $?"
    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 void foo(foo*)' at test-v0.c:8:1 has some indirect sub-type changes:
	parameter 1 of type 'foo*' has sub-type changes:
	  in pointed to type 'struct foo' at test-v1.c:1:1:
	    type size changed from 32 to 64 (in bits)
	    1 data member insertion:
	      'char member1', at offset 32 (in bits) at test-v1.c:4:1
	    1 data member change:
	      'char pad[]' offset changed from 32 to 40 (in bits) (by +8 bits)

    returned value: 4
    $

This patch allows users to suppress this change report using a new
property value to the "has_data_member_inserted_at" property of the
[suppress_type] directive.  The resulting suppression specification
reads:

    $ cat -n foo.suppr
	 1	[suppress_type]
	 2	 type_kind = struct
         3       name = foo
	 4	 has_data_member_inserted_at = offset_of_flexible_array_data_member
	 5	 has_size_change = yes
    $

With this suppression specification the previous command now gives:

    $ abidiff --suppr foo.suppr test-v0.o test-v1.o && echo "returned value: $?"
    Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
    Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

    returned value: 0
    $

The patch adds new test cases and updates the documentation to add a
mention to the new offset_of_flexible_array_data_member named
boundary.

	* doc/manuals/libabigail-concepts.rst: Add documentation for the
	new "offset_of_flexible_array_data_member" named boundary.
	* include/abg-fwd.h (has_flexible_array_data_member): Declare new
	function.
	* src/abg-ir.cc (has_flexible_array_data_member): Define it.
	* include/abg-suppression.h
	(type_suppression::insertion_range::named_boundary_sptr): Define
	new typedef.
	(type_suppression::insertion_range::create_named_boundary): Declare
	new static function member function.
	(is_named_boundary): Declare new function.
	(class type_suppression::insertion_range::named_boundary): Declare
	new type.
	* src/abg-suppression.cc
	(struct type_suppression::insertion_range::named_boundary::priv):
	Define new private type.
	(OFFSET_OF_FLEXIBLE_ARRAY_DATA_MEMBER_STRING): Define new static
	constant string getter function.
	(type_suppression::insertion_range::create_named_boundary): Define
	new static member function.
	(is_named_boundary): Define new function.
	(read_type_suppression): Parse the new
	"offset_of_flexible_array_data_member" named boundary.
	(type_suppression::insertion_range::eval_boundary): Evaluate the
	new "offset_of_flexible_array_data_member" named boundary.
	* tests/data/test-abidiff-exit/test-fam1-report-[1-5].txt: New
	reference test output.
	* tests/data/test-abidiff-exit/test-fam2-report-1.txt: Likewise.
	* tests/data/test-abidiff-exit/test-fam1-suppr-[1-4].abignore: New test
	suppression specification.
	* tests/data/test-abidiff-exit/test-fam{1,2}-v{0,1}.o: New test input
	binaries.
	* tests/data/test-abidiff-exit/test-fam{1,2}-v{0,1}.c: Source code of
	the test input binaries.
	* tests/data/Makefile.am: Add the new test material to the source
	distribution.
	* tests/test-abidiff-exit.cc (in_out_specs): Add the new test
	input to this harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Applied to master.
---
 doc/manuals/libabigail-concepts.rst           |   5 +
 include/abg-fwd.h                             |   9 ++
 include/abg-suppression.h                     |  27 +++++
 src/abg-ir.cc                                 |  61 ++++++++++
 src/abg-suppression.cc                        |  83 ++++++++++++++
 tests/data/Makefile.am                        |  18 +++
 .../test-abidiff-exit/test-fam1-report-1.txt  |  14 +++
 .../test-abidiff-exit/test-fam1-report-2.txt  |   3 +
 .../test-abidiff-exit/test-fam1-report-3.txt  |  14 +++
 .../test-abidiff-exit/test-fam1-report-4.txt  |   3 +
 .../test-abidiff-exit/test-fam1-report-5.txt  |  14 +++
 .../test-fam1-suppr-1.abignore                |   4 +
 .../test-fam1-suppr-2.abignore                |   3 +
 .../test-fam1-suppr-3.abignore                |   5 +
 .../test-fam1-suppr-4.abignore                |   5 +
 tests/data/test-abidiff-exit/test-fam1-v0.c   |  10 ++
 tests/data/test-abidiff-exit/test-fam1-v0.o   | Bin 0 -> 3184 bytes
 tests/data/test-abidiff-exit/test-fam1-v1.c   |  11 ++
 tests/data/test-abidiff-exit/test-fam1-v1.o   | Bin 0 -> 3224 bytes
 .../test-abidiff-exit/test-fam2-report-1.txt  |  14 +++
 tests/data/test-abidiff-exit/test-fam2-v0.c   |  10 ++
 tests/data/test-abidiff-exit/test-fam2-v0.o   | Bin 0 -> 3184 bytes
 tests/data/test-abidiff-exit/test-fam2-v1.c   |  12 ++
 tests/data/test-abidiff-exit/test-fam2-v1.o   | Bin 0 -> 3232 bytes
 tests/test-abidiff-exit.cc                    | 105 ++++++++++++++++++
 25 files changed, 430 insertions(+)
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-report-1.txt
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-report-2.txt
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-report-3.txt
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-report-4.txt
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-report-5.txt
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-suppr-1.abignore
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-suppr-2.abignore
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-suppr-3.abignore
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-suppr-4.abignore
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-v0.c
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-v0.o
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-v1.c
 create mode 100644 tests/data/test-abidiff-exit/test-fam1-v1.o
 create mode 100644 tests/data/test-abidiff-exit/test-fam2-report-1.txt
 create mode 100644 tests/data/test-abidiff-exit/test-fam2-v0.c
 create mode 100644 tests/data/test-abidiff-exit/test-fam2-v0.o
 create mode 100644 tests/data/test-abidiff-exit/test-fam2-v1.c
 create mode 100644 tests/data/test-abidiff-exit/test-fam2-v1.o

new file mode 100644
index 00000000..0267d32b
new file mode 100644
index 00000000..e922b423
new file mode 100644
index 00000000..35002c53
index b9ea4792..42b717f6 100644
  

Patch

diff --git a/doc/manuals/libabigail-concepts.rst b/doc/manuals/libabigail-concepts.rst
index 324c5162..28e71684 100644
--- a/doc/manuals/libabigail-concepts.rst
+++ b/doc/manuals/libabigail-concepts.rst
@@ -500,6 +500,11 @@  names start with the string "private_data_member".
 	       value equals the offset of the end of the structure or
 	       class.
 
+	     - the keyword ``offset_of_flexible_array_data_member``
+               which is a named constant that evaluates to the offset
+               of the flexible array data member contained in the
+               relevant structure.
+
 	     - the function call expression
 	       ``offset_of(data-member-name)`` where `data-member-name` is
 	       the name of a given data member of the relevant structure
diff --git a/include/abg-fwd.h b/include/abg-fwd.h
index 0edc9927..7d6637b9 100644
--- a/include/abg-fwd.h
+++ b/include/abg-fwd.h
@@ -481,6 +481,15 @@  is_class_type(const type_or_decl_base*);
 class_decl_sptr
 is_class_type(const type_or_decl_base_sptr&);
 
+var_decl_sptr
+has_flexible_array_data_member(const class_decl&);
+
+var_decl_sptr
+has_flexible_array_data_member(const class_decl*);
+
+var_decl_sptr
+has_flexible_array_data_member(const class_decl_sptr&);
+
 bool
 is_declaration_only_class_or_union_type(const type_base *t,
 					bool look_through_decl_only = false);
diff --git a/include/abg-suppression.h b/include/abg-suppression.h
index cbb16207..996600bb 100644
--- a/include/abg-suppression.h
+++ b/include/abg-suppression.h
@@ -366,6 +366,7 @@  public:
   class boundary;
   class integer_boundary;
   class fn_call_expr_boundary;
+  class named_boundary;
 
   /// Convenience typedef for a shared_ptr to @ref boundary
   typedef shared_ptr<boundary> boundary_sptr;
@@ -377,6 +378,10 @@  public:
   /// fn_call_expr_boundary
   typedef shared_ptr<fn_call_expr_boundary> fn_call_expr_boundary_sptr;
 
+  /// Convenience typedef for a shared_ptr to a @ref
+  /// named_boundary
+  typedef shared_ptr<named_boundary> named_boundary_sptr;
+
   insertion_range();
 
   insertion_range(boundary_sptr begin, boundary_sptr end);
@@ -396,6 +401,9 @@  public:
   static insertion_range::fn_call_expr_boundary_sptr
   create_fn_call_expr_boundary(const string&);
 
+  static insertion_range::named_boundary_sptr
+  create_named_boundary(const string&);
+
   static bool
   eval_boundary(const boundary_sptr	boundary,
 		const class_or_union*	context,
@@ -411,6 +419,9 @@  is_integer_boundary(type_suppression::insertion_range::boundary_sptr);
 type_suppression::insertion_range::fn_call_expr_boundary_sptr
 is_fn_call_expr_boundary(type_suppression::insertion_range::boundary_sptr);
 
+type_suppression::insertion_range::named_boundary_sptr
+is_named_boundary(type_suppression::insertion_range::boundary_sptr);
+
 /// The abstraction of the boundary of an @ref insertion_range, in the
 /// context of a @ref type_suppression
 class type_suppression::insertion_range::boundary
@@ -458,6 +469,22 @@  public:
   ~fn_call_expr_boundary();
 }; //end class type_suppression::insertion_range::fn_call_expr_boundary
 
+/// An @ref insertion_range boundary that is expressed as a named
+/// constant that is to be evaluated later in the context of a given
+/// type and resolved to a bit offset.
+class type_suppression::insertion_range::named_boundary
+  : public type_suppression::insertion_range::boundary
+{
+  struct priv;
+  std::unique_ptr<priv> priv_;
+
+  named_boundary();
+
+public:
+  named_boundary(const string& name);
+  const string& get_name() const;
+}; //end class type_suppression::insertion_range::named_boundary
+
 /// Abstraction of a negated type suppression specification.
 ///
 /// A negated type suppression suppresses a type if the negation of
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index bb9483c9..79aec355 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -10760,6 +10760,67 @@  class_decl_sptr
 is_class_type(const type_or_decl_base_sptr& d)
 {return dynamic_pointer_cast<class_decl>(d);}
 
+/// Test if the last data member of a class is an array with
+/// non-finite data member.
+///
+/// The flexible data member idiom is a well known C idiom:
+/// https://en.wikipedia.org/wiki/Flexible_array_member.
+///
+/// @param klass the class to consider.
+///
+/// @return the data member which type is a flexible array, if any, or
+/// nil.
+var_decl_sptr
+has_flexible_array_data_member(const class_decl& klass)
+{
+  var_decl_sptr nil;
+  const class_or_union::data_members& dms = klass.get_data_members();
+  if (dms.empty())
+    return nil;
+
+  if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
+    {// The type of the last data member is an array.
+      if (array->is_infinite())
+	// The array has a non-finite size.  We are thus looking at a
+	// flexible array data member.  Let's return it.
+	return dms.back();
+    }
+
+  return nil;
+}
+
+/// Test if the last data member of a class is an array with
+/// non-finite data member.
+///
+/// The flexible data member idiom is a well known C idiom:
+/// https://en.wikipedia.org/wiki/Flexible_array_member.
+///
+/// @param klass the class to consider.
+///
+/// @return the data member which type is a flexible array, if any, or
+/// nil.
+var_decl_sptr
+has_flexible_array_data_member(const class_decl* klass)
+{
+  if (!klass)
+    return var_decl_sptr();
+
+  return has_flexible_array_data_member(*klass);
+}
+
+/// Test if the last data member of a class is an array with
+/// non-finite data member.
+///
+/// The flexible data member idiom is a well known C idiom:
+/// https://en.wikipedia.org/wiki/Flexible_array_member.
+///
+/// @param klass the class to consider.
+///
+/// @return the data member which type is a flexible array, if any, or
+/// nil.
+var_decl_sptr
+has_flexible_array_data_member(const class_decl_sptr& klass)
+{return has_flexible_array_data_member(klass.get());}
 
 /// Test wheter a type is a declaration-only class.
 ///
diff --git a/src/abg-suppression.cc b/src/abg-suppression.cc
index f8d065f6..d84857ba 100644
--- a/src/abg-suppression.cc
+++ b/src/abg-suppression.cc
@@ -43,6 +43,14 @@  using namespace comparison;
 using std::dynamic_pointer_cast;
 using regex::regex_t_sptr;
 
+/// @return the string constant "offset_of_flexible_array_data_member".
+static const string&
+OFFSET_OF_FLEXIBLE_ARRAY_DATA_MEMBER_STRING()
+{
+  static string s = "offset_of_flexible_array_data_member";
+  return s;
+}
+
 // <parsing stuff>
 
 // section parsing
@@ -1482,6 +1490,25 @@  type_suppression::insertion_range::create_fn_call_expr_boundary(const string& s)
   return result;
 }
 
+/// Create a named boundary.
+///
+/// The return value is to be used as a boundary for an instance of
+/// @ref type_suppression::insertion_range.  The value of that
+/// boundary is a named constant that is to be evaluated to an integer
+/// value, in the context of a @ref class_decl.  That evaluate is
+/// performed by the function
+/// type_suppression::insertion_range::eval_boundary().
+///
+/// @param name the name of the boundary.
+///
+/// @return the newly created named boundary.
+type_suppression::insertion_range::named_boundary_sptr
+type_suppression::insertion_range::create_named_boundary(const string& name)
+{
+  named_boundary_sptr result(new named_boundary(name));
+  return result;
+}
+
 /// Evaluate an insertion range boundary to get a resulting integer
 /// value.
 ///
@@ -1563,6 +1590,19 @@  type_suppression::insertion_range::eval_boundary(const boundary_sptr	boundary,
 	    }
 	}
     }
+  else if (named_boundary_sptr b = is_named_boundary(boundary))
+    {
+      if (b->get_name() == OFFSET_OF_FLEXIBLE_ARRAY_DATA_MEMBER_STRING())
+	{
+	  // Look at the last data member of 'context' and make sure
+	  // its type is an array with non-finite size.
+	  if (var_decl_sptr dm = has_flexible_array_data_member(is_class_type(context)))
+	    {
+	      value = get_data_member_offset(dm);
+	      return true;
+	    }
+	}
+    }
   return false;
 }
 
@@ -1605,6 +1645,18 @@  type_suppression::insertion_range::fn_call_expr_boundary_sptr
 is_fn_call_expr_boundary(type_suppression::insertion_range::boundary_sptr b)
 {return dynamic_pointer_cast<type_suppression::insertion_range::fn_call_expr_boundary>(b);}
 
+/// Test if a given instance of @ref
+/// type_suppression::insertion_range::boundary is actually a named boundary.
+///
+/// @param b the boundary to consider.
+///
+/// @return the instance of @ref
+/// type_suppression::insertion_range::named_boundary if @p b is a
+/// named boundary, or nil.
+type_suppression::insertion_range::named_boundary_sptr
+is_named_boundary(type_suppression::insertion_range::boundary_sptr b)
+{return dynamic_pointer_cast<type_suppression::insertion_range::named_boundary>(b);}
+
 /// The private data type of @ref
 /// type_suppression::insertion_range::boundary.
 struct type_suppression::insertion_range::boundary::priv
@@ -1706,6 +1758,35 @@  type_suppression::insertion_range::fn_call_expr_boundary::operator ini::function
 type_suppression::insertion_range::fn_call_expr_boundary::~fn_call_expr_boundary()
 {}
 
+/// The private data type for the @ref
+/// type_suppression::insertion_range::named_boundary.
+struct type_suppression::insertion_range::named_boundary::priv
+{
+  string name_;
+
+  priv()
+  {}
+
+  priv(const string& name)
+    : name_(name)
+  {}
+}; // end struct type_suppression::insertion_range::named_boundary::priv
+
+/// Constructor for @ref
+/// type_suppression::insertion_range::named_boundary
+///
+/// @param name the name of the @ref named_boundary type.
+type_suppression::insertion_range::named_boundary::named_boundary(const string& name)
+  : priv_(new priv(name))
+{}
+
+/// Getter for the name of the named boundary.
+///
+/// @return the name of the named boundary.
+const string&
+type_suppression::insertion_range::named_boundary::get_name() const
+{return priv_->name_;}
+
 /// Test if an instance of @ref suppression is an instance of @ref
 /// type_suppression.
 ///
@@ -2021,6 +2102,8 @@  read_type_suppression(const ini::config::section& section)
       type_suppression::insertion_range::boundary_sptr begin, end;
       if (ins_point == "end")
 	begin = type_suppression::insertion_range::create_integer_boundary(-1);
+      else if (ins_point == OFFSET_OF_FLEXIBLE_ARRAY_DATA_MEMBER_STRING())
+	begin = type_suppression::insertion_range::create_named_boundary(ins_point);
       else if (isdigit(ins_point[0]))
 	begin = type_suppression::insertion_range::create_integer_boundary
 	  (atoi(ins_point.c_str()));
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 3134df7d..945831ff 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -367,6 +367,24 @@  test-abidiff-exit/test-anon-types-v0.c \
 test-abidiff-exit/test-anon-types-v0.o \
 test-abidiff-exit/test-anon-types-v1.c \
 test-abidiff-exit/test-anon-types-v1.o \
+test-abidiff-exit/test-fam1-report-1.txt \
+test-abidiff-exit/test-fam1-report-2.txt \
+test-abidiff-exit/test-fam1-report-3.txt \
+test-abidiff-exit/test-fam1-report-4.txt \
+test-abidiff-exit/test-fam1-report-5.txt \
+test-abidiff-exit/test-fam1-suppr-1.abignore \
+test-abidiff-exit/test-fam1-suppr-2.abignore \
+test-abidiff-exit/test-fam1-suppr-3.abignore \
+test-abidiff-exit/test-fam1-suppr-4.abignore \
+test-abidiff-exit/test-fam1-v0.c \
+test-abidiff-exit/test-fam1-v0.o \
+test-abidiff-exit/test-fam1-v1.c \
+test-abidiff-exit/test-fam1-v1.o \
+test-abidiff-exit/test-fam2-report-1.txt \
+test-abidiff-exit/test-fam2-v0.c \
+test-abidiff-exit/test-fam2-v0.o \
+test-abidiff-exit/test-fam2-v1.c \
+test-abidiff-exit/test-fam2-v1.o \
 \
 test-diff-dwarf/test0-v0.cc		\
 test-diff-dwarf/test0-v0.o			\
diff --git a/tests/data/test-abidiff-exit/test-fam1-report-1.txt b/tests/data/test-abidiff-exit/test-fam1-report-1.txt
new file mode 100644
index 00000000..90861635
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-report-1.txt
@@ -0,0 +1,14 @@ 
+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 void foo(foo*)' at test-fam1-v0.c:8:1 has some indirect sub-type changes:
+    parameter 1 of type 'foo*' has sub-type changes:
+      in pointed to type 'struct foo' at test-fam1-v1.c:1:1:
+        type size changed from 32 to 64 (in bits)
+        1 data member insertion:
+          'char member1', at offset 32 (in bits) at test-fam1-v1.c:4:1
+        1 data member change:
+          'char pad[]' offset changed from 32 to 40 (in bits) (by +8 bits)
+
diff --git a/tests/data/test-abidiff-exit/test-fam1-report-2.txt b/tests/data/test-abidiff-exit/test-fam1-report-2.txt
new file mode 100644
index 00000000..9666a8fd
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-report-2.txt
@@ -0,0 +1,3 @@ 
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
diff --git a/tests/data/test-abidiff-exit/test-fam1-report-3.txt b/tests/data/test-abidiff-exit/test-fam1-report-3.txt
new file mode 100644
index 00000000..90861635
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-report-3.txt
@@ -0,0 +1,14 @@ 
+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 void foo(foo*)' at test-fam1-v0.c:8:1 has some indirect sub-type changes:
+    parameter 1 of type 'foo*' has sub-type changes:
+      in pointed to type 'struct foo' at test-fam1-v1.c:1:1:
+        type size changed from 32 to 64 (in bits)
+        1 data member insertion:
+          'char member1', at offset 32 (in bits) at test-fam1-v1.c:4:1
+        1 data member change:
+          'char pad[]' offset changed from 32 to 40 (in bits) (by +8 bits)
+
diff --git a/tests/data/test-abidiff-exit/test-fam1-report-4.txt b/tests/data/test-abidiff-exit/test-fam1-report-4.txt
new file mode 100644
index 00000000..9666a8fd
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-report-4.txt
@@ -0,0 +1,3 @@ 
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
diff --git a/tests/data/test-abidiff-exit/test-fam1-report-5.txt b/tests/data/test-abidiff-exit/test-fam1-report-5.txt
new file mode 100644
index 00000000..90861635
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-report-5.txt
@@ -0,0 +1,14 @@ 
+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 void foo(foo*)' at test-fam1-v0.c:8:1 has some indirect sub-type changes:
+    parameter 1 of type 'foo*' has sub-type changes:
+      in pointed to type 'struct foo' at test-fam1-v1.c:1:1:
+        type size changed from 32 to 64 (in bits)
+        1 data member insertion:
+          'char member1', at offset 32 (in bits) at test-fam1-v1.c:4:1
+        1 data member change:
+          'char pad[]' offset changed from 32 to 40 (in bits) (by +8 bits)
+
diff --git a/tests/data/test-abidiff-exit/test-fam1-suppr-1.abignore b/tests/data/test-abidiff-exit/test-fam1-suppr-1.abignore
new file mode 100644
index 00000000..ab6f8500
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-suppr-1.abignore
@@ -0,0 +1,4 @@ 
+[suppress_type]
+ type_kind = struct
+ has_data_member_inserted_at = offset_of_flexible_array_data_member
+ has_size_change = yes
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-fam1-suppr-2.abignore b/tests/data/test-abidiff-exit/test-fam1-suppr-2.abignore
new file mode 100644
index 00000000..1699a00f
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-suppr-2.abignore
@@ -0,0 +1,3 @@ 
+[suppress_type]
+ type_kind = struct
+ has_data_member_inserted_at = offset_of_flexible_array_data_member
diff --git a/tests/data/test-abidiff-exit/test-fam1-suppr-3.abignore b/tests/data/test-abidiff-exit/test-fam1-suppr-3.abignore
new file mode 100644
index 00000000..7ff5e6d1
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-suppr-3.abignore
@@ -0,0 +1,5 @@ 
+[suppress_type]
+ type_kind = struct
+ name = foo
+ has_data_member_inserted_at = offset_of_flexible_array_data_member
+ has_size_change = yes
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-fam1-suppr-4.abignore b/tests/data/test-abidiff-exit/test-fam1-suppr-4.abignore
new file mode 100644
index 00000000..6afd1283
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-suppr-4.abignore
@@ -0,0 +1,5 @@ 
+[suppress_type]
+ type_kind = struct
+ name = bar
+ has_data_member_inserted_at = offset_of_flexible_array_data_member
+ has_size_change = yes
\ No newline at end of file
diff --git a/tests/data/test-abidiff-exit/test-fam1-v0.c b/tests/data/test-abidiff-exit/test-fam1-v0.c
new file mode 100644
index 00000000..982f0429
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-v0.c
@@ -0,0 +1,10 @@ 
+struct foo
+{
+  int member0;
+  char pad[];
+};
+
+void
+foo(struct foo * p __attribute__((unused)))
+{
+}
diff --git a/tests/data/test-abidiff-exit/test-fam1-v0.o b/tests/data/test-abidiff-exit/test-fam1-v0.o
new file mode 100644
index 0000000000000000000000000000000000000000..e36cdc0864827b07b045e1fafae82038a4c250bf
GIT binary patch
literal 3184
zcmb_e&2Jl35TEC@<4v}4oH&A}0cDFo{SdqUpoGwpVib`kfGVg|ZdJOr*Y<+fwstpB
zC_)I3kSZ=ka6%j^gphjRfVgn)jsJr?+$wQ^ncaDt?aNk0z)1UM<~N`3)BgDNx3&vH
zfFuEz;YgDxz_ffMw_~vl%TR;sJGXz^x&6_DJ2&p%L%0M&Cu@O*r)kKNkx{h%WCBGY
z^mh>~l0j%?lA$zpdLWAW4U~&8Q!IJo2+AR9Bm8t4uu9yI5HqCBQZAvVeakxH+aJ(6
zH$~eLNrf+mVCXi5h-bktE*n|}(M9oGrDkYrt80s5sa$;$K&uH&H;jwMCF5m7)Uc0v
z&?<?#Tid|=B?R;=FvAIP`eh+@YZRrQhFxT{ws>_#dY@ULBJGp6R>)(nlu1)K31BQ>
zUlat-Q^V9M#48$0G|0)N01Mm5OXzzZxe(&d$~-Yz6Z}wEi<hS$)(Q(r+BmKxU^Z1x
zeOA!W^~%-j=2r71v)QyS*iEz5XuZ%_Z@g%pz2^4J9VcRg)jDTdezZS!HwW(64ZJR@
zPS7209&W5#>ldtpmT3)OG#L-f{c-3G#u!d}>AQZ%4I0oLIsrs(7+HPCZ(0Wpy9@Q<
z#CPkxN$)+cKJcRY$m=*AZ{T>NIyzb5{&X7DDJHD<oXCkq3q5*Xzi+vRUi3d?P+C${
zxU#i%(L9TbbnYLlP`t=EEVCePT?27g6{{!8`W@Vnrx2%)DBjuED%H;mTk|v9=#ap<
zBW-38{`f1;h<lg^gU07cHEL+dBQ3d?$4nZ;w=M_IJQ5kJ2D2IMNYoy2mNhtW<dl&#
zz}uQb8Z6|Xc#C2F7+ytWDYHK5ZBllbUKAp^2XiQAXDu@mo}Jwi1tAempQI;Pkhtvl
z6yvmG={-dGe8yk)K+r20oa)|WJ?S>7N%&R9513P3!iTJX%3Q50=Scn~_8~^=Mx^>b
zlfdbG-(j6zFCsbLuM!oS%q9LE>zA0T`Ax=YZRktM4nOcCrvr8v1qmNYDRK`Zu<3aK
zyAy_B2kywRdv0fcu;-2Y6ST#$)9D26!9!*zaK;1o;gFFxc4Y{bkRri*vEH5dzKidg
zJ)T6ajSqtrMo#yAPV5f%`hnxSY3Kh*SjA{sBe_p9S(}CQJhM)|SvrjhVd{;4GwYO*
z)%Y`Lqx1N0<7xlZoK#NM|B;joslIfs=-)y+<3pm!hxK>H7m<^nygT^Q8q+3@YECjd
zh^+wfJhFPs_iZ%f#ec(KLk2QeeQBO~{a1NIWjysyuc_L94>2_-LhvhtZ;+B9)prkV
zdG*^||0c&$eR?m{`cuRxr|c8On3nl+`VwF+>r4J2;(76(aQsh?iT~me@hv`(^~c12
z&GCvGIO>6B2idpuzsK?1u7qL8@f#_U2y*=-{5=YJ>wlNmU!GH1fBKD(@e-$g)Y=Ha
sU9LamhUs^Rel68_+S9zL>U@9X{}gnKNu59Sl^6dD_y04;Nv6jC4RnF@YybcN

literal 0
HcmV?d00001

diff --git a/tests/data/test-abidiff-exit/test-fam1-v1.c b/tests/data/test-abidiff-exit/test-fam1-v1.c
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam1-v1.c
@@ -0,0 +1,11 @@ 
+struct foo
+{
+  int member0;
+  char member1;
+  char pad[];
+};
+
+void
+foo(struct foo * p __attribute__((unused)))
+{
+}
diff --git a/tests/data/test-abidiff-exit/test-fam1-v1.o b/tests/data/test-abidiff-exit/test-fam1-v1.o
new file mode 100644
index 0000000000000000000000000000000000000000..3bfcfc3f15baea9759c977da0a2f38f84f2527ad
GIT binary patch
literal 3224
zcmb_eOOG2x5U%#v>+w$ZX#~40XlJ9KJj9IcB`nK^4Mr;xuZW@$DMz#!+hco(U$V!G
z2?B(WkRpT>1QHxL0Yc(N1PAV1_ywG~@B_FZae%6sYP;Q;C@7*NPgQ+gUv+i$bdTSE
z^~$A`5FkasMVNXL1^6;MwabxNhQ}ZeH!64jsN8w?ue)#j@)N=t5GIWp^mv*cs#uDX
zZuEL!3SoK(Ml%{&GGjY!w$Myx`d%GG#_XY!fw^=h=!TFIa}<}Qi1+Yk(gRXvRAG+N
ziri!ga!T>lJq()f<Jc-$sZU#AnJzKK0vL;XTjGNCqIH<xMMmlrSk^_$Sj2^_h-Vh_
zma)09xgu7x%THicd108AwPz7Q<gqeLV8(9DpJP6@A}hpUo`TFRI7F3m#mnn5`t&;G
zEU(>Or-=ECk|wnVU@c)8M1p6jVyYFQ?nV|p<mx5>8x_<Uj6H{12=Vvg0x4<={?OQr
z`jZlysiin=#LEcCO<W@<K1>-HeEI4P`=IoKT`IZf-IBds+<vaOQ+(b&bKS4o6))rg
zXZx(}biz^B-*5U|e-PBr^#--p{&;uC**WhVZ`)22+P!Ym9(9L7vx{`v&RWYGK*#S?
z{Xvm+2||AuIt{N=a*j)G4GOJZ$1l`-^*4h;GYAXqpz2kFrWdpe7~~8`{r;dpoMEBv
zg<fPj7*P)z4aXk`;s209D@k+V^1;ELeFmF#_CItA@a)7QZeIs6UKSfCvgTdfm8TG<
zA4#;kuPiQqlsZ_LyMzHTocN>-O~ar6Bn{#&Cc$_}C%Zi}Zp6oT1|!G78Ir_+=s?~#
zWPoyMD5D1C6mM!84|tyqI57=UECcX>CWrw`2`JUSa38*m$g0wx$%)eTm#!5Oxd-!T
ztE-lo30GIQN+cA*=_loJHY6@9ev)z8F?Dy&De<xff?iT^n%8HaZU7R>Pk4tMlv}Zy
z;5XU-K*O)H{|Rfo9=UePpWzr%)K3yU{$vbK`tUmYbhDAjK71CtP+~3dui3xATF-AY
zPCZlm2JZ0fPUuxphl5zRq!s$(5L~)2z^x94;12w@=hpq|sCg808$BG0Y_D1!_{THD
z-oWcN{aH#o==zd^Q%IBGqsXuIIvpQxJh$5meHX6^XBc|5Tb$T$9W@4CM{Xdm=TX%L
z5~)XWpJbjg8<Y2(eTr3O3mw9u54ke%nqsS_&OeQV^qxK{pY~tRN%P71e<nu}J(k`p
zx~<Ae44FlKSxqLaAVzWWOyOrYl6`#YIcdOP@S7-V`p{#q;gF6|^mhyvr_{*OV`-g9
z_3!eAN<P(3x2#@&9Wgy8Lhu`dSIALBk3GV%r1@Js|4ru7{B*zQ^Y;;>oU%?dBRR>3
zb0h)Qa(=1bK|G271@rGcg#Yma_!WL33lHIc&U`Hl-qK%a4v=-r`0trNa~B~tX8x`W
zWG(wA;cwAM>i@6YfBBwL|LNNy`4Xpk^tlm&A9(&27fjzL`ikm&+S8<^uJQSi|6edH
U5`FztR}%ksuK!2oNu~4u1vo+YiU0rr

literal 0
HcmV?d00001

diff --git a/tests/data/test-abidiff-exit/test-fam2-report-1.txt b/tests/data/test-abidiff-exit/test-fam2-report-1.txt
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam2-report-1.txt
@@ -0,0 +1,14 @@ 
+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 void foo(foo*)' at test-fam2-v0.c:8:1 has some indirect sub-type changes:
+    parameter 1 of type 'foo*' has sub-type changes:
+      in pointed to type 'struct foo' at test-fam2-v1.c:1:1:
+        type size hasn't changed
+        1 data member insertion:
+          'char member1', at offset 32 (in bits) at test-fam2-v1.c:4:1
+        1 data member change:
+          'char pad[10]' offset changed from 32 to 40 (in bits) (by +8 bits)
+
diff --git a/tests/data/test-abidiff-exit/test-fam2-v0.c b/tests/data/test-abidiff-exit/test-fam2-v0.c
new file mode 100644
index 00000000..2403e6cf
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam2-v0.c
@@ -0,0 +1,10 @@ 
+struct foo
+{
+  int member0;
+  char pad[10];
+};
+
+void
+foo(struct foo * p __attribute__((unused)))
+{
+}
diff --git a/tests/data/test-abidiff-exit/test-fam2-v0.o b/tests/data/test-abidiff-exit/test-fam2-v0.o
new file mode 100644
index 0000000000000000000000000000000000000000..e5cc0b042e78465c477f6905b60bc70a446d38ea
GIT binary patch
literal 3184
zcmb_e&2Jl35TEC@<4v}4oVcP*1IiYG`XP4xK^sC#icv(G0IHx;xmD@fUfT=awYA=a
zP=q)XAyr(8;0RKMkPsY@5SQLL^Jny4ZXgbHW<Ae+d0iw#8EJQBe)IW0cRzXkt*x98
zAW6U_c%(@bU{ri0H&d|*N1+1Owr}6xzWwnZcdq~XBf<p`CRuazdWK#qS&CwGheId}
zVZMuCo(#e$k_?5B*8!0?ucMrYnS3FL5-299h4`5Cn#D3{Lqg1;3bT|<nA65(A@TM1
zXq_9OZHc7Z7k#iymqNsIU|E+eqlD<9c)nDzjMbIZMX^*Y9|JHd!Z0oCf_2e)*%B3O
zWFCytMBS;ZWBvjHrV7k(LL7flh@A>WnI~bVQbq4sSG>9`{ZB1Zndb4E%j7dxP!i>i
z16T{#*$!IZ1!|d^g>+I=iC%JeQ-Fmn<OTFSi(CltS81LY%?ds!tfmu`6RWv}N!m27
zAYgW?p174W(Dm|_YxZXSCA(gC&$)HGQER+dTdSS7Pha&r_O_R>!D*baoiN#p{EeO;
z`Ek%j)r;Hxjf3?yXYHJ`->{t?42Dt9-iyXTFT!wI&d?8Aeq4ig--{vf$BEPR!iKY7
zbK6ku4@1A&8Ft<as=Xko4uY1~3VL2JsG^fI-W!eLD#eVe9WU`x(Ls++(Cs?@L6H0p
z8MKx(6)taXUa(K&B%S#eGn7v9(e#b0aPumNgR)pTQZ(=2ay*SVJw)lUzE&!KmfM`4
z*+Pd2ocX4e%){@0XBlw;vtTfIGwDVHEm>qt&gEk!1JXm6fh(7UVm0u*W|8p^8`*#(
zS?<^+9@Y#pU?Bs=Lk#ne;blaYl=+z+C2fi6LLriCFo&`_YMGgEb#zM<ghV(!lAdBg
z;<DotjMIuu4<X8D6@S?SL9Zw{)xE*`NW-tN{(*+~S--_xuPet$eHPe<7|k1z?*Hrr
zo{sk&*6HdZlH>hyqC%ay#J^?zB6B^z%{a}CIzQl!KMWJEg*=HTyf3B1KS;o(y8+zR
zcnogr4?MTyxAuCwLDU_hEtS1iEB5yfnZ4MHdj8>%K@j;e1WQPf;N4Vj55v&MOU;dj
ziSOdA;EWTm{XQr5`@7xP3w<8Q6S5VIr#X`AB-1rnnC@rR$ycS5s1T-~_%~H2Mb_g_
zp^f(Ae~qX0*K<-iS^p<e6w-ZZU(w$}Q}H3u=FR$m@kQk1C(jOkS5w-+x1N&>f2LM|
z@0d%b`@W3^9V6dw7_7-a=DIJ9GpqkHFQ|;C{^>T=`|lv8=R^p8WAF`96w-Zn(Uw)e
z$@On=EY+v`MXx_XjB?68QB3I=A5Qu^Q%TmB{3A4G#ed52KdZs)OOTBJoMpZKdESs!
za#l#jN&Xeuq^!6>N8iwF)O~;8_(OLQVttNZSCgVF=TE}4zq024F3-Q*r!@ccjgavY
xr+)O>2*F*h-{*$uJ49bgJ)YJyYp5olANikxZYk;Gr@pe{?{WXXaGYd%{6j_-^xgmf

literal 0
HcmV?d00001

diff --git a/tests/data/test-abidiff-exit/test-fam2-v1.c b/tests/data/test-abidiff-exit/test-fam2-v1.c
--- /dev/null
+++ b/tests/data/test-abidiff-exit/test-fam2-v1.c
@@ -0,0 +1,12 @@ 
+struct foo
+{
+  int member0;
+  char member1;	     /*  This is an added data member.  */
+  char pad[10]; 	     /*  This is not a fam, so the change should not be
+				 suppressed.  */
+};
+
+void
+foo(struct foo * p __attribute__((unused)))
+{
+}
diff --git a/tests/data/test-abidiff-exit/test-fam2-v1.o b/tests/data/test-abidiff-exit/test-fam2-v1.o
new file mode 100644
index 0000000000000000000000000000000000000000..867701a692dd3f2a056d5154c11336ffe4602e52
GIT binary patch
literal 3232
zcmb_e-ESL35TEtg@x|9TPK=--pj;4DKg69sC?TYz7)7*+T2)Y~k0?FcXZxsqw(N5h
zf>04iNEH$)f+xfSLh#T>KuGkNe}Gs103=>{L*fBu?q)CN?Nvn;BYAh`Hy=AYv%BZp
zZ(O~U5dtI$xCqCRL;=3eAM=fnZNL*yh8w$ge&4<G{$F?B{^cixb0BomYBW4cLz0Yy
zknIeIP!d9S5DZt;^2A1bR_`I3&5fKkh@3t|AqR8WoaYCS5p!ghCyU$o(`lH8j2@;q
zPjN*d-h*6IeDwpG6-KCACNA??4-DN#4#Waz#jSO5!Fa{kD{rDl=6NuTi-uOjoh*q{
z#j>HTt*$MJ<$UQWOsgz3-7vNcau8)q4Fl+r82Qh!Kh`2I#9o<<^mW)PS1|azEnZuZ
z_NP}UYUAY53fUBLi9nf?0LCIFvWFUYfpVs7AuMpn(IEF11I+B=oI~4lI13^EE-uhS
zWx*dZYhi^lVlA^6g$@030_I~;D~OLW8X8}|cEjAMy=>NM_IbNz)~odws~gpq%rn>B
zwz=yBtgz~5O=}QLeRsR-`tI0kq3DcTz3s!z4Qu1Pbx=30F7$_f*PQwjuj`{bb+pxU
z#xQUPO?O=7xdwqd39ODYs9Og$y9JfraNt(j!}dE~rRxQizSne`Uf1#Z6*RIY)6r;L
zA)iU5?F3H9T4>SsIvvYB^n(8(f|8OV!sVTvE%OW(>+FB1R9J4nI~0*Px(?#7Bvw!4
z^}E=bXAq_zQP|?wi=~e<I}3A{&>(_SN9t-8{`@CRiLFe7@v_D(pV4d4HJ-sp&~Sw`
z(jdH;52!RqJRS+HhPO72w1*sO4Njz)V?KCKQ%Hlw6qNE`cmOXUvYe<-e65rw)9XSc
zdr&|=xoa7j@Z|26$q9*Y`bm0{8Hvk`pJtpomh8^CguTpxpjQ((t?RN(&j1m{CwxEx
z(yeHU@tZ7vsNmOF{*-4mAGvpmpJN-EsGdZs{c{l<*WoRe>3JiPb@)6Ip~kbszhU_T
z&uV;=ajF^pVzMXi4g#kM_9Pfbb5C-Cdl-OCuLju7$pq}N+js1?+njdyJ-;(VUC2Al
z=GZ-$Q9EPD@4B-teb0BL3oap9g7-tYH5?3FeD-XA7`QgR7uF<jTDLf`+uQGqoq=p%
zyn)AKR?&@WB>N<zG?<CcIm=|5q;(Vs3qR-y#gzn~WL5vusHAiHxc=0CH72bm*S}9f
zf>c{NSM*vn5;nwc@?q84VF@v^lXnWgy&-MmsKz8kmcj2rtK&hneG^qGM%MQjtRB0D
zoN7z^Ov}H)4VC_sKfSVQ{%yq6m<Yjd3|=K6L8|RO>eAL9@%lH}m)58EMO}Y{7{!!%
zA{){vzMNAD@GRGt^LvP=`G3j&-#^0tlZW_U;R9KDg#Q=pub9D+dZ5`r<}K~-vH#3l
zgxCk{zbOrQmi3eHx5%W`|5vWRJf~ED`gTZviBmr6+6ckVync@prtcGdMOA<5Y1&pz
bzCZH+3z~(b?w|5X^Z$eM|B?OVr2790Gb;H(

literal 0
HcmV?d00001

diff --git a/tests/test-abidiff-exit.cc b/tests/test-abidiff-exit.cc
--- a/tests/test-abidiff-exit.cc
+++ b/tests/test-abidiff-exit.cc
@@ -1080,6 +1080,111 @@  InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/test-anon-types-report-1.txt",
     "output/test-abidiff-exit/test-anon-types-report-1.txt"
   },
+  {
+    "data/test-abidiff-exit/test-fam1-v0.o",
+    "data/test-abidiff-exit/test-fam1-v1.o",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+    "data/test-abidiff-exit/test-fam1-report-1.txt",
+    "output/test-abidiff-exit/test-fam1-report-1.txt"
+  },
+  {
+    "data/test-abidiff-exit/test-fam1-v0.o",
+    "data/test-abidiff-exit/test-fam1-v1.o",
+    "data/test-abidiff-exit/test-fam1-suppr-1.abignore",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_OK,
+    "data/test-abidiff-exit/test-fam1-report-2.txt",
+    "output/test-abidiff-exit/test-fam1-report-2.txt"
+  },
+  {
+    "data/test-abidiff-exit/test-fam1-v0.o",
+    "data/test-abidiff-exit/test-fam1-v1.o",
+    "data/test-abidiff-exit/test-fam1-suppr-2.abignore",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+    "data/test-abidiff-exit/test-fam1-report-3.txt",
+    "output/test-abidiff-exit/test-fam1-report-3.txt"
+  },
+  {
+    "data/test-abidiff-exit/test-fam1-v0.o",
+    "data/test-abidiff-exit/test-fam1-v1.o",
+    "data/test-abidiff-exit/test-fam1-suppr-3.abignore",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_OK,
+    "data/test-abidiff-exit/test-fam1-report-4.txt",
+    "output/test-abidiff-exit/test-fam1-report-4.txt"
+  },
+  {
+    "data/test-abidiff-exit/test-fam1-v0.o",
+    "data/test-abidiff-exit/test-fam1-v1.o",
+    "data/test-abidiff-exit/test-fam1-suppr-4.abignore",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+    "data/test-abidiff-exit/test-fam1-report-5.txt",
+    "output/test-abidiff-exit/test-fam1-report-5.txt"
+  },
+  {
+    "data/test-abidiff-exit/test-fam2-v0.o",
+    "data/test-abidiff-exit/test-fam2-v1.o",
+    "data/test-abidiff-exit/test-fam1-suppr-1.abignore",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+    "data/test-abidiff-exit/test-fam2-report-1.txt",
+    "output/test-abidiff-exit/test-fam2-report-1.txt"
+  },
+  {
+    "data/test-abidiff-exit/test-fam2-v0.o",
+    "data/test-abidiff-exit/test-fam2-v1.o",
+    "data/test-abidiff-exit/test-fam1-suppr-3.abignore",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+    "data/test-abidiff-exit/test-fam2-report-1.txt",
+    "output/test-abidiff-exit/test-fam2-report-1.txt"
+  },
 #ifdef WITH_BTF
   {
     "data/test-abidiff-exit/btf/test0-v0.o",