Commit Graph

786 Commits

Author SHA1 Message Date
Dodji Seketeli
c29f0f2679 corpus: Allow several variables with same ID to be exported
The libQt6Network.so.6.3.1 exhibits some interesting debug info where
two variables with slightly different qualified name have the same ELF
symbol.

Consider the DIE for this variable:
 [ 1aab3]    variable             abbrev: 118
             name                 (GNU_strp_alt) "backendMutex"
             decl_file            (implicit_const) qsslsocket_p.h (42)
             decl_line            (data1) 196
             decl_column          (data1) 26
             linkage_name         (GNU_strp_alt) "_ZN17QSslSocketPrivate12backendMutexE"
             type                 (ref_udata) [ 1aa35]
             external             (flag_present) yes
             declaration          (flag_present) yes
             inline               (implicit_const) declared_inlined (3)
             location             (exprloc)
              [ 0] addr +0x1e3050 <_ZN17QSslSocketPrivate12backendMutexE>

This DIE designates a variable named backendMutex in the global
namespace.  It's associated to the ELF symbol
_ZN17QSslSocketPrivate12backendMutexE.

Then, later, there is this DIE:

 [d05d3e]    class_type           abbrev: 260
             name                 (GNU_strp_alt) "QSslSocketPrivate"
             declaration          (flag_present) yes
             sibling              (ref_udata) [d05d70]
[...]
 [d05d70]    variable             abbrev: 642
             name                 (GNU_strp_alt) "backendMutex"
             decl_file            (implicit_const) qsslsocket_p.h (54)
             decl_line            (data1) 196
             decl_column          (data1) 26
             linkage_name         (GNU_strp_alt) "_ZN17QSslSocketPrivate12backendMutexE"
             type                 (ref_addr) [  fdc5]
             external             (flag_present) yes
             declaration          (flag_present) yes
             inline               (implicit_const) declared_inlined (3)
             location             (exprloc)
              [ 0] addr +0x1e3050 <_ZN17QSslSocketPrivate12backendMutexE>

Here, this DIE represents a static data member named
QSslSocketPrivate::backendMutex, as it's member of the
QSslSocketPrivate class.  Note how it's also associated with the ELF
symbol _ZN17QSslSocketPrivate12backendMutexE.

So both variables are associated with the same ELF symbol and should
thus be exported from the ABI corpus.

Today, only one of these variables is represented as exported in the
corpus.  Depending on the order in which the variables are analyzed,
the variable that is represented as exported might be either one or
the other, leading to some spurious self-comparison errors.

This patch fixes the issue by allowing the corpus to represent more
than one variable having a given ELF symbol to be exported.  This is
similar to what is already for functions.

This fixes the self comparison of the qt6-qtbase package, which can be
witnessed by issuing the command:

    $ fedabipkgdiff --self-compare -a --from fc36 qt6-qtbase

	* include/abg-corpus.h (corpus::lookup_variables): Replace
	corpus::lookup_variable with this one which returns the set of
	variables associated with a given ID of variable.
	* src/abg-corpus-priv.h (istr_var_ptr_set_map_type): Define new
	typedef.
	(corpus::exported_decls_builder::priv::id_vars_map_): Replace
	id_var_map_ with this new data member of type
	istr_var_ptr_set_map_type.
	(corpus::exported_decls_builder::priv::id_fns_map): Fix comment.
	(corpus::exported_decls_builder::priv::id_vars_map): Replace
	previous id_var_map with this member function.
	(corpus::exported_decls_builder::priv::var_id_is_in_id_vars_map):
	Replace the var_id_is_in_id_var_map member function.
	(corpus::exported_decls_builder::priv::var_is_in_vars): Define new
	static member function.
	(corpus::exported_decls_builder::priv::{var_is_in_id_vars_map, add_var_to_id_vars_map}):
	Define new member functions.
	(corpus::exported_decls_builder::priv::add_var_to_map): Remove.
	(corpus::exported_decls_builder::priv::add_var_to_exported):
	Adjust by using the new var_is_in_id_vars_map and
	add_var_to_id_vars_map.
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::maybe_add_var_to_exported_vars):
	Adjust, use the new
	corpus::exported_decls_builder::priv::var_is_in_id_vars_map.
	(corpus::lookup_variables): Replace corpus::lookup_variable with
	this one which returns the set of variables associated with a
	given ID of variable.
	* tools/abicompat.cc
	(compare_expected_against_provided_variables): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-09-06 22:35:22 +02:00
Dodji Seketeli
3dae26e28c hash,reader,writer: (De)Serialize hash values using the xxhash canonical form
The XH64 hashing function expects an array of bytes as the input data
to hash.  Depending on the machine's endian-ness, an 8 bytes integer
passed to XH64 might be represented differently, leading to different
hash values depending on the endian-ness.  Also, once the hash value
is computed, we need to serialize it and store it as a string of
characters in the ABIXML format.  That too represents potential
avenues for getting the endian-ness wrong.

This patch standardizes the representation of data to be given to XH64
using the big endian representation.  The xxhash project itself uses
the big endian representation as its canonical form using the data
type XXH64_canonical_t.  Almost all the ABIXML files of the test-suite
had to be updated.  This should fix the regressions we are seeing on
big endian machines since the type hashing patch landed in the
mainline.

	* include/abg-hash.h (deserialize_hash, serialize_hash): Declare
	new functions.
	* src/abg-hash.cc (deserialize_hash, serialize_hash): Define them.
	(char_to_int, int_to_char): Define static functions.
	(hash): For the overload that hashes an integer, make it take a
	second one as hashing seed.  Also, lay out the integer value to
	hash in big endian format before passing it to XH64.
	(combine_hashes): Use the amended hash function above.
	* src/abg-reader.cc (read_type_hash_and_cti): Use the new
	deserialize_hash function.
	* src/abg-writer.cc (write_type_hash_and_cti): Use the new
	serialize_hash function.
	* tests/data/test-annotate/PR29443-missing-xx.o.annotated.abi:
	Adjust.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test-anonymous-members-0.o.abi:
	Likewise.
	* tests/data/test-annotate/test-pointer-to-member-1.o.annotated.abi:
	Likewise.
	* tests/data/test-annotate/test0.abi: Likewise.
	* tests/data/test-annotate/test1.abi: Likewise.
	* tests/data/test-annotate/test13-pr18894.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test2.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-annotate/test3.so.abi: Likewise.
	* tests/data/test-annotate/test4.so.abi: Likewise.
	* tests/data/test-annotate/test5.o.abi: Likewise.
	* tests/data/test-annotate/test6.so.abi: Likewise.
	* tests/data/test-annotate/test7.so.abi: Likewise.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Likewise.
	* tests/data/test-read-btf/test0.o.abi: Likewise.
	* tests/data/test-read-btf/test1.o.abi: Likewise.
	* tests/data/test-read-ctf/PR27700/test-PR27700.abi: Likewise.
	* tests/data/test-read-ctf/test-PR26568-1.o.abi: Likewise.
	* tests/data/test-read-ctf/test-PR26568-2.o.abi: Likewise.
	* tests/data/test-read-ctf/test-alias.o.abi: Likewise.
	* tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi:
	Likewise.
	* tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi:
	Likewise.
	* tests/data/test-read-ctf/test-anonymous-fields.o.abi: Likewise.
	* tests/data/test-read-ctf/test-array-mdimension.abi: Likewise.
	* tests/data/test-read-ctf/test-array-of-pointers.abi: Likewise.
	* tests/data/test-read-ctf/test-array-size.abi: Likewise.
	* tests/data/test-read-ctf/test-bitfield-enum.abi: Likewise.
	* tests/data/test-read-ctf/test-bitfield.abi: Likewise.
	* tests/data/test-read-ctf/test-callback.abi: Likewise.
	* tests/data/test-read-ctf/test-callback2.abi: Likewise.
	* tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi:
	Likewise.
	* tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi:
	Likewise.
	* tests/data/test-read-ctf/test-const-array.abi: Likewise.
	* tests/data/test-read-ctf/test-dynamic-array.o.abi: Likewise.
	* tests/data/test-read-ctf/test-enum-many.o.hash.abi: Likewise.
	* tests/data/test-read-ctf/test-enum-symbol.o.hash.abi: Likewise.
	* tests/data/test-read-ctf/test-enum.o.abi: Likewise.
	* tests/data/test-read-ctf/test-fallback.abi: Likewise.
	* tests/data/test-read-ctf/test-forward-type-decl.abi: Likewise.
	* tests/data/test-read-ctf/test-functions-declaration.abi:
	Likewise.
	* tests/data/test-read-ctf/test-linux-module.abi: Likewise.
	* tests/data/test-read-ctf/test-list-struct.abi: Likewise.
	* tests/data/test-read-ctf/test0.abi: Likewise.
	* tests/data/test-read-ctf/test0.hash.abi: Likewise.
	* tests/data/test-read-ctf/test1.so.abi: Likewise.
	* tests/data/test-read-ctf/test1.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test3.so.abi: Likewise.
	* tests/data/test-read-ctf/test3.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test4.so.abi: Likewise.
	* tests/data/test-read-ctf/test4.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test5.o.abi: Likewise.
	* tests/data/test-read-ctf/test7.o.abi: Likewise.
	* tests/data/test-read-ctf/test8.o.abi: Likewise.
	* tests/data/test-read-ctf/test9.o.abi: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR24378-fn-is-not-scope.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise.
	* tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR26261/PR26261-exe.abi: Likewise.
	* tests/data/test-read-dwarf/PR27700/test-PR27700.abi: Likewise.
	* tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR29443-missing-xx.o.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-PR26568-1.o.abi: Likewise.
	* tests/data/test-read-dwarf/test-PR26568-2.o.abi: Likewise.
	* tests/data/test-read-dwarf/test-fallback.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-pointer-to-member-1.o.abi:
	Likewise.
	* tests/data/test-read-dwarf/test-suppressed-alias.o.abi:
	Likewise.
	* tests/data/test-read-dwarf/test0.abi: Likewise.
	* tests/data/test-read-dwarf/test0.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test2.so.abi: Likewise.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test3-alias-1.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-3.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-4.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3.so.abi: Likewise.
	* tests/data/test-read-dwarf/test3.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test4.so.abi: Likewise.
	* tests/data/test-read-dwarf/test4.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test5.o.abi: Likewise.
	* tests/data/test-read-dwarf/test5.o.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test6.so.abi: Likewise.
	* tests/data/test-read-dwarf/test6.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test7.so.abi: Likewise.
	* tests/data/test-read-dwarf/test7.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test15.xml: Likewise.
	* tests/data/test-read-write/test18.xml: Likewise.
	* tests/data/test-read-write/test21.xml: Likewise.
	* tests/data/test-read-write/test24.xml: Likewise.
	* tests/data/test-read-write/test25.xml: Likewise.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Likewise.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-09-03 15:36:40 +02:00
Dodji Seketeli
b6add20f05 dwarf-reader,ir,writer: Better support for static member variables
To support the duality concrete/abstract instance of static data
member variables in DWARF, the reader needed a little bit of an
overhaul.  That overhaul is necessary to self-compare libLLVM.so, from
llvm-libs, in fc37.  Note that that self-compare is done using this
command:

    $ fedabipkgdiff -a--self-compare --from fc37 llvm-libs

So now, with this patch, the IR of a static data member is constructed
only when the concrete instance DIE of the static data member is
encountered.  The abstract instance DIE is then read first, the IR is
built from it, and then the concrete instance DIE is read for
additional attributes that might be needed, like the ELF symbol
attribute.

The patch fixes a number of issues related to static data members
representation in the IR, namely, it puts them all in their own array
in the class_or_union, just like what is done for non-static data
members.  The ABIXML writer is updated to emit static data member from
their new storage.

	* include/abg-ir.h (class_or_union::get_static_data_members):
	Declare new method.
	* src/abg-dwarf-reader.cc (add_or_update_class_type): Do not
	create any IR for the /declaration/ of static data member here.
	Wait for its definition from a concrete instance DIE to create the
	IR for it.
	(build_ir_node_from_die): In the DW_TAG_variable case, if we are
	looking at the concrete instance of a static variable (one that
	has a DW_AT_abstract_origin pointing to a static data member) then
	build the IR from it and add it to its class scope.
	* src/abg-ir-priv.h (class_or_union::priv::static_data_members_):
	Define new data member.
	(class_or_union::priv::priv): Stick the static data members that
	are in class_or_union::priv::data_members_ into
	class_or_union::priv::static_data_members_.
	* src/abg-ir.cc (maybe_adjust_canonical_type): Make sure static
	data members of the canonical type has the same symbols set as the
	data members of the canonicalized type.
	(class_or_union::add_data_member): Update the new
	class_or_union::priv::static_data_members_ when a data member is
	added.
	(class_or_union::get_non_static_data_members): Fix comments.
	(class_or_union::get_static_data_members): Define new member
	functions.
	(set_member_is_static): Update the new
	class_or_union::priv::static_data_members_ when static-ness is
	changed.
	* src/abg-writer.cc (write_decl_in_scope): Support writing pure
	declarations (not types).
	(write_translation_unit): Don't forget to write remaining global
	variables.
	(write_class_decl): Make sure to write static data members first,
	before writing the non-static data members.
	* tests/data/test-abidiff-exit/test-ld-2.28-210.so--ld-2.28-211.so.txt:
	Adjust.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test10.xml: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-08-29 17:15:44 +02:00
Dodji Seketeli
ce31d8ad5d dwarf-reader,reader.cc: Fix function virtuality setting
When setting the virtual-ness of a function (whether it's virtual or
not and its vtable offset), one must set the vtable offset before
setting the is_virtual property because setting the later triggers a
fix-up that uses the former.

It turns out some parts of the code got the order wrong.  To fix that,
this patch introduce a new set_member_function_virtuality that ensures
things are done in the proper order.

SET_member_function_vtable_offset and set_member_function_is_virtual
are now static functions that are used only by the new
set_member_function_virtuality.

	* include/abg-fwd.h (set_member_function_vtable_offset)
	(set_member_function_is_virtual): Remove these function
	declarations.
	(set_member_function_virtuality): Declare new function.
	* include/abg-ir.h (decl_base::get_context_rel): Make this public.
	(set_member_function_is_virtual)
	(set_member_function_vtable_offset): Remove these friend
	declaration for the decl_base class.
	* src/abg-dwarf-reader.cc (finish_member_function_reading): Use
	the new set_member_function_virtuality in lieu of the previous
	set_member_function_is_virtual and
	set_member_function_vtable_offset.
	* src/abg-ir.cc (set_member_function_vtable_offset)
	(set_member_function_is_virtual): Make these functions static.
	(set_member_function_virtuality): Define new functions.
	(class_or_union::add_member_function): Use the new
	set_member_function_virtuality in lieu of
	set_member_function_is_virtual and
	set_member_function_vtable_offset.
	* src/abg-reader.cc (build_class_decl): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-08-29 17:15:44 +02:00
Dodji Seketeli
d181673b57 ir: Fix name setting of a ptr-to-mbr-type
The name of a pointer to member type is currently set at the time of
construction of the type.

This can be problematic because at the time of construction of the
type, the member type might not be yet fully constructed.  That would
result in a name (for the pointer to member type) that is incorrect
and stays incorrect for the lifetime of the ptr-to-mbr-type.

To be correct, the name of the pointer to member type must always
reflect the current state of the member and containing types.

This patch does just that.

The patch turns decl_base::get_name into a virtual member function.
It then creates a ptr_to_mbr_type::get_name virtual member function
that dynamically overloads decl_base::get_name.  Then,
ptr_to_mbr_type::get_name just builds and returns the qualified name
of the pointer to member type.

	* include/abg-ir.h (decl_base::{g,s}et_name): Make these member
	functions virtual.
	(ptr_to_mbr_type::get_name): Add new virtual overload.
	* src/abg-ir.cc (ptr_to_mbr_type::ptr_to_mbr_type): Do not set the
	name of the type here.  Just say that it's not anonymous.
	(ptr_to_mbr_type::get_name): Define new (virtual) member function.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-08-29 17:15:43 +02:00
Dodji Seketeli
217ba7fdb8 dwarf-reader: Avoid duplicating anonymous member types
Sometimes, anonymous member types are duplicated in some classes read
by the DWARF reader.  This is because the DWARF reader doesn't lookup
anonymous member types in their class scope before adding them into
their scope.

This patch teaches the DWARF reader how to name an anonymous class,
union or enum by using its flat pretty representation, e.g:

    struct {int blah; char meh;}

That flat representation is used as the name of the anonymous type to
look it up in a given class scope before adding it to that scope.  If
the scope already contains the type, then the type is not added.

Now that class scopes have their proper anonymous member types, it
appeared that the filtering of change reports needed a number of
adaptations because we are now seeing things that we were not seeing
before.  For instance two new change categories
NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY and
NON_COMPATIBLE_NAME_CHANGE_CATEGORY are added.  The former is for a
change where a given type becomes another type of a different kind in
an non-compatible way.  For instance, a struct type becomes an enum
type.  The later category is for a change in a name of the type,
resulting in a non-compatible change.  Thus, new non-compatible
changes can now be categorized and reported as such.

	* include/abg-comp-filter.h (has_void_ptr_to_ptr_change)
	(has_harmless_enum_to_int_change)
	(has_benign_array_of_unknown_size_change): Declare new functions.
	* include/abg-comparison.h (enum diff_category): Add
	NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY,
	NON_COMPATIBLE_NAME_CHANGE_CATEGORY enumerators.  Update the other
	enumerator values.  Also, update the EVERYTHING_CATEGORY
	enumerator value.
	* include/abg-ir.h (class_decl::find_base_class): Document the
	name of the parameter.
	* src/abg-comp-filter.cc (type_diff_has_cv_qual_change_only)
	(is_non_compatible_distinct_change, is_void_ptr_to_ptr): Define
	new static functions.
	(has_subtype_changes): Remove static function.
	(class_diff_has_only_harmless_changes): Do not bother checking if
	the class_diff has subtype changes.  If there are, the category of
	those changes is going to be propagated upward to this current
	diff node.  Update the comments.
	(has_harmless_name_change): A diff node carrying compatible types
	or types that differ only from their CV qualifiers should qualify
	as having a harmless name change.
	(has_harmless_enum_to_int_change): Make this function be
	non-static.
	(type_diff_has_cv_qual_change_only): Introduce an overload that
	takes two ABI artifacts instead of one diff node.  Make the diff
	node overload use the new one.  Simplify logic by essentially
	peeling off qualified or typedefs first.  Then if what remain is
	pointer or array types, look at their underlying types.  If the
	remaining underlying types are equal then return true.
	(has_void_ptr_to_ptr_change): Use the new is_void_ptr_to_ptr
	function.  This allows the function to detect void* -> pointer and
	pointer -> void* changes.  And it simplifies the logic.
	* src/abg-comparison.cc (distinct_diff::compatible_child_diff):
	Build a compatible child diff node iff the two diff subject are
	actually compatible meaning, they are equal modulo a typedef.
	(get_default_harmful_categories_bitmap): Add the new
	abigail::comparison::{NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY,NON_COMPATIBLE_NAME_CHANGE_CATEGORY}
	enumerators to the bitmap of harmful categories.
	(operator<<(ostream& o, diff_category c)): Update this to support
	emitting the new
	abigail::comparison::{NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY,NON_COMPATIBLE_NAME_CHANGE_CATEGORY}
	enumerators.
	(class_or_union_diff::priv::count_filtered_{subtype_}changed_dm):
	Fix logic for counting local changes.
	diff::has_local_changes_to_be_reported is not reliable so do not
	rely on it.  We might want to remove that function in the end.
	(category_propagation_visitor::visit_end): If the current diff
	node has a harmless void pointer to pointer, enum to int, or a
	benign array of unknown size change, do not propagate the
	NON_COMPATIBLE_{NAME,DISTINCT}_CHANGE_CATEGORY that have
	necessarily bubbled up from some of their distant children nodes.
	* src/abg-dwarf-reader.cc
	(maybe_set_member_type_access_specifier)
	(get_next_member_sibling_die): Declare this pre-existing static
	function.
	(get_internal_anonymous_die_name)
	(lookup_class_typedef_or_enum_type_from_corpus)
	(lookup_class_typedef_or_enum_type_from_corpus): Remove.
	(die_return_and_parm_names_from_fn_type_die): Add is_method_type
	and return_type_name parameters. Fix the representation of member
	functions.
	(die_function_signature): Add qualified_name parameter. Adjust
	call to die_return_and_parm_names_from_fn_type_die.
	(die_type_name, die_enum_flat_representation)
	(die_class_flat_representation)
	(die_class_or_enum_flat_representation): Define new static
	functions.
	(reader::get_die_qualified_type_name, die_qualified_type_name):
	For anonymous class or enum types, use the new
	die_class_or_enum_flat_representation.  Adjust the call to
	die_return_and_parm_names_from_fn_type_die. For function types fix
	the name representation.
	(die_pretty_print_type): Adjust call to
	die_return_and_parm_names_from_fn_type_die.
	(die_pretty_print_decl): Take qualified_name and include_fns
	parameters.  Use the new die_type_name for variable type names.
	Adjust call to die_function_signature.
	(die_pretty_print): Adjust call die_pretty_print_decl.
	(get_member_child_die): Remove useless vertical space.
	(build_enum_underlying_type): Sort this enum underlying type (and
	potentially hash it) before canonicalizing it.
	(add_or_update_class_type): If an anonymous type is in the global
	scope, take that into account when building its internal anonymous
	die name.  Lookup anonymous member types before adding them to the
	class scope to avoid duplicating them in their scope.
	(add_or_update_union_type): Likewise, lookup anonymous member
	types before adding them to the union scope to avoid duplicating
	them in their scope.
	(build_subranges_from_array_type_die): Const-ify the input reader.
	Adjust call to build_ir_node_from_die.  Associate the subrange DIE
	to the IR node built.
	(build_ir_node_from_die): Get the current corpus from the reader
	because it might be set for scope passed to this function, or the
	scope might be nullptr.  Schedule base types for canonicalization
	like all the other types.  Also, lookup all class/union types
	before adding them to their class scope.
	* src/abg-leaf-reporter.cc (leaf_reporter::report): In the
	overload for class_or_union_diff, report changed data members and
	their sub-types.
	* tests/Makefile.am: Do not XFAIL the test runtestabidiffexit.  No
	more tests are XFAILED.  All tests should now pass.
	* tests/data/test-abidiff-exit/PR30503/libsdl/libsdl-1.2.60-1.2.64-report.txt:
	Adjust.
	* tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/qualifier-typedef-array-report-1.txt:
	Likewise.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test0.abi: Likewise.
	* tests/data/test-annotate/test1.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-dwarf/PR25058-liblttng-ctl-report-1.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test4-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test5-report.txt: Likewise.
	* tests/data/test-diff-filter/test-PR26739-2-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test41-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test5-report.txt: Likewise.
	* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
	Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR24378-fn-is-not-scope.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test0.abi: Likewise.
	* tests/data/test-read-dwarf/test0.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-08-29 17:15:43 +02:00
Dodji Seketeli
2ebe28b77e ir: Cache the result of scope_decl::get_sorted_member_types
Speed up ABIXML emitting by caching the result of
scope_decl::get_sorted_member_types when it's called on a
canonicalized type.

	* include/abg-ir.h
	(environment::canonicalization_started): Define new member
	functions.
	* src/abg-ir-priv.h
	(environment::priv::canonicalization_started_): Define new data
	member.
	(canonicalize_types): Call
	environment::canonicalization_started(true) right before starting
	type canonicalization and call
	environment::canonicalization_started(false) right after type
	canonicalization is done.
	* src/abg-ir.cc (environment::canonicalization_started): Define
	new methods.
	(environment::canonicalization_is_done): Set the
	new canonicalization_started flag to false when the
	canonicalization is done.
	(scope_decl::priv::clear_sorted_member_types_cache_): Declare new
	data member.
	(scope_decl::{add_member_decl, insert_member_type}): If we are
	adding a type to the scope, then flag the scope as needing to
	clear the sorted member types cache.
	(scope_decl::get_sorted_member_types): If type canonicalization is
	not yet started, then the sorted member types cache needs to be
	cleared.  If the sorted member types cache is to be cleared, then
	clear it.  If the cache is empty, fill it.  Then return the
	content of the cache.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-08-29 17:15:43 +02:00
Dodji Seketeli
d18ff748d7 comp-filter: Consider lvalue-ness changes on references as harmful
This patch detects an lvalue-ness change on a reference type,
categorizes it as REFERENCE_LVALUENESS_CHANGE_CATEGORY and considers
it as harmful by default.

Note that this patch fixes the parts of runtestdifffilter that have to
do with lvalue-ness changes to reference types, but there is still one
test failing from the testsuite: runtestabidiffexit.  This test has
been XFAILed in the test suite.

	* include/abg-comparison.h (enum diff_category): Add the new
	REFERENCE_LVALUENESS_CHANGE_CATEGORY enumerator.  Adjust the value
	of the other enumerators.
	* src/abg-comparison.cc (get_default_harmful_categories_bitmap):
	Consider the new REFERENCE_LVALUENESS_CHANGE_CATEGORY as being
	part of the default harmful categories bitmap.
	(operator<<(ostream& o, diff_category c)): Support the new
	REFERENCE_LVALUENESS_CHANGE_CATEGORY for me.
	* include/abg-comp-filter.h (has_lvalue_reference_ness_change):
	Declare new function.
	* src/abg-comp-filter.cc (has_lvalue_reference_ness_change):
	Define new function.
	(categorize_harmful_diff_node): Use the new
	has_lvalue_reference_ness_change to set the new
	REFERENCE_LVALUENESS_CHANGE_CATEGORY.
	* tests/Makefile.am: XFAIL runtestabidiffexit.
	* tests/data/test-diff-filter/test3-report.txt: Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test47-filter-void-ptr-change-report-0.txt:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-08-29 17:15:43 +02:00
Dodji Seketeli
1b1b8399d1 ir: Remove the now useless type propagation optimization
Now that the type hashing patch is in, I figure we can do away with
the overly complicated type propagation optimization.  The type
propagating optimization is disabled by the type hashing patch anyway
so this is overdue now.

The nice thing about this is that we are dropping a big complicated
code with no noticeable speed penalty \o/

	* configure.ac: Remove the now useless --enable-ct-propagation
	option.
	* include/abg-ir.h (environment::do_on_the_fly_canonicalization):
	Remove member function declaration.
	* src/abg-ir-priv.h (type_base::priv::{depends_on_recursive_type_,
	canonical_type_propagated_,
	propagated_canonical_type_confirmed_}): Remove data members.
	(type_base::priv::priv): Update.
	(type_base::priv::{depends_on_recursive_type,
	set_depends_on_recursive_type,
	set_does_not_depend_on_recursive_type, canonical_type_propagated,
	set_canonical_type_propagated,
	propagated_canonical_type_confirmed,
	set_propagated_canonical_type_confirmed,
	clear_propagated_canonical_type}): Remove member functions.
	(environment::priv::{types_with_non_confirmed_propagated_ct_,
	recursive_types_, types_with_cleared_propagated_ct_,
	do_on_the_fly_canonicalization_}): Remove data members.
	(environment::priv::priv): Adjust.
	(environment::priv::{mark_dependant_types,
	mark_dependant_types_compared_until}): Update comment.
	(environment::priv::{mark_dependant_types,
	mark_dependant_types_compared_until, is_recursive_type,
	propagate_ct, confirm_ct_propagation_for_types_dependant_on,
	confirm_ct_propagation, confirm_ct_propagation,
	types_with_cleared_propagated_ct,
	types_with_cleared_propagated_ct,
	record_type_with_cleared_propagated_canonical_type,
	erase_type_with_cleared_propagated_canonical_type,
	collect_types_that_depends_on,
	cancel_ct_propagation_for_types_dependant_on,
	cancel_ct_propagation, clear_propagated_canonical_type,
	add_to_types_with_non_confirmed_propagated_ct,
	remove_from_types_with_non_confirmed_propagated_ct,
	cancel_all_non_confirmed_propagated_canonical_types}): Remove.
	(canonicalize_types): Remove canonical type propagation debugging
	code.
	* src/abg-ir.cc (mark_dependant_types_compared_until): Remove function.
	(RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED): Adjust, do not use the
	removed mark_dependant_types_compared_until.
	(return_comparison_result): Remove handling of the canonical type
	propagation optimization.
	(environment::do_on_the_fly_canonicalization): Remove member
	functions.
	(maybe_propagate_canonical_type, maybe_propagate_canonical_type)
	(maybe_cancel_propagated_canonical_type, ): Remove functions.
	(compare_canonical_type_against_candidate, canonicalize): Remove
	handling of the canonical type propagation optimization.
	(equals): In the overload for class_or_union, adjust call to
	return_comparison_result.  In the overload for class_decl, remove
	call to maybe_cancel_propagated_canonical_type.
	(OnTheFlyCanonicalization): Remove this doxygen documentation
	module describing the canonical type propagation optimization.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-08-29 17:15:43 +02:00
Dodji Seketeli
ccc71fc0e0 Implement type hashing
The order in which types of the same name & kind (aka homonym types)
are canonicalized does have an impact on the final canonicalization
result.  This variation is at the root of the self-comparison error
happening on the gcc-gnat package in f37.  The command to reproduce
the issue is:

	$ fedabipkgdiff  -a --self-compare --from fc37 gcc-gnat

Note that the binary on which self-comparison is failing is gnat1 for
the s390 arch:

    $ pwd
    ~/git/libabigail/hash-types/prtests/extracts/gcc-gnat-12.3.1-1.fc37.s390x
    $
    $ abidw --debug-abidiff -d usr/lib/debug usr/libexec/gcc/s390x-redhat-linux/12/gnat1

That test is still failing with this patch, but is going to pass with
subsequent patches in the series.

Having persistent hashes that can be serialized along with the types
into ABIXML does help to suppress that variation.

This patch implements that idea.

Learning from the teachings of the DWZ tool, the patch uses the xxhash
algorithm for primitive hashing and hash combination.  The patch
prevents cycling while hashing type graphs by maintaining a hashing
state in objects being hashed, just like what DWZ does.

The patch cleans out the relics of the previous (failed) attempt of
using hashing in the IR.  Now, a virtual
type_or_decl_base::hash_value() is declared and implemented by
decl_base, type_base and descendants of type_base.

Each IR node has a "private" hashing function that knows how to hash
the specific parts of the IR node and combine the hashes of its
sub-type IR children nodes to come up with a hashing value for the
whole IR node, while preventing cycling.  There are some subtleties
introduced during the hashing.  For instance, a typedef hash is the
same as the hash of its underlying type.  This helps the hash value of
a pointer or reference to a typedef of class to be the same as the
hash value of a pointer or reference to the class.  Another subtlety
is to never hash the declaration of a class, if a definition is
present; rather, always hash the definition.  In general, types that
are not canonicalized (for which is_non_canonicalized_type returns
true) are not hashed.

That private hashing function is thus used by the ::hash_value()
of the IR node to compute the hash value for the first time and cache
it for it subsequent invocations.

After building the IR, the patch first sorts all types, then hashes
them and then canonicalizes them.  During the canonicalization phase,
two types with different hashes are deemed different.  Two types with
the same hash are compared structurally.

During ABIXML de-serialization, libabigail reads the hash value back
from each IR node and uses that instead of re-calculating the hash.

Note that calculating the hash of a node read from ABIXML could lead
to a different result than calculating the hash for the same node from
DWARF, because the order in which hashes are calculated counts,
especially for recursive types.  That is one of the reasons why hashes
are not re-calculated when reading from abixml.

In all fairness, I think we would need to test this hypothesis again,
because we now sort types before hashing them, so in theory, the
hashing should yield the same result as when done from ELF.
Regardless, just reading the hash values from ABIXML is faster than
re-calculating it.  We might want to re-calculate the hashes for
debugging purposes, however.  This is left as an exercise for the
astute reader of this patch.

If the hash of an ABIXML node equals the hash of an ELF node, then
during type canonicalization, the two nodes are compared structurally.
If the hashes are different, then the nodes compare different during
canonicalization.  That speeds up canonicalization at ABIXML reading
time.  But this implies that each change in a hashing scheme should
result in a change in the major ABIXML version number, rendering newer
ABIXML files incompatible with previous ones.  It even makes them
incompatible with newer libabigail code altogether.  In that case, we
might want to teach abidiff about ABIXML versioning, even when
comparing an ABIXML input against an ELF one.

Note that the patch uses the hashing during type canonicalization in
general; that is, if the hashes are present and different, then the
types are different.  That helps to do away with the need for the
"canonical type propagation" optimization that I suspect is causing
issues on redundant types.

It turns out that not using that optimization doesn't incur any
noticeable speed penalty so in a subsequent patch, that canonical type
propagation optimization code is going to be entirely removed.

The patch uses an optional value for hashes, to make the difference
between no-hash (for recursive sub-types and types supposed to have no
hash/canonical types) and a hash value of zero which is a valid hash
value.

Note that the patch emits hashes for function-decl elements.  This is
the hash of the type of the function.  When parsing ABIXML, the reader
sets that function-decl hash to the function_type built from it.

Also, note that for types having the same representation (homonym
types) and yet are canonically different, this patch emits a distinct
canonical type index (aka CTI).  That CTI is appended to the hash
value, following a "#" sign.

Later, during type canonicalization, two homonym types T and T' (where
T originates from ELF and T' originates from ABIXML) having the same
hash and CTI will be structurally compared.  If T equals T', then T
and T' will be considered canonically equivalent.  In other words,
CTIs help to match homonym types originating from ABIXML against
homonym types originating from ELF.

Note that 2 tests are still failing. They are fall-outs that are
addressed in subsequent patches.  This patch XFAIL them until they get
fixed by subsequent patches of the series.

	* configure.ac: Bump ABIXML version to 4.0.  Detect the new xxhash
	dependency and require the 0.8.0 version at minimum.
	* include/abg-fwd.h (look_through_decl_only_type): Declare new
	functions.
	(is_scope_decl): Const-ify the parameter and
	the returned value.  Also, do not include "abg-hash.h" here.
	* include/abg-hash.h: Make this include cstdint (for uint64_t) and
	abg-ir.h, instead of stdint.h.
	(enum hashing_state): Define new enum in the abigail::hashing
	namespace.
	(combine_hashes, fnv_has, hash, get_hashing_state)
	(set_hashing_state, is_recursive_artefact): Declare new functions
	in the abigail::hashing namespace.
	(struct {decl_base, type_base, type_decl, qualified_type_def,
	pointer_type_def, reference_type_def, ptr_to_mbr_type,
	array_type_def, enum_type_decl, typedef_decl, function_type,
	method_type, member_base, class_or_union, class_decl::base_spec,
	class_decl, union_decl}::hash): Declare new hash functors in the
	abigail::ir namespace.
	* include/abg-ir.h: Remove the inclusion of abg-hash.h from this
	header.
	(typedef hash_t): Define new type.
	(peek_hash_value): Declare new function.
	(get_canonical_types): Return a pointer to const vector.
	({type_or_decl_base, type_base, qualified_type_def,
	pointer_type_def, reference_type_def, ptr_to_mbr_type,
	array_type_def::subrange_type, typedef_decl, function_type,
	method_type, class_or_union, class_decl, class_decl::base_spec,
	union_decl}::hash_value): Add new virtual member functions.
	(type_or_decl_base::set_hash_value): Add new member function.
	(type_or_decl_base::priv_): Make this data member public.
	(peek_hash_value, set_or_get_cached_hash_value): Declare these
	functions as friends of class type_or_decl_base.
	({decl_base, scope_decl, var_decl, function_decl,
	function_decl::parameter}::get_hash): Remove member functions.
	* src/abg-comparison-priv.h (types_or_decls_hash::operator()):
	Adjust to using the new hash_t type.
	* src/abg-ctf-reader.cc
	(reader::{additional_types_to_canonicalize, types}): Add new data
	members.
	(reader::add_type(): Add new member function.
	(reader::canonicalize_all_types): Use the new types vector data
	member to stash types to be canonicalized and pass them to
	ir::hash_and_canonicalize_types for canonicalization.
	(process_ctf_base_type)
	(build_ir_node_for_variadic_parameter_type)
	(build_ir_node_for_void_type, build_ir_node_for_void_pointer_type)
	(build_array_ctf_range, process_ctf_enum_type): Do not use
	canonicalize anymore.  Rather, rely on reader::add_type to
	schedule types for canonicalization, doing the generic sorting and
	hashing before doing the actually canonicalization.
	* src/abg-dwarf-reader.cc ({dwarf_offset_pair_hash,offset_hash,
	offset_pair_hash}::operator()): Use the new hashing function.
	(reader::read_debug_info_into_corpus): Improve logging.  Use
	ir::hash_and_canonicalize_types in lieu of ir::canonicalize_types.
	(reader::types_to_canonicalize): Add
	non-const overload.
	(reader::canonicalize_types_scheduled): Add better logs & misc
	obvious cleanup.
	(maybe_canonicalize_type): Force scheduling canonicalization of
	all types at the end of the DWARF processing.
	* src/abg-hash.cc (combine_hashes, hash, get_hashing_state)
	(set_hashing_state, is_recursive_artefact): Define new functions.
	(MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES)
	(MAYBE_FLAG_TYPE_AS_RECURSIVE)
	(MAYBE_RETURN_EARLY_IF_HASH_EXISTS): Define new macros.
	(struct {decl_base, type_base, type_decl, qualified_type_def,
	pointer_type_def, reference_type_def, ptr_to_mbr_type,
	array_type_def, ptr_to_mbr_type, enum_type_decl, typedef_decl,
	function_decl, function_type, method_type, member_base,
	class_or_union, class_decl::base_spec, class_decl,
	union_decl}:#️⃣:operator): Define new hash functors.
	({template_parameter, template_decl, non_type_tparameter,
	template_tparameter, type_composition, type_composition,
	function_tdecl}::{hash, dynamic_hash, shared_ptr_hash): Remove.
	* src/abg-ir-priv.h: Don't include abg-ir.h anymore, rather
	include abg-hash.h.
	(struct type_or_decl_base::priv): Move this here, from abg-ir.cc.
	(type_or_decl_base::priv::{hashing_state_, hash_value_,
	is_recursive_artefact_}): Define new data members.
	(type_or_decl_base::priv::{get_hashing_state, set_hashing_state,
	set_hash_value, force_set_hash_value, is_recursive_artefact}):
	Define new member functions.
	(struct sort_for_hash_functor): Define new functor.
	(do_hash_value, set_or_get_cached_hash_value)
	(hash_and_canonicalize_types, sort_and_canonicalize_types): Define
	new function templates.
	(type_is_suitable_for_hash_computing)
	(sort_types_for_hash_computing_and_c14n)
	(get_canonical_type_index, get_decl_name_for_comparison): Declare
	new functions.
	(type_base::priv::canonical_type_index): New data member.
	(type_base::priv::{priv, clear_propagated_canonical_type}):
	Initialize it.
	(uint64_t_pair_hash::operator()): Adjust.
	(environment::priv::number_of_canonical_types): New data member.
	(environment::priv::priv): Initialize it.
	(environment::priv::get_new_canonical_type_index): New member
	function.
	(environment::priv::propagate_ct): Propagate the CTI too.
	(environment::priv::{confirm_ct_propagation_for_types_dependant_on,
	confirm_ct_propagation}): Assert that canonical type has been
	propagated and thus we have a canonical type.
	(struct type_topo_comp::operator()): Beef up sorting of types.
	Take into account the absolute path of the TU, the hash value, the
	CTI)
	(struct sort_for_hash_functor): Define new functor.
	(sort_types_for_hash_computing_and_c14n): Declare new function
	template and new overload.
	(canonicalize_types): Take new do_log and show_stats parameters.
	Improve logging.  Do not sort types in here.
	(hash_and_canonicalize_types): Define new function template.  This
	one does the sorting before the hashing and the canonicalization.
	(sort_and_canonicalize_types): Likewise, but this one does no
	hashing.
	(cache_type_comparison_result): Cache the result of the comparison
	now, unconditionally.  As we don't do canonical type propagation
	anymore, we should not get canonical types and equality to
	disagree anymore.
	(* src/abg-ir.cc (try_canonical_compare): If hash values are
	present and different then the two types are different.
	(environment::get_canonical_types): Constify return value.
	(environment::get_canonical_type): Adjust.
	(struct type_or_decl_base::priv): Move this to abg-ir-priv.h.
	(type_or_decl_base::hashing_started): Remove.
	({decl_base, scope_decl, var_decl, function_decl,
	function_decl::parameter, class_decl::base_spec,
	non_type_tparameter, type_composition}::get_hash): Likewise.
	({template_parameter}::get_hashing_has_started)
	(template_parameter::set_hashing_has_started): Likewise.
	(type_or_decl_base::{hash_value, set_hash_value})
	({type_base, type_decl, qualified_type_def, pointer_type_def,
	reference_type_def, ptr_to_mbr_type,
	array_type_def::subrange_type, array_type_def, enum_type_decl,
	typedef_decl, function_type, method_type, class_or_union,
	class_decl::base_spec, class_decl, union_decl}::hash_value):
	Define new member functions.
	(type_or_decl_base::set_hash_value): Likewise.
	(get_decl_name_for_comparison): Make this non-static.
	(is_scope_decl): Constify.
	(type_is_suitable_for_hash_computing)
	(peek_hash_value, read_type_hash, read_hash_and_stash)
	(look_through_decl_only_type)
	(candidate_matches_a_canonical_type_hash)
	(sort_types_for_hash_computing_and_c14n): Define new functions.
	(lookup_pointer_type, lookup_reference_type)
	(pointer_type_def::get_qualified_name)
	(reference_type_def::get_qualified_name)
	(reference_type_def::get_pretty_representation): Adjust.
	(get_type_name):  Better handle naming of anonymous type decls,
	used for enums.
	(get_debug_representation): Adjust to emit hashes & CTI of types
	as well as member types while debugging.
	(look_through_decl_only_type): Rename look_through_decl_only into
	this.
	(lookup_pointer_type, lookup_reference_type)
	(reference_type_def::get_qualified_name): Adjust.
	(compare_canonical_type_against_candidate): Stop doing canonical
	type propagation during type canonicalization.
	(type_base::get_canonical_type_for): Use the new
	candidate_matches_a_canonical_type_hash.  Set the canonical type
	index for homophone canonical types.  In debug mode, check that if
	a type equals a canonical type, their hash value must match.
	(canonicalize): Take new do_log and show_stats parameter.  Improve
	logging.  Also, a type must have the same CTI as its canonical
	type.
	(hash_type_or_decl): Adjust to use the new type
	hash_t.
	(type_topo_comp::operator()): Add an overload for type_base_wptr.
	If the two pointers are equal, get out early.  Otherwise, if
	everything else is equal, sort using the absolute path of the
	containing translation unit.
	(maybe_propagate_canonical_type): Propagate canonical type only if
	their CTI match.
	* src/abg-reader.cc (maybe_canonicalize_type): Improve logging.
	Schedule all types for late canonicalization.
	(reader::perform_type_canonicalization): Improve logging.  Call
	hash_and_canonicalize_types to hash and canonicalize types.
	(read_type_hash_and_cti, read_hash_and_stash): Define new static
	functions.
	(build_function_decl, build_type_decl)
	(build_qualified_type_decl)
	(build_pointer_type_def, build_reference_type_def)
	(build_ptr_to_mbr_type, build_function_type, build_subrange_type)
	(build_array_type_def, build_enum_type_decl, build_typedef_decl)
	(build_class_decl, build_union_decl): Read and set the hash value
	from ABIXML.
	(build_function_decl, build_qualified_type_decl)
	(build_pointer_type_def, build_reference_type_def)
	(build_function_type, build_subrange_type, build_array_type_def)
	(build_enum_type_decl, build_typedef_decl, build_class_decl)
	(build_union_decl): Read the hash and CTI and set them to the
	type.
	(build_reference_type_def): Build the referenced type before-hand.
	(build_class_tdecl, build_type_tparameter, build_type_composition)
	(build_template_tparameter, build_type, handle_type_decl)
	(handle_qualified_type_decl, handle_pointer_type_def)
	(handle_reference_type_def, handle_function_type)
	(handle_array_type_def, handle_enum_type_decl)
	(handle_typedef_decl, handle_class_decl, handle_union_decl):
	Adjust to the use of the new maybe_canonicalize_type signature.
	* src/abg-btf-reader.cc (reader::canonicalize_types): Use the new
	hash_and_canonicalize_types defined above.  Log the time taken by
	type canonicalization.
	* src/abg-ctf-reader.cc (reader::{types,
	additional_types_to_canonicalize}): New data members
	(reader::add_types): New member functions.
	(reader::canonicalize_all_types): Use the new
	hash_and_canonicalize_types defined above.
	(process_ctf_base_type): Do not call canonicalize here.
	(build_ir_node_for_variadic_parameter_type)
	(build_ir_node_for_void_type)
	(build_ir_node_for_void_pointer_type, process_ctf_enum_type):
	Likewise, and call reader::add_type instead.
	* src/abg-dwarf-reader.cc ({dwarf_offset_pair_hash, offset_hash,
	offset_pair_hash}::operator()): Adjust to using the new hash_t
	type.
	(reader::canonicalize_types_scheduled): Use the new
	hash_and_canonicalize_types above.
	(maybe_canonicalize_type): Schedule all types for late
	canonicalization.
	* src/abg-writer.cc (reader::get_id_for_type): Constify the
	parameter.
	(write_type_hash_and_cti, write_common_type_info)
	(write_fn_parm_and_return_types): Define new static functions.
	(write_type_decl, write_qualified_type_def)
	(write_pointer_type_def, write_reference_type_def)
	(write_array_subrange_type, write_array_type_def)
	(write_enum_type_decl, write_typedef_decl, write_function_decl)
	(write_function_type, write_class_decl_opening_tag)
	(write_union_decl_opening_tag): Emit hash value and CTI to the
	ABIXML.
	* tests/Makefile.am: XFAIL the tests runtestdifffilter and
	runtestabidiffexit for now.
	* tests/data/test-abidiff-exit/PR30329/PR30329-report-1.txt:
	Adjust.
	* tests/data/test-annotate/PR29443-missing-xx.o.annotated.abi:
	Likewise.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test-anonymous-members-0.o.abi:
	Likewise.
	* tests/data/test-annotate/test-pointer-to-member-1.o.annotated.abi:
	Likewise.
	* tests/data/test-annotate/test0.abi: Likewise.
	* tests/data/test-annotate/test1.abi: Likewise.
	* tests/data/test-annotate/test13-pr18894.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test2.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-annotate/test3.so.abi: Likewise.
	* tests/data/test-annotate/test4.so.abi: Likewise.
	* tests/data/test-annotate/test5.o.abi: Likewise.
	* tests/data/test-annotate/test6.so.abi: Likewise.
	* tests/data/test-annotate/test7.so.abi: Likewise.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Likewise.
	* tests/data/test-diff-filter/test-PR26739-2-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test3-report.txt: Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test43-decl-only-def-change-leaf-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg-ctf/gmp-6.x.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt:
	Likewise.
	* tests/data/test-read-btf/test0.o.abi: Likewise.
	* tests/data/test-read-btf/test1.o.abi: Likewise.
	* tests/data/test-read-ctf/PR27700/test-PR27700.abi: Likewise.
	* tests/data/test-read-ctf/test-PR26568-1.o.abi: Likewise.
	* tests/data/test-read-ctf/test-PR26568-2.o.abi: Likewise.
	* tests/data/test-read-ctf/test-alias.o.abi: Likewise.
	* tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi:
	Likewise.
	* tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi:
	Likewise.
	* tests/data/test-read-ctf/test-anonymous-fields.o.abi: Likewise.
	* tests/data/test-read-ctf/test-array-mdimension.abi: Likewise.
	* tests/data/test-read-ctf/test-array-of-pointers.abi: Likewise.
	* tests/data/test-read-ctf/test-array-size.abi: Likewise.
	* tests/data/test-read-ctf/test-bitfield-enum.abi: Likewise.
	* tests/data/test-read-ctf/test-bitfield.abi: Likewise.
	* tests/data/test-read-ctf/test-callback.abi: Likewise.
	* tests/data/test-read-ctf/test-callback2.abi: Likewise.
	* tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi:
	Likewise.
	* tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi:
	Likewise.
	* tests/data/test-read-ctf/test-const-array.abi: Likewise.
	* tests/data/test-read-ctf/test-dynamic-array.o.abi: Likewise.
	* tests/data/test-read-ctf/test-enum-many.o.hash.abi: Likewise.
	* tests/data/test-read-ctf/test-enum-symbol.o.hash.abi: Likewise.
	* tests/data/test-read-ctf/test-enum.o.abi: Likewise.
	* tests/data/test-read-ctf/test-fallback.abi: Likewise.
	* tests/data/test-read-ctf/test-forward-type-decl.abi: Likewise.
	* tests/data/test-read-ctf/test-functions-declaration.abi:
	Likewise.
	* tests/data/test-read-ctf/test-linux-module.abi: Likewise.
	* tests/data/test-read-ctf/test-list-struct.abi: Likewise.
	* tests/data/test-read-ctf/test0.abi: Likewise.
	* tests/data/test-read-ctf/test0.hash.abi: Likewise.
	* tests/data/test-read-ctf/test1.so.abi: Likewise.
	* tests/data/test-read-ctf/test1.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test3.so.abi: Likewise.
	* tests/data/test-read-ctf/test3.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test4.so.abi: Likewise.
	* tests/data/test-read-ctf/test4.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test5.o.abi: Likewise.
	* tests/data/test-read-ctf/test7.o.abi: Likewise.
	* tests/data/test-read-ctf/test8.o.abi: Likewise.
	* tests/data/test-read-ctf/test9.o.abi: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR24378-fn-is-not-scope.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise.
	* tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR26261/PR26261-exe.abi: Likewise.
	* tests/data/test-read-dwarf/PR27700/test-PR27700.abi: Likewise.
	* tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR29443-missing-xx.o.abi: Likewise.
	* tests/data/test-read-dwarf/PR29692-kdelibs3-libkjava.so.1.0.0.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-PR26568-1.o.abi: Likewise.
	* tests/data/test-read-dwarf/test-PR26568-2.o.abi: Likewise.
	* tests/data/test-read-dwarf/test-fallback.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-pointer-to-member-1.o.abi:
	Likewise.
	* tests/data/test-read-dwarf/test-suppressed-alias.o.abi:
	Likewise.
	* tests/data/test-read-dwarf/test0.abi: Likewise.
	* tests/data/test-read-dwarf/test0.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test2.so.abi: Likewise.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test3-alias-1.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-3.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-4.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3.so.abi: Likewise.
	* tests/data/test-read-dwarf/test3.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test4.so.abi: Likewise.
	* tests/data/test-read-dwarf/test4.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test5.o.abi: Likewise.
	* tests/data/test-read-dwarf/test5.o.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test6.so.abi: Likewise.
	* tests/data/test-read-dwarf/test6.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test7.so.abi: Likewise.
	* tests/data/test-read-dwarf/test7.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test-crc.xml: Likewise.
	* tests/data/test-read-write/test0.xml: Likewise.
	* tests/data/test-read-write/test1.xml: Likewise.
	* tests/data/test-read-write/test10.xml: Likewise.
	* tests/data/test-read-write/test11.xml: Likewise.
	* tests/data/test-read-write/test12.xml: Likewise.
	* tests/data/test-read-write/test13.xml: Likewise.
	* tests/data/test-read-write/test14.xml: Likewise.
	* tests/data/test-read-write/test15.xml: Likewise.
	* tests/data/test-read-write/test16.xml: Likewise.
	* tests/data/test-read-write/test17.xml: Likewise.
	* tests/data/test-read-write/test18.xml: Likewise.
	* tests/data/test-read-write/test19.xml: Likewise.
	* tests/data/test-read-write/test2.xml: Likewise.
	* tests/data/test-read-write/test20.xml: Likewise.
	* tests/data/test-read-write/test21.xml: Likewise.
	* tests/data/test-read-write/test22.xml: Likewise.
	* tests/data/test-read-write/test23.xml: Likewise.
	* tests/data/test-read-write/test24.xml: Likewise.
	* tests/data/test-read-write/test25.xml: Likewise.
	* tests/data/test-read-write/test26.xml: Likewise.
	* tests/data/test-read-write/test27.xml: Likewise.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Likewise.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Likewise.
	* tests/data/test-read-write/test3.xml: Likewise.
	* tests/data/test-read-write/test4.xml: Likewise.
	* tests/data/test-read-write/test5.xml: Likewise.
	* tests/data/test-read-write/test6.xml: Likewise.
	* tests/data/test-read-write/test7.xml: Likewise.
	* tests/data/test-read-write/test8.xml: Likewise.
	* tests/data/test-read-write/test9.xml: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-08-29 17:15:43 +02:00
Dodji Seketeli
90dae34855 ir: Fix getting the translation unit for an ABI artifact
Sometimes when the current translation unit is not yet set for a given
artifact, we can infer it by getting the translation unit of the scope
of the artifact.  This patch performs that inference when the
translation unit is not yet set for the current artifact.

	* include/abg-fwd.h (get_translation_unit): Take a
	type_or_decl_base parameter, not a decl_base.
	* src/abg-ir.cc (get_translation_unit): Likewise.  If no
	translation has yet been associated with the ABI artifact, get it
	from its scope.
	(type_or_decl_base::get_corpus): Use the new get_translation_unit.
	(maybe_set_translation_unit): Assert that the translation unit is
	non-nil.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-08-14 14:10:33 +02:00
Dodji Seketeli
f68ae8cb36 Use smart pointers for variables exported from the ABI corpus
It turned out that for some applications using the library, being able
to share the variables returned by
libabigail::ir::corpus::lookup_variable is useful.  This patch changes
the API to use shared pointer for variables exported from the ABI
corpus.  For the sake of consistency, we should do the same for
function decls, but given the churn, I thought I'd do it for variables
first and see the impact.  If it's OK then I'll do it for function
decls too.

	* include/abg-comparison.h (string_var_ptr_map): Use a
	var_decl_sptr rather than a var_decl*.
	* include/abg-corpus.h (corpus::{variable, variables_set}):
	Likewise.
	(corpus::lookup_variable): Return a var_decl_sptr not a var_decl*.
	(corpus::exported_decls_builder::maybe_add_var_to_exported_vars):
	Take a var_decl_sptr, not a var_decl*.
	* include/abg-fe-iface.h
	(fe_iface::add_var_to_exported_or_undefined_decls): Likewise.
	* include/abg-ir.h (istring_var_decl_ptr_map_type): Use a
	var_decl_sptr rather than a var_decl*.
	* src/abg-btf-reader.cc (reader::build_ir_node_from_btf_type):
	Adjust call to add_var_to_exported_or_undefined_decls.
	* src/abg-comparison-priv.h (var_comp::operator()()): Add a new
	overload for var_decl_sptr.
	(corpus_diff::priv::{deleted_variable_is_suppressed,
	deleted_variable_is_suppressed}): Take a var_decl_sptr not a
	var_decl*.
	(sort_string_var_ptr_map): Take ...
	* src/abg-comparison.cc (sort_string_var_ptr_map): ... a
	vector<var_decl_sptr> rather than a vector<var_decl*>.
	(corpus_diff::priv::ensure_lookup_tables_populated): Adjust.
	(variable_is_suppressed): Likewise.
	(corpus_diff::priv::{deleted_variable_is_suppressed,
	added_variable_is_suppressed}): Likewise.
	* src/abg-corpus-priv.h (str_var_ptr_map_type)
	(istr_var_ptr_map_type): Use a var_decl_sptr rather than a
	var_decl*.
	(corpus::exported_decls_builder::priv::{add_var_to_map,
	keep_wrt_id_of_vars_to_keep, keep_wrt_regex_of_vars_to_suppress,
	keep_wrt_regex_of_vars_to_keep}): Likewise.
	(corpus::exported_decls_builder::priv::vars): Likewise.
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::maybe_add_var_to_exported_vars):
	Likewise.
	(var_comp::operator()()): Add an overload for var_decl_sptr.
	(corpus::lookup_variable): Return var_decl_sptr rather than
	var_decl*.
	* src/abg-ctf-reader.cc (reader::process_ctf_archive): Adjust.
	* src/abg-dwarf-reader.cc (build_ir_node_from_die): Adjust.
	* src/abg-fe-iface.cc
	(fe_iface::add_var_to_exported_or_undefined_decls): Take a
	var_decl_sptr rather than a var_decl*.
	* src/abg-reader.cc (build_class_decl, handle_var_decl): Adjust.
	* src/abg-writer.cc (write_translation_unit): Likewise.
	* tools/abicompat.cc (var_change::decl, var_change::var_change):
	Likewise.
	(compare_expected_against_provided_variables): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-08-14 14:05:54 +02:00
Dodji Seketeli
5fb6df40ea abidw: Support the --abidiff option for Linux Kernel trees
It turned out abidw --abidiff (self-comparison) doesn't work when
analyzing a Linux Kernel tree.  In other words, abidw cannot
self-compare a Linux Kernel tree.  Embarrassing.  Fixed thus.

	* include/abg-corpus.h (is_corpus_group): Declare ...
	* src/abg-corpus.cc (is_corpus_group): ... new function.
	* src/abg-ctf-reader.cc (create_reader): Support --debug-abidiff
	when the package is configured with --enable-debug-self-comparison.
	* tools/abidw.cc (load_corpus_and_write_abixml): Factorize self
	comparison code out into ...
	(perform_self_comparison): ... this.
	(load_kernel_corpus_group_and_write_abixml): Use the new
	perform_self_comparison to perform self comparison when the
	--abidiff option is provided.  Also, support --debug-abidiff when
	the package is configured with --enable-debug-self-comparison.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-07-16 12:53:30 +02:00
Dodji Seketeli
86a1a1168e ir,comparison,default-reporter: Consider sub-ranges in array diffs
It appears that the comparison engine does not take changes in the
underlying types of sub-ranges into account when looking for sub-range
changes.

This patch fixes that issue.

Then the patch amends the diff model of array_diff to make it take
into account sub-range diffs as children diff nodes.  Then it updates
redundancy propagation to make sure changes to sub-ranges are always
reported even when they are redundant.  The patch filters out harmless
name changes to integral types, by default.

	* include/abg-comparison.h (array_diff::array_diff): Take a vector
	of sub-range diffs as children diff nodes.
	(array_diff::{subrange_diffs, any_subrange_diff_to_be_reported}):
	Declare new methods.
	(is_anonymous_subrange_diff): Declare new function.
	* src/abg-comp-filter.cc (integral_type_has_harmless_name_change):
	Define new function.
	(has_harmless_name_change): Use the new
	integral_type_has_harmless_name_change.
	* src/abg-comparison-priv.h (array_diff::priv::subrange_diffs_):
	Define new data member.
	* src/abg-comparison.cc (is_anonymous_class_or_union_diff): Fix
	comment.
	(is_anonymous_subrange_diff): Define new function.
	(array_diff::chain_into_hierarchy): Append sub-range diffs as
	children nodes of the array_diff node.
	(array_diff::array_diff): Take a vector of sub-range diffs as
	children diff nodes.
	(array_diff::{subrange_diffs, any_subrange_diff_to_be_reported}):
	Define new methods.
	(array_diff::has_changes): Take sub-range diffs into account.
	(compute_diff): In the overload for array_type_def, compute diffs
	for sub-ranges as part of the diff for array_type_defs.
	(leaf_diff_node_marker_visitor::visit_begin): Do not consider an
	anonymous sub-range diff node as being a leaf diff node to report
	about.
	(redundancy_marking_visitor::visit_end): Report all sub-range diff
	nodes changes; do not propagate their (potential) redundancy to
	their array_diff node parent.
	* src/abg-default-reporter.cc (default_reporter::report): In the
	overload for array_diff, if there is a sub-range change to be
	reported, then report it.
	* src/abg-ir-priv.h (real_type::base_type): Add SIZE_BASE_TYPE,
	SSIZE_BASE_TYPE, BIT_SIZE_BASE_TYPE, SBIT_SIZE_BASE_TYPE,
	ARRAY_SIZE_BASE_TYPE enumerators to this enum.
	* src/abg-ir.cc (parse_base_real_type): Support parsing real type
	names that are __ARRAY_SIZE_TYPE__, sizetype, ssizetype,
	bitsizetype and sbitsizetype.
	(real_type::to_string): Support IZE_BASE_TYPE, SSIZE_BASE_TYPE,
	BIT_SIZE_BASE_TYPE, SBIT_SIZE_BASE_TYPE and ARRAY_SIZE_BASE_TYPE
	enumerators.
	(equals): In the overload for array_type_def::subrange_type,
	compare the underlying types of the sub-ranged.  In the overload
	for array_type_def, consider sub-range changes mismatch as a local
	non-type change.  This is so that changes to sub-ranges don't get
	filtered out because changes to element types are redundant.
	* src/abg-reporter-priv.cc (represent): In the overload for
	subrange_diff, clean up reporting of change of bound values.
	Also, add reports of changes from non-finite to finite size.
	* tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-1.txt:
	Adjust.
	* Tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-2.txt:
	Likewise.
	* tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-2.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test-allow-type-array-v0--v1-report-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test-allow-type-array-v0--v3-report-1.txt:
	Likewise.
	* tests/data/test-abidiff/test-PR27985-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test10-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test11-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-clang-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/PR24430-fold-qualified-array-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test-PR29811-0-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt:
	Likewise.
	* tests/data/test-diff-suppr/test-has-data-member-inserted-at-1-report-1.txt:
	Likewise.
	* tests/data/test-diff-suppr/test-has-strict-flexible-array-data-member-conversion-report-2.txt:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-07-16 12:49:51 +02:00
Dodji Seketeli
a645a7b681 ir: Rename integral_type into real_type
It turns out what we call integral_type in the libabigail IR is
actually a real_type because it includes real types (float and
double).  This patch rights that wrong.

	* include/abg-fwd.h (is_real_type): Declare new function.
	* src/abg-ctf-reader.cc (process_ctf_base_type): Adjust.
	* src/abg-dwarf-reader.cc (die_qualified_type_name)
	(build_type_decl): Adjust.
	* src/abg-ir-priv.h (class real_type): Rename class integral_type
	into this.
	* src/abg-ir.cc (get_internal_real_type_name, operator|)
	(operator&, operator~, operator|=, operator&=)
	(parse_real_type_modifier, parse_base_real_type, parse_real_type)
	(real_type::{real_type, get_base_type, get_modifiers,
	set_modifiers, to_string, operator string()}):
	s/integral_type/real_type.
	(type_decl::{type_decl, get_qualified_name,
	get_pretty_representation}): Adjust.
	(is_real_type): Define new function.
	(is_integral_type): Use the new is_real_type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-07-16 12:45:43 +02:00
Dodji Seketeli
1add2fea50 ir: Cache the pretty representation used during pre-canonicalization type sorting
Profiling showed that during pre-canonicalization types sorting (which
uses type_topo_comp and decl_topo_comp sorting functors) we spend a
lot of time computing the pretty representation of types and decls
invoked from type_topo_comp::operator() and
decl_topo_comp::operator().

This patch thus uses type_base::get_cached_pretty_representation and
introduces a new similar decl_base::get_cached_pretty_representation
to cache the pretty representation of types and decls and re-use that
representation instead of computing it over and over.

Together with the previous patch of this series, the time spent to
analyze a Linux Kernel tree went from ~ 55 minutes to around 1m15s
using a non-optimized build of libabigail.

	* include/abg-ir.h (decl_base::get_cached_pretty_representation):
	Declare new member function.
	* src/abg-ir-priv.h ({type,decl}_topo_comp::operator()): Use
	{type,decl}_base::get_cached_pretty_representation instead of
	get_pretty_representation.:
	* src/abg-ir.cc (decl_base::priv::{internal_cached_repr_,
	cached_repr}): Define new data members.
	(decl_base::get_cached_pretty_representation):
	Define new member function.
	(type_base::get_cached_pretty_representation): Cache pretty
	representation even for non-canonicalized types.  Fix comments.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-06-21 18:43:53 +02:00
Dodji Seketeli
fb92e0a322 dwarf-reader,ir: Improve detection of method types & implicit parms
There is a confusion in the DWARF reader about static member functions
and non-static member functions.  With recent versions of DWARF, a
member function with the DW_AT_object_pointer attribute is known to
have a this-pointer and thus designates a non-static member function.
DWARF emitted by gcc 4.4.x and previous compiler didn't emit the
DW_AT_object_pointer so we need to look at the first parameter of the
member function, make sure it's artificial and pointers to a pointer
to the same class as the class of the current member function.

This patch avoids to confuse static and non-static member functions by
telling apart types of static member functions, non-static member
function and non member functions. This fixes the representation of
several method types and function declaration signatures across the
test suite.

	* include/abg-ir.h (method_type::get_is_for_static_method): Add
	new method.
	* src/abg-dwarf-reader.cc (fn_die_first_parameter_die)
	(member_fn_die_has_this_pointer, die_peel_typedef): Define new
	static functions.
	(die_this_pointer_is_const): Make this support DIEs representing
	const pointers.
	(die_function_type_is_method_type): Use the new
	member_fn_die_has_this_pointer function rather than (wrongly) open
	coding its functionality.  If the (member) function DIE has no
	this pointer DIE and if the function is at class scope, then we
	are looking a static member function.
	(finish_member_function_reading): Use the new
	method::get_is_for_static_method method rather than open-coding
	its functionality.
	* src/abg-ir.cc (method_type::get_is_for_static_method): Define
	new method.
	(type_topo_comp::operator()): In this comparison
	operator for types, if two method types have the same string
	representation then if one method type is for a static method,
	then make the non-static method type come first.
	(function_type::get_first_non_implicit_parm): The first parameter
	of a function can only carry the "this pointer" if it's
	artificial.
	* tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-1.txt:
	Adjust.
	* tests/data/test-abidiff/test-struct1-report.txt: Likewise.
	* tests/data/test-abidiff/test-struct1-v0.cc.bi: Likewise.
	* tests/data/test-abidiff/test-struct1-v1.cc.bi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Likewise.
	* tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test41-report-0.txt: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-05-06 18:32:41 +02:00
Dodji Seketeli
0fb03efa85 Update Copyright for year 2024
* update-copyright.sh: Update the date in this script.  Running
	the script then yields the changes below.
	* include/abg-btf-reader.h: Update copyright year as a result of
	running update-copyright.sh above.
	* include/abg-comp-filter.h: Likewise.
	* include/abg-comparison.h: Likewise.
	* include/abg-config.h: Likewise.
	* include/abg-corpus.h: Likewise.
	* include/abg-ctf-reader.h: Likewise.
	* include/abg-cxx-compat.h: Likewise.
	* include/abg-diff-utils.h: Likewise.
	* include/abg-dwarf-reader.h: Likewise.
	* include/abg-elf-based-reader.h: Likewise.
	* include/abg-elf-reader.h: Likewise.
	* include/abg-fe-iface.h: Likewise.
	* include/abg-fwd.h: Likewise.
	* include/abg-hash.h: Likewise.
	* include/abg-ini.h: Likewise.
	* include/abg-interned-str.h: Likewise.
	* include/abg-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-reader.h: Likewise.
	* include/abg-regex.h: Likewise.
	* include/abg-reporter.h: Likewise.
	* include/abg-sptr-utils.h: Likewise.
	* include/abg-suppression.h: Likewise.
	* include/abg-tools-utils.h: Likewise.
	* include/abg-traverse.h: Likewise.
	* include/abg-viz-common.h: Likewise.
	* include/abg-viz-dot.h: Likewise.
	* include/abg-viz-svg.h: Likewise.
	* include/abg-workers.h: Likewise.
	* include/abg-writer.h: Likewise.
	* src/abg-btf-reader.cc: Likewise.
	* src/abg-comp-filter.cc: Likewise.
	* src/abg-comparison-priv.h: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus-priv.h: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-ctf-reader.cc: Likewise.
	* src/abg-default-reporter.cc: Likewise.
	* src/abg-diff-utils.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-elf-based-reader.cc: Likewise.
	* src/abg-elf-helpers.cc: Likewise.
	* src/abg-elf-helpers.h: Likewise.
	* src/abg-elf-reader.cc: Likewise.
	* src/abg-fe-iface.cc: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ini.cc: Likewise.
	* src/abg-internal.h: Likewise.
	* src/abg-ir-priv.h: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-leaf-reporter.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-regex.cc: Likewise.
	* src/abg-reporter-priv.cc: Likewise.
	* src/abg-reporter-priv.h: Likewise.
	* src/abg-suppression-priv.h: Likewise.
	* src/abg-suppression.cc: Likewise.
	* src/abg-symtab-reader.cc: Likewise.
	* src/abg-symtab-reader.h: Likewise.
	* src/abg-tools-utils.cc: Likewise.
	* src/abg-traverse.cc: Likewise.
	* src/abg-viz-common.cc: Likewise.
	* src/abg-viz-dot.cc: Likewise.
	* src/abg-viz-svg.cc: Likewise.
	* src/abg-workers.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tests/print-diff-tree.cc: Likewise.
	* tests/test-abicompat.cc: Likewise.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-cxx-compat.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-diff2.cc: Likewise.
	* tests/test-dot.cc: Likewise.
	* tests/test-elf-helpers.cc: Likewise.
	* tests/test-ini.cc: Likewise.
	* tests/test-ir-walker.cc: Likewise.
	* tests/test-kmi-whitelist.cc: Likewise.
	* tests/test-lookup-syms.cc: Likewise.
	* tests/test-read-btf.cc: Likewise.
	* tests/test-read-ctf.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tests/test-svg.cc: Likewise.
	* tests/test-symtab-reader.cc: Likewise.
	* tests/test-symtab.cc: Likewise.
	* tests/test-tools-utils.cc: Likewise.
	* tests/test-types-stability.cc: Likewise.
	* tests/test-utils.cc: Likewise.
	* tests/test-utils.h: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.
	* tools/abisym.cc: Likewise.
	* tools/binilint.cc: Likewise.
	* tools/fedabipkgdiff: Likewise.
	* tools/kmidiff.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-04-26 15:29:50 +02:00
Dodji Seketeli
2ce2199cbc {ctf,btf}-reader: Document the namespace for nicer apidoc
The apidoc is not generating any documentation for the libabigail::btf
and libabigail::ctf namespaces.

It turns out I need to add some doxygen comment to the these namespaces
in the source code.  Fixed thus.

	* include/abg-btf-reader.h (namespace btf): Add doxygen comment.
	Just adding it to the *.cc won't cut it, I am not sure why.
	* include/abg-ctf-reader.h (namespace ctf): Likewise.
	* src/abg-btf-reader.cc (namespace btf): Add doxygen comment.
	* src/abg-ctf-reader.cc (namespace ctf): Add doxygen commit.
	(create_reader, reset_reader): Fix doxygen comments.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-04-18 17:53:52 +02:00
Dodji Seketeli
dbae53ec30 Bug 31646: Fix type suppression tactics for webkit2gtk3
By default, using abidw --abidiff on the binary
/usr/lib64/libwebkit2gtk-4.0.so.37 on the ppc64le platform takes more
than 50GB of RAM and ooms on my system.  That is why a number of
suppression specifications have been put in place in the
default.abignore file that is installed by default on the system.
With that suppression specification however, abidw --abidiff hits an
assert and crashes.

That is because the suppression specification rule below is too eager
and thus removes parameters from some function's signature, in the
final internal representation:

    [suppress_type]
      soname_regexp = libwebkit2?gtk-.*\\.so.*
      name_regexp = (^std::.*|WebCore::.*|WebKit::.*)
      drop = true

An example of function signature that got changed (in the IR) because
of this suppression specification is:

This function signature:

    WebKitAuthenticationScheme
    webkit_authentication_request_get_scheme(WebKitAuthenticationRequest*)

becomes (after applying the suppression specification above):

    void
    webkit_authentication_request_get_scheme()

Woops.  That is not good.

To address that problem, this patch changes that suppression
specification to make libabigail transform those types into opaque
types.  An opaque struct, class or enum is essentially a
declaration-only type of the same kind and name.

So the suppression specification above becomes:

    [suppress_type]
      # Drop all standard c++ types on the floor like before.
      soname_regexp = libwebkit2?gtk-.*\\.so.*
      name_regexp = ^std::.*
      drop = true

    [suppress_type]
      # Transform all C++ types in the WebCore and WebKit namespaces into
      # opaque types.  These are essentially internal types of libwebkit2
      # anyway.  This greatly reduces the size of the in-memory working set.
      label = libabigail::OPAQUE_TYPE_LABEL
      soname_regexp = libwebkit2?gtk-.*\\.so.*
      name_regexp = (WebCore::.*|WebKit::.*)
      drop = true

Notice the introduction of the new special label
"libabigail::OPAQUE_TYPE_LABEL".  This new special label is what makes
the suppression engine of libabigail transform a type (that matches
that suppression specification) into an opaque type, rather than
dropping it on the floor.

The patch then adapts the code of the suppression engine to detect
this special label for the purpose of transforming types into opaque
types.  The patch normalizes the use of the term "opaque type" instead
of "private type" that was used previously in the code.

The patch fixes a bug in the code of get_opaque_version_of_type that
prevents this function from working on types with no location
information.

While working on this, I have noticed that the abipkgdiff has a bug
that was making it ignore suppression specifications provided via the
--suppression option.  The patch fixes that.

I have noticed that abipkgdiff --self-check completely ignores all
suppression specifications provided either via --suppression or
indirectly via devel packages.  The patch fixes that.

Last but not least, fedabipkgdiff --self-compare completely ignores
suppression specifications too!  The patch fixes that as well.

With all those fixes, the system now takes around 7GB of RAM and ~ 30
minutes to complete the analysis of the webkit2gtk3 package, using a
non-optimized libabigail build.

The command I use is:

    $ time tools/fedabipkgdiff --debug --self-compare --abipkgdiff build/tools/abipkgdiff --suppressions default.abignore -a --from fc39 webkit2gtk3

    [...]

    [DEBUG] Result from run_abipkgdiff: 0, in: 0:29:00.088735
    [DEBUG] Result from self_compare_rpms_from_distro: 0, in: 0:29:20.721748

    real	29m20,846s
    user	29m4,561s
    sys	        2m41,611s
    $

The culprit package was webkit2gtk3-2.40.1-1.fc36.ppc64le.rpm.

To reproduce the issue on that package, I do:

    $ time ~/git/libabigail/rhbz2273891/build/tools/abipkgdiff --self-check --suppr ~/git/libabigail/rhbz2273891/default.abignore --d1 webkit2gtk3-debuginfo-2.40.1-1.fc36.ppc64le.rpm --devel1 webkit2gtk3-devel-2.40.1-1.fc36.ppc64le.rpm webkit2gtk3-2.40.1-1.fc36.ppc64le.rpm

    ==== SELF CHECK SUCCEEDED for 'libwebkit2gtk-4.0.so.37.63.2' ====
    ==== SELF CHECK SUCCEEDED for 'WebKitWebDriver' ====
    ==== SELF CHECK SUCCEEDED for 'WebKitNetworkProcess' ====
    ==== SELF CHECK SUCCEEDED for 'WebKitWebProcess' ====

    real	8m25,895s
    user	8m46,433s
    sys	        0m15,683s
    $

	* default.abignore: Split the libwebkit2gtk suppression
	specification for types whose names match the regexp
	^std::.*|WebCore::.*|WebKit::.* into two.  One that drops type
	with names being ^std::.* and another one that turns type being
	WebCore::.*|WebKit::.* into opaque types.
	* doc/manuals/libabigail-concepts.rst: Add documentation for the
	new special label libabigail::OPAQUE_TYPE_LABEL that transforms
	types matching a [suppress_type] into opaque types.
	* include/abg-suppression.h (is_opaque_type_suppr_spec): Renamed
	is_private_type_suppr_spec into this.
	(get_opaque_types_suppr_spec_label): Renamed
	get_private_types_suppr_spec_label.
	* src/abg-comparison.cc (diff::is_suppressed): Adjust.
	* src/abg-dwarf-reader.cc (type_is_suppressed): Adjust. Change the
	name of the type_is_private parameter into type_is_opaque.
	(get_opaque_version_of_type): Do not return early if the type has
	no associated location.  What was I thinking.
	(build_ir_node_from_die): For enums, struct and classes adjust
	call to type_is_suppressed.
	* src/abg-suppression.cc (type_suppression::suppresses_diff):
	Adjust to using is_opaque_type_suppr_spec and
	get_opaque_version_of_type in lieu of is_private_type_suppr_spec
	and get_private_types_suppr_spec_label.
	(get_opaque_types_suppr_spec_label): Rename
	get_private_types_suppr_spec_label into this.  Also, rename the
	name of the special label that specifies opaque types from
	"Artificial private types suppression specification" to
	"libabigail::OPAQUE_TYPE_LABEL".
	(is_opaque_type_suppr_spec): Rename is_private_type_suppr_spec
	into this.
	(is_type_suppressed): Rename the "type_is_private" parameter into
	"type_is_opaque".
	* src/abg-tools-utils.cc (handle_file_entry): Adjust to using
	get_opaque_types_suppr_spec_label rather than
	get_private_types_suppr_spec_label.
	* tools/abipkgdiff.cc (compare): Use the supprs variable where all
	the suppression specifications got accumulated, not just the
	priv_types_supprs1.
	(compare_to_self): Add a suppression specifications variable for
	private types.  Add those private types specs to the user-provided
	ones.
	* tools/fedabipkgdiff (abipkgdiff): In the self comparison mode,
	take into account devel packages and suppression specifications.
	Pass those to the abipkgdiff tool's invocation.
	* tests/data/test-diff-suppr/PR31646/test-PR31646-result-[1-3].txt:
	New reference test output files.
	* tests/data/test-diff-suppr/PR31646/test-PR31646-v{0,1}.cc:
	Source code of binary inputs below.
	* tests/data/test-diff-suppr/PR31646/test-PR31646-v{0,1}.o: Binary
	input files.
	* tests/data/test-diff-suppr/PR31646/test-PR31646.2.abignore:
	Suppression specification file.
	* tests/data/test-diff-suppr/PR31646/test-PR31646.abignore:
	Likewise.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the new test input
	to this harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-04-16 17:46:19 +02:00
Dodji Seketeli
338394f545 Bug 31513 - abidiff considers data members moved to base class as harmful
Consider the 'struct type' below and its use in the file
example-v0.cc:

    //----> example-v0.cc: <------
    struct type
    {
      int m0;
    };

    int
    use(type& t)
    {
      return t.m0;
    }
    //---->8<-----

Now, consider a second version of that program where the data member
of the 'struct type' is moved into a base class:

    //----> example-v1.cc: <------
    struct base
    {
      int m0;
    };

    struct type : public base
    {
    };

    int
    use(type& t)
    {
      return t.m0;
    }
    //---->8<------

The first and second version of 'struct type' are ABI compatible
because neither the size of 'struct type' nor the offset of the data
member m0 has changed.

But then look at what abidiff says:

    $ abidiff example-v0.o example-v1.o || echo "exit code: $?"
    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 use(type&)' at example-v0.cc:7:1 has some indirect sub-type changes:
	parameter 1 of type 'type&' has sub-type changes:
	  in referenced type 'struct type' at example-v1.cc:6:1:
	    type size hasn't changed
	    1 base class insertion:
	      struct base at example-v1.cc:1:1
	    1 data member deletion:
	      'int m0', at offset 0 (in bits) at example-v0.cc:3:1

    exit code: 4
    $

abidiff considers that the mere addition of a base class constitutes a
potential ABI incompatibility.

Also, abidiff fails to see that although the data member m0 was
removed from 'struct type' itself, it was moved into its new base
type.  In practice, the data member m0 is still a member of 'struct
type', by definition of class type inheritance.

Thus, the exit code of abidiff is ABIDIFF_ABI_CHANGE which value is 4.

This patch fixes this problem.

First of all, here is what abidiff now says with this patch:

    $ abidiff example-v0.o example-v1.o && echo "return code: $?"
    Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
    Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

    return code: 0
    $

In other words, abidiff now recognizes the changes as being ABI
compatible and filters them out by default.

Furthermore, here are the changes that abidiff sees when asked to
avoid filtering these (now considered harmless) changes:

    $ abidiff --harmless example-v0.o example-v1.o && echo "return code: $?"
    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 use(type&)' at example-v0.cc:7:1 has some indirect sub-type changes:
	parameter 1 of type 'type&' has sub-type changes:
	  in referenced type 'struct type' at example-v1.cc:6:1:
	    type size hasn't changed
	    1 base class insertion:
	      struct base at example-v1.cc:1:1

    $

We can see that abidiff no longer considers that the data member m0
was deleted.

At its core, this patch teaches
class_diff::ensure_lookup_tables_populated to detect data members
being moved to base classes.  That detection prevents the code base to
consider those data members as being removed from the class.

Now that the moved data members are not considered as removed, the
patch goes further to consider data member moves to base classes that
are not accompanied with any size or offset change as being harmless,
and thus, to be filtered out by default.

To that end, the patch teaches categorize_harmful_diff_node that an
added base classes is not necessarily a harmful change if it is not
accompanied with a size or offset change.  Rather, an added base
classes (or any change to a class) not accompanied with a size or
offset change is now categorized into
HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY.  Note that the previous
HARMLESS_UNION_CHANGE_CATEGORY was renamed into
HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY.

Incidentally, a removal of a base class or any change accompanied with
an offset change is always categorized as harmful change.

The patch also adds several non-regression tests.

	* include/abg-comparison.h (typedef string_decl_base_sptr_map):
	Move this typedef to include/abg-fwd.h:
	(HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY): Inside the enum
	diff_category, rename the enumerator
	HARMLESS_UNION_CHANGE_CATEGORY into this.
	(EVERYTHING_CATEGORY): Adjust this enum to refer to
	HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY, no more HARMLESS_UNION_CHANGE_CATEGORY
	* include/abg-fwd.h (typedef string_decl_base_sptr_map): Move this
	typedef here from abg-comparison.h
	(collect_non_anonymous_data_members): Declare new function.
	* src/abg-comp-filter.cc (has_offset_changes)
	(type_has_offset_changes, has_offset_changes)
	(has_subtype_changes, class_diff_has_only_harmless_changes):
	Define new static functions.
	(base_classes_removed): Rename base_classes_added_or_removed into
	this and update comment.
	(categorize_harmless_diff_node): Changes that were categorized as
	HARMLESS_UNION_CHANGE_CATEGORY is now categorized as
	HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY.  Also, a diff that
	satisfies either union_diff_has_harmless_changes or
	class_diff_has_only_harmless_changes is categorized as
	HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY.
	(categorize_harmful_diff_node): Adjust to invoke
	base_classes_removed instead of base_classes_added_or_removed.  An
	added base class doesn't necessarily qualifies as a harmful change
	anymore.  Rather, a diff node that carries an offset change as
	detected by type_has_offset_changes is categorized as
	SIZE_OR_OFFSET_CHANGE_CATEGORY.
	* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
	Adjust to use
	abigail::comparison::HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY
	rather than abigail::comparison::HARMLESS_UNION_CHANGE_CATEGORY.
	(operator<<(ostream& o, diff_category c)): Likewise.
	(class_diff::ensure_lookup_tables_populated): Detect data members
	that are moved into base classes to avoid considering those data
	members as being removed from the class.
	* src/abg-default-reporter.cc (default_reporter::report): Adjust
	to use HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY rather than
	HARMLESS_UNION_CHANGE_CATEGORY.
	* src/abg-ir.cc (collect_non_anonymous_data_members): Define
	function overloads.
	* tests/data/test-abidiff-exit/PR31513/non-regr/libtest[1-4]-v{0,1}.so:
	New binary test input files.
	* tests/data/test-abidiff-exit/PR31513/non-regr/report[1-4.txt:
	New reference output files.
	* tests/data/test-abidiff-exit/PR31513/non-regr/test[1-4]-v{0,1}.cc:
	Source code of the binary input files above.
	* tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-{1,2}.txt:
	New reference output files.
	* tests/data/test-abidiff-exit/PR31513/reported/libloremipsum_gcc{7,11}.so:
	New binary test input files.
	* tests/data/test-abidiff-exit/PR31513/reported/libstdcpp.suppr:
	New test suppression file.
	* tests/data/Makefile.am: Add new test files above to source
	distribution.
	* tests/test-abidiff-exit.cc (in_out_specs): Add the new input
	test files to this test harness.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
	Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-03-29 17:36:09 +01:00
Dodji Seketeli
15f2ff5d6c Emit & read undefined interfaces to & from ABIXML
This patch teaches the ABIXML writer to emit information about
undefined interfaces.  It also teaches the ABIXML reader to read
information about undefined interfaces.

It introduces two new ABIXML elements:
'undefined-elf-function-symbols' and 'undefined-elf-variable-symbols'
to represent undefined function and variable symbols.

Then, in the 'abi-instr' element functions and variables that
reference undefined elf symbols now have an 'elf-symbol-id' attribute
referencing the undefined symbol listed in the new
'undefined-elf-variable-symbols' or 'undefined-elf-function-symbols'
element.

The patch introduces tests that perform compatibility checks done on
ABIXML files.

	* include/abg-writer.h (set_write_undefined_symbols): Declare new
	function.
	(set_common_options): Use the new set_write_undefined_symbols in
	this function template.
	* src/abg-dwarf-reader.cc (reader::{get_die_language, die_is_in_c,
	die_is_in_cplus_plus, die_is_in_c_or_cplusplus}): Move these
	member functions into ...
	(get_die_language, die_is_in_c, die_is_in_cplus_plus)
	(die_is_in_c_or_cplusplus): ... these static non-member functions.
	(fn_die_equal_by_linkage_name): Adjust and remove the now useless
	reader parameter.
	(compare_dies, get_scope_die, function_is_suppressed)
	(variable_is_suppressed): Adjust.
	(build_translation_unit_and_add_to_ir): When we are asked to load
	undefined symbol, make sure to also analyze top-level class types
	and if we are in C++, also analyze top-level unions and structs as
	these might also have some undefined interfaces.
	* src/abg-reader.cc (build_elf_symbol_db): Let's not construct and
	return the symbol DB anymore.  Rather, let's let the caller
	construct it, so we can just update it with the input gathered.
	(read_symbol_db_from_input): Support getting undefined function
	and variable symbols from the new undefined-elf-function-symbols
	and undefined-elf-variable-symbols elements.  Note that undefined
	and defined function symbols go into the same symbol DB whereas
	undefined and defined variable symbols go into another symbol DB.
	Now, we suppose that the variable & symbol DBs are allocated by
	the caller.  We pass it down to build_elf_symbol_db that populates
	it.  Maybe we should rename build_elf_symbol_db into
	populate_elf_symbol_db.
	(reader::read_corpus): Allocate the function
	and variable symbol DB and let read_symbol_db_from_input populate
	it.  Sort functions and variables after reading the whole ABIXML.
	* src/abg-writer.cc (write_context::write_context): Define new
	data member.
	(write_context::write_context): Initialize it.
	(write_context::{get,set}::write_undefined_symbols): Define
	accessors.
	(set_write_undefined_symbols): Define a new function.
	(write_context::decl_is_emitted): Add a new overload.
	(write_elf_symbol_reference): Add a writer context and a corpus
	parameter.  If the symbol is not in the corpus or if the symbol is
	undefined and we were not asked to emit undefined symbols then do
	not emit any reference to it.
	(write_translation_unit): Emit the undefined functions and
	variables that belong to the current translation unit, along with
	their reference to the undefined ELF symbol they are associated
	to.
	(write_var_decl, write_function_decl): Let
	write_elf_symbol_reference decide whether it should emit the
	reference to ELF symbol or not, as it now know how to make that
	decision.
	(write_corpus): Write the undefined function & variable ELF symbol
	data bases.  These in the new 'undefined-elf-function-symbols' and
	'undefined-elf-variable-symbols' elements.
	* tools/abidw.cc (options::load_undefined_interfaces): Define new
	data member.
	(options:options): Initialize it.
	(display_usage): Add a help string for the
	--no-load-undefined-interfaces option.
	(parse_command_line): Parse the --no-load-undefined-interfaces
	option.
	(set_generic_options): Set the
	fe_iface::option_type::load_undefined_interfaces option.
	* doc/manuals/abidw.rst: Document the new
	--no-load-undefined-interfaces of abidw.
	* tests/data/test-abicompat/test10/libtest10-with-exported-symbols.so:
	New binary input file.
	* tests/data/test-abicompat/test10/libtest10-with-incompatible-exported-symbols.so:
	New binary input file.
	* tests/data/test-abicompat/test10/libtest10-with-incompatible-exported-symbols.so.abi:
	New abixml input file.
	* tests/data/test-abicompat/test10/test10-app-with-undefined-symbols:
	New binary input file.
	* tests/data/test-abicompat/test10/test10-app-with-undefined-symbols.abi:
	New abixml input file.
	* tests/data/test-abicompat/test10/test10-app-with-undefined-symbols.cc:
	New source file for binary test input
	* tests/data/test-abicompat/test10/test10-fn-changed-report-0.txt:
	New source file for binary test input
	* tests/data/test-abicompat/test10/test10-fn-changed-report-1.txt:
	New source file for binary test input
	* tests/data/test-abicompat/test10/test10-fn-changed-report-2.txt:
	New source file for binary test input
	* tests/data/test-abicompat/test10/test10-fn-changed-report-3.txt:
	New source file for binary test input
	* tests/data/test-abicompat/test10/test10-fn-changed-report-4.txt:
	New source file for binary test input
	* tests/data/test-abicompat/test10/test10-with-exported-symbols.cc:
	New source file for binary test input
	* tests/data/test-abicompat/test10/test10-with-exported-symbols.h:
	New source file for binary test input
	* tests/data/test-abicompat/test10/test10-with-incompatible-exported-symbols.cc:
	New source file for binary test input
	* tests/data/test-abicompat/test10/test10-with-incompatible-exported-symbols.h:
	New source file for binary test input.
	* tests/data/Makefile.am: Add new test input files to source
	distribution.
	* tests/test-abicompat.cc (in_out_specs): Add the new test inputs
	to this test harness.
	* tests/test-annotate.cc (main): Use the new
	--no-load-undefined-interfaces option of abidw to keep the old
	behavior.
	* tests/test-read-common.cc (test_task::serialize_corpus): Do not
	emit undefined symbols.
	* tests/test-read-dwarf.cc (test_task_dwarf::perform): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-03-14 16:27:14 +01:00
Dodji Seketeli
897ecc9a49 Add support for undefined symbols in the BTF reader
This patch teaches the BTF reader how to construct an IR for undefined
interfaces.  The patch also updates the abicompat tool for BTF
support.

	* doc/manuals/abicompat.rst: Update documentation for the --btf
	option of abicompat.
	* include/abg-elf-reader.h
	(elf::reader::{function,variable}_symbol_is_undefined): Declare
	new member functions.
	* src/abg-btf-reader.cc
	(reader::read_debug_info_into_corpus): Sort functions &
	variables after canonicalization.
	(reader::build_ir_node_from_btf_type): Always call
	fe_iface::add_{fn,var}_to_exported_or_undefined_decls with the
	decl that was constructed.
	(reader::build_function_decl): Support setting an undefined symbol
	to the function decl.
	(reader::build_var_decl): Likewise, support setting undefined
	symbol the variable decl.
	* src/abg-elf-reader.cc
	((elf::reader::{function,variable}_symbol_is_undefined): Declare
	new member functions.): Define new member functions.
	* src/abg-symtab-reader.cc
	(symtab::{function,variable}_symbol_is_undefined): Return the
	undefined symbol that was found.
	* src/abg-symtab-reader.h
	(symtab::{function,variable}_symbol_is_undefined): Return an
	undefined symbol rather than just a boolean value.
	* tools/abicompat.cc: Add support for BTF here.
	(options::use_btf): Define new data member ...
	(options::options): ... and initialize it.
	(display_usage): Add a help string for the --btf option.
	(parse_command_line): Parse the --btf option.
	* tests/data/test-abicompat/test7-fn-changed-report-0.1.txt: New
	reference test output file.
	* tests/data/test-abicompat/test7-fn-changed-report-2.1.txt:
	Likewise.
	* tests/data/test-abicompat/libtest7-fn-changed-libapp-btf-v0.so:
	New binary input file.
	* tests/data/test-abicompat/libtest7-fn-changed-libapp-btf-v1.so:
	Likewise.
	* tests/data/test-abicompat/test7-fn-changed-app.btf: Likewise.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/test-abicompat.cc (in_out_specs): Add the new test input
	to the test harness.
	* tests/data/test-abicompat/test7-fn-changed-app.c: Adjust.
	* tests/data/test-abicompat/test7-fn-changed-libapp-v0.c:
	Likewise.
	* tests/data/test-abicompat/test7-fn-changed-libapp-v1.c: Likewise

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-03-14 16:27:07 +01:00
Dodji Seketeli
610d87c29b Represent undefined corpus interfaces to analyze app compatibility
In the text below, the term interface means the "declaration of either
a function or a global variable".

To analyze the compatibility between an application and a dependent
library, one has essentially to analyze the interfaces of the
application that have undefined symbols (aka undefined interfaces from
the application) and see how they relate to the same interfaces coming
from the library but with symbols that are defined and exported from
the library (aka defined/exported interfaces from the library).

An interface that is undefined in the application and defined in the
library is an interface that the application consumes from the
library.

In other words an undefined interface from an application is an
interface that the application expects and an interface that is
exported by a library is an interface that the library provides.

If comparing the expected interface against the provided interface
yields a meaningful difference, then that might mean there is an
incompatibility between the application and the library on that
interface.

This patch uses this scheme to re-implement the weak mode of ABI
compatibility between an application and a library.

The patch adds the concept of undefined functions and variables to the
ABI corpus.  Then it teaches the DWARF reader how to construct the IR
for these undefined interfaces.  Then it revisits the weak mode of
operation of abicompat to make it compare the interfaces expected from
the application against the corresponding interfaces provided by
library.  The patch also teaches the weak mode abicompat how to detect
incompatibilities between the interfaces that plugin expects and the
interfaces provided by the application.

This patch makes the CTF front-end construct undefined interfaces.  A
subsequent patch is needed to construct undefined interfaces from the
BTF front-end however.

	* include/abg-corpus.h (corpus::{lookup_variable,
	get_undefined_functions, get_undefined_variables}): Declare new
	member functions.
	(corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns):
	Make this return a boolean.
	* include/abg-fe-iface.h (fe_iface::options_type): Add a new
	load_undefined_interfaces enumerator.
	(fe_iface::add_fn_to_exported_or_undefined_decls): Rename
	maybe_add_fn_to_exported_decls into this.
	(fe_iface::add_var_to_exported_or_undefined_decls): Rename
	maybe_add_var_to_exported_decls into this.
	* src/abg-btf-reader.cc (reader::build_ir_node_from_btf_type):
	Adjust call to maybe_add_fn_to_exported_decls as
	add_fn_to_exported_or_undefined_decls.  Similarly, adjust call to
	maybe_add_var_to_exported_decls as
	add_var_to_exported_or_undefined_decls.
	* src/abg-corpus-priv.h (corpus::priv::undefined_{fns,vars}): Add
	new member variables.
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns):
	Return a bool iff the decl was added to the set of exported decls.
	(corpus::{lookup_variable, get_undefined_functions,
	get_undefined_variables}): Define new member functions.
	(corpus::sort_{functions,variables}): Sort the undefined decls
	too.
	* (corpus::lookup_{function,variable}_symbol): Lookup the symbol
	also among undefined symbols, not just among defined symbols.
	* src/abg-ctf-reader.cc (reader::process_ctf_archive): Adjust call
	to maybe_add_fn_to_exported_decls as
	add_fn_to_exported_or_undefined_decls.  Similarly, adjust call to
	maybe_add_var_to_exported_decls as
	add_var_to_exported_or_undefined_decls. Also, sort functions &
	variables in the corpus.
	* src/abg-dwarf-reader.cc (die_name_and_linkage_name): Define new
	static function.
	(reader::fixup_functions_with_no_symbols): Adjust call to
	maybe_add_fn_to_exported_decls as
	add_fn_to_exported_or_undefined_decls.
	(reader::{is_decl_die_with_undefined_symbol,
	load_undefined_interfaces}): Define new member functions.
	(build_translation_unit_and_add_to_ir): Analyze DIEs of interfaces
	that have undefined symbols if we were asked to load undefined
	interfaces.
	(variable_is_suppressed): Add a boolean parameter to tell if the
	var is decl-only.  Use that decl-only flag to determine if the
	variable is suppressed.  A non-member decl-only variable won't be
	suppressed if we were asked to load undefined interfaces.
	(build_or_get_var_decl_if_not_suppressed): Add a boolean parameter
	to tell if the var is decl-only.
	(potential_member_fn_should_be_dropped): A potential non-virtual
	member function with no symbol is now dropped on the floor
	regardless of it has a mangled name or not.
	(build_var_decl): If the var has an undefined symbol, then set
	that symbol.
	(build_function_decl): If the function has an undefined symbol,
	then set that symbol.
	(build_ir_node_from_die): Add a var or function with undefined
	symbol to the set of undefined vars or functions of the current
	corpus.
	* src/abg-fe-iface.cc
	(fe_iface::add_fn_to_exported_or_undefined_decls): Renamed
	fe_iface::maybe_add_fn_to_exported_decls into this.  If the
	function has an undefined symbol then add the function to the set
	of undefined functions.
	(fe_iface::add_var_to_exported_or_undefined_decls): Renamed
	fe_iface::maybe_add_var_to_exported_decls into this.  If the
	variable has an undefined symbol then add the variable to the set
	of undefined variables.
	* src/abg-ir.cc (elf_symbol::is_variable): Undefined symbol with
	type STT_NOTYPE are actually for undefined variables.
	(maybe_adjust_canonical_type): It's here, after type
	canonicalization that a member function is added to either the set
	of defined & exported functions, or to the set of functions with
	undefined symbols.
	* src/abg-reader.cc (build_function_decl, build_class_decl)
	(build_union_decl, handle_var_decl): Adjust.
	* src/abg-symtab-reader.cc
	(symtab::{lookup_undefined_function_symbol,
	lookup_undefined_variable_symbol, function_symbol_is_undefined,
	variable_symbol_is_undefined,
	collect_undefined_fns_and_vars_linkage_names}): Define new member
	functions.
	(symtab::symtab): Initialize the new
	cached_undefined_symbol_names_ data member.
	* src/abg-symtab-reader.h
	(symtab::{lookup_undefined_function_symbol,
	lookup_undefined_variable_symbol, function_symbol_is_undefined,
	variable_symbol_is_undefined,
	collect_undefined_fns_and_vars_linkage_names}): Declare new member
	functions.
	(symtab::{undefined_variable_linkage_names_,
	cached_undefined_symbol_names_}): Define new data members.
	(symtab::load_): Consider undefined symbol of type STT_NOTYPE as
	being undefined global variables.  It's what I am seeing in ELF
	binaries.
	* src/abg-symtab-reader.h
	(symtab::{lookup_undefined_function_symbol,
	lookup_undefined_variable_symbol, function_symbol_is_undefined,
	variable_symbol_is_undefined}): Declare new member functions.
	(symtab::{undefined_function_linkage_names_,
	undefined_variable_linkage_names_}): Define new member variables.
	* src/abg-writer.cc (write_var_decl, write_function_decl): Emit a
	reference to a symbol only when the symbol is defined.
	* tools/abicompat.cc (report_function_changes)
	(report_variable_changes)
	(compare_expected_against_provided_functions)
	(compare_expected_against_provided_variables): Define new static
	functions.
	(perform_compat_check_in_weak_mode): Use the new static functions
	above. Compare interfaces expected by the application corpus
	against interfaces provided by the library.  Report the changes.
	Do that in the reverse direction as well.
	(read_corpus): Instruct the corpus reader to load the set of
	undefined interfaces too.
	* tests/data/test-abicompat/test6-var-changed-app: Remove file.
	* tests/data/test-abicompat/test6-var-changed-app.cc: Likewise.
	* tests/data/test-abicompat/libtest6-undefined-var.so: Add new
	binary input file.
	* tests/data/test-abicompat/test6-undefined-var.cc: Add sourcefile
	for the binary input file above.
	* tests/data/test-abicompat/test6-var-changed-report-2.txt: New
	reference output file.
	* tests/data/Makefile.am: Update the list of distributed files
	accordingly.
	* tests/data/test-abicompat/libtest5-fn-changed-libapp-v0.so:
	Adjust.
	* tests/data/test-abicompat/libtest5-fn-changed-libapp-v1.so:
	Likewise.
	* tests/data/test-abicompat/libtest6-var-changed-libapp-v0.so:
	Likewise.
	* tests/data/test-abicompat/libtest6-var-changed-libapp-v1.so:
	Likewise.
	* tests/data/test-abicompat/libtest7-fn-changed-libapp-v0.so:
	Likewise.
	* tests/data/test-abicompat/libtest7-fn-changed-libapp-v1.so:
	Likewise.
	* tests/data/test-abicompat/libtest8-fn-changed-libapp-v0.so:
	Likewise.
	* tests/data/test-abicompat/libtest8-fn-changed-libapp-v1.so:
	Likewise.
	* tests/data/test-abicompat/libtest9-fn-changed-v0.so: Likewise.
	* tests/data/test-abicompat/libtest9-fn-changed-v1.so: Likewise.
	* tests/data/test-abicompat/test5-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test6-var-changed-libapp-v0.cc:
	Likewise.
	* tests/data/test-abicompat/test6-var-changed-libapp-v1.cc:
	Likewise.
	* tests/data/test-abicompat/test6-var-changed-report-0.txt:
	Likewise.
	* tests/data/test-abicompat/test6-var-changed-report-1.txt:
	Likewise.
	* tests/data/test-abicompat/test7-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test7-fn-changed-report-1.txt:
	Likewise.
	* tests/data/test-abicompat/test7-fn-changed-report-2.txt:
	Likewise.
	* tests/data/test-abicompat/test8-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-libapp-v1.c:
	Likewise.
	* tests/data/test-abicompat/test9-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test9-fn-changed-app.cc: Likewise.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test1.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.ab: Likewise.i
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test2.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64--dbus-glib-0.104-3.fc23.armv7hl-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt:
	Likewise.
	* tests/data/test-fedabipkgdiff/test0-from-fc20-to-fc23-dbus-glib-report-0.txt:
	Likewise.
	* tests/data/test-fedabipkgdiff/test2-dbus-glib-0.100.2-2.fc20--dbus-glib-0.106-1.fc23-report-0.txt:
	Likewise.
	* tests/data/test-fedabipkgdiff/test3-dbus-glib-0.100.2-2.fc20.i686--dbus-glib-0.106-1.fc23.i686-report-0.txt:
	Likewise.
	* tests/data/test-fedabipkgdiff/vte291-0.39.1-1.fc22.x86_64--vte291-0.39.90-1.fc22.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR26261/PR26261-exe.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test2.so.abi: Likewise.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/test-abicompat.cc (in_out_specs): Adjust.
	* tests/test-read-ctf.cc (test_task_ctf::perform): Do not load
	undefined interfaces, by default.
	* tests/test-symtab.cc (Symtab::SimpleSymtabs)
	(Symtab::SymtabWithWhitelist, Symtab::AliasedFunctionSymbols):
	Adjust the expected undefined variable symbols counts.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-03-14 16:26:54 +01:00
Dodji Seketeli
908f56e1b5 ir,dwarf-reader: Peel const-qualifier from const this pointers
In DWARF, it appears that the this pointer of a concrete instance of
method is sometimes represented as a const pointer, whereas the this
pointer of the abstract instance (or interface) of that same method
has the this pointer represented as a non-const pointer.  That
difference often causes some spurious const-ness change reports on the
this pointer when doing comparisons.

This patch thus trims of the const-qualifier off of the this pointer
of methods.

	* include/abg-fwd.h (is_const_qualified_type)
	(peel_const_qualified_type): Declare ...
	* src/abg-ir.cc (is_const_qualified_type)
	(peel_const_qualified_type): ... new functions.
	* src/abg-dwarf-reader.cc (build_function_type): Trim the const
	qualifier off of the this pointer representation if present.
	* tests/data/test-annotate/test1.abi: Adjust.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test2.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test6.so.abi: Likewise.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Likewise.
	* tests/data/test-diff-dwarf/test0-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test29-vtable-changes-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test30-vtable-changes-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test31-vtable-changes-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test36-ppc64-aliases-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test41-PR20476-hidden-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test5-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test8-report.txt: Likewise.
	* tests/data/test-diff-filter/test0-report.txt: Likewise.
	* tests/data/test-diff-filter/test01-report.txt: Likewise.
	* tests/data/test-diff-filter/test10-report.txt: Likewise.
	* tests/data/test-diff-filter/test13-report.txt: Likewise.
	* tests/data/test-diff-filter/test2-report.txt: Likewise.
	* tests/data/test-diff-filter/test28-redundant-and-filtered-children-nodes-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test41-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test9-report.txt: Likewise.
	* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt:
	Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-10.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-12.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-14.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-16.txt:
	Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test31-report-1.txt: Likewise.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test2.so.abi: Likewise.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test6.so.abi: Likewise.
	* tests/data/test-read-dwarf/test6.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-03-06 14:02:55 +01:00
Dodji Seketeli
dd34ee8687 ir,dwarf-reader: Better handle inline-ness setting or detection
The DWARF reader mistakenly considers that if the value of
DW_AT_inline attribute is set to DW_INL_declared_inlined, that means
the function we are looking at was declared inline.  Rather, that
means the function was declared inlined *and* was inlined by the
compiler.  To have a better coverage of functions that were declared
inline, we need to consider functions which DW_AT_inline attribute is
set to DW_INL_declared_inlined or DW_INL_declared_not_inlined.  This
patches fixes that.

I noticed that we were missing concrete instances of inlined functions
as we were taking into account DW_TAG_inlined_subroutine DIEs.  This
patch fixes that.

I noticed that finish_member_function_reading (which is called for
virtual member functions that don't have associated an associated elf
symbol in the current translation unit) wasn't taking into account the
inline declaration of virtual member functions.  This patch fixes that.

Last but not least, this patch stops considering the change of
inline-ness declaration of functions as being an ABI change.  Whenever
that inline-ness declaration change happens alongside a meaningful ABI
change, libabigail will report it, but that alone is not an ABI
change.

All in all, these change fix the fall-out (caught by the CI) from the
previous patch:
	3ccfe465 dwarf-reader: Fix DIE origin handling & scope getting

	* include/abg-ir.h (function_decl::is_declared_inline): Add a
	setter overload.
	* src/abg-dwarf-reader.cc (die_is_declared_inline): Take into the
	account values DW_INL_declared_inlined and
	DW_INL_declared_not_inlined of DW_AT_inline attribute.  Not just
	DW_INL_declared_inlined.
	(finish_member_function_reading): Set the inline-ness declaration
	here.
	(build_ir_node_from_die): Handle DW_TAG_inlined_subroutine just as
	DW_TAG_subprogram.
	* src/abg-ir.cc (function_decl::is_declared_inline): Add a setter
	overload.
	* tests/data/test-annotate/test1.abi: Adjust.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test41-report-0.txt: Likewise.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-03-04 09:49:02 +01:00
Dodji Seketeli
4b39942467 ir,corpus,comparison: Const-iffy the access to corpus interfaces
In preparation to subsequent patches that perform manipulations of the
corpus interfaces, it appears that we need to add const access to
those corpus interfaces.

	* include/abg-comparison.h (typedef string_function_ptr_map): Make
	this typedef use a const function_decl*, not just a
	function_decl*.
	(typedef string_var_ptr_map): Make this typedef use a const
	var_decl*, not just a var_decl*.
	* include/abg-corpus.h (typedef corpus::functions): Make this
	typedef be a vector<const function_decl*>, not just a
	vector<function_decl*>.
	(corpus::exported_decls_builder::fn_id_maps_to_several_fns):
	Adjust declaration to const function_decl*.
	* include/abg-fwd.h (typedef istring_var_decl_ptr_map_type)
	(typedef istring_function_decl_ptr_map_type): Move these typedefs to
	abg-ir.h.
	(get_function_id_or_pretty_representation): Use const function_decl*.
	* include/abg-ir.h (typedef istring_var_decl_ptr_map_type)
	(typedef istring_function_decl_ptr_map_type): Move these here from
	abg-fwd.h.  Also make these use const var_decl* and const.
	function_decl.
	* src/abg-comparison-priv.h (sort_string_function_ptr_map)
	(sort_string_var_ptr_map): Use vector<const function_decl*> and
	vector<const var_decl*> rather than their non-const variants.
	* src/abg-comparison.cc (sort_string_function_ptr_map)
	(sort_string_var_ptr_map): Likewise.
	(corpus_diff::priv::{ensure_lookup_tables_populated,
	apply_supprs_to_added_removed_fns_vars_unreachable_types}):
	Adjust.
	* src/abg-corpus-priv.h (corpus::priv::{fns,vars}): Make these
	data members use vector<const function_decl*> and vector<const
	var_decl*> types.
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::fn_id_maps_to_several_fns)
	(corpus::maybe_drop_some_exported_decls): Adjust.
	(corpus_group::priv::{fns,vars}): Make these data members use
	vector<const function_decl*> and vector<const var_decl*> types.
	* src/abg-default-reporter.cc (default_reporter::report): In the
	overload for const corpus_diff&, adjust.
	* src/abg-ir.cc (get_function_id_or_pretty_representation):
	Adjust.
	* src/abg-leaf-reporter.cc (leaf_reporter::report): In the
	overload for const corpus_diff&, adjust.
	* tools/abicompat.cc (perform_compat_check_in_normal_mode):
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-03-01 14:19:05 +01:00
Dodji Seketeli
6432acb1d9 ir,{btf,ctf,dwarf}-reader: Rename {subrange_type,array_type_def}::is_infinite.
Rename subrange_type::is_infinite into subrange_type::is_non_finite
for better legibility.

	* include/abg-ir.h
	({array_type_def,subrange_type}::is_non_finite): Rename
	{array_type_def,subrange_type}::is_infinite into this.
	* src/abg-btf-reader.cc (reader::build_array_type): Add a missing
	call to subrange_type::is_non_finite.
	* src/abg-comp-filter.cc
	(is_var_1_dim_unknown_size_array_change):Rename
	subrange_type::is_infinite into subrange_type::is_non_finite.
	* src/abg-ctf-reader.cc (build_array_ctf_range): Likewise.
	* src/abg-dwarf-reader.cc (build_subrange_type): Likewise.
	* src/abg-ir.cc (clone_array, has_flexible_array_data_member)
	(array_type_def::subrange_type::as_string): Likewise.
	({array_type_def,subrange_type}::is_non_finite): Rename
	{array_type_def,subrange_type}::is_infinite into this.
	* src/abg-reader.cc (build_subrange_type): Rename
	subrange_type::is_infinite into subrange_type::is_non_finite.
	* src/abg-reporter-priv.cc (report_size_and_alignment_changes):
	Likewise.
	* src/abg-writer.cc (write_array_size_and_alignment): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-02-16 16:00:14 +01:00
Dodji Seketeli
3f2afc7a71 dwarf-reader,corpus: Use interned string to lookup corpus interfaces by ID.
This patch speeds up the lookup of a function or variable using the
function/variable ID.  This patch is in preparation of many more
function lookup made during ABIXML emitting by patches coming up in
the future.

	* include/abg-corpus.h (corpus::lookup_functions): Take an
	interned_string instead of an std::string.  Add an overload for
	const char* string too, for debugging purposes.
	* src/abg-corpus-priv.h (istr_fn_ptr_set_map_type)
	(istr_var_ptr_map_type): Define new typedefs.
	(corpus::exported_decls_builder::priv::{id_fns_map_,
	id_var_map_}): Use the new istr_fn_ptr_set_map_type and
	istr_var_ptr_map_type types for these data members.
	(corpus::exported_decls_builder::priv::{id_fns_map, id_var_map,
	add_fn_to_id_fns_map, var_id_is_in_id_var_map, add_var_to_map,
	add_var_to_exported}): Adjust.
	(corpus::priv::lookup_functions): Declare new member function.
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::maybe_add_var_to_exported_vars): Adjust.
	(corpus::priv::lookup_functions): Define new member function.  The
	code here comes from the code that was in
	corpus::lookup_functions.  This is a factorization of
	corpus::lookup_functions.
	(corpus::lookup_functions): Take an interned_string instead of the
	previous.  Factorize the code that was here into the new
	corpus::priv::lookup_functions.
	* src/abg-dwarf-reader.cc
	(reader::symbol_already_belongs_to_a_function): Adjust the call to
	corpus::lookup_functions to use an interned_string.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-02-12 17:49:25 +01:00
Dodji Seketeli
6ba168688e ir: Introduce a missing IR kind for subrange types
Array subranges were introduced to support the Ada language.  In doing
so, I forgot to define an  enum type_or_decl_kind enumerator for the
array_type_def::subrange_type IR node.  This patch fixes that.

	* include/abg-ir.h (type_or_decl_kind::SUBRANGE_TYPE): Add a new
	enumerator to enum type_or_decl_kind::type_or_decl_kind.
	* src/abg-ir.cc (array_type_def::subrange_type::subrange_type):
	Use the new type_or_decl_kind::SUBRANGE_TYPE to flag the IR node
	representing array_type_def::subrange_type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-02-12 17:39:36 +01:00
Dodji Seketeli
d4ca1088e4 Bug 30260 - Support pointer-to-member type
This adds support for C++ pointer-to-member types.

Here is a screenshot of what this patch enables libabigail to do:

    $ cat -n test-ptr-to-mbr-v0.cc
	 1	struct X
	 2	{
	 3	  void f(int);
	 4	  int a;
	 5	};
	 6
	 7	int X::* pmi = &X::a;
	 8	void (X::* pmf)(int) = &X::f;
	 9

    $ diff -u test-ptr-to-mbr-v0.cc test-ptr-to-mbr-v1.cc
    --- test-ptr-to-mbr-v0.cc	2023-11-22 15:22:04.258260701 +0100
    +++ test-ptr-to-mbr-v1.cc	2023-11-22 15:23:02.482621214 +0100
    @@ -1,9 +1,8 @@
     struct X
     {
    -  void f(int);
    -  int a;
    +  void f(int, char);
    +  char a;
     };

    -int X::* pmi = &X::a;
    -void (X::* pmf)(int) = &X::f;
    -
    +auto pmi = &X::a;
    +auto pmf = &X::f;

    $ abidiff test-ptr-to-mbr-v0.o test-ptr-to-mbr-v1.o
    Functions changes summary: 0 Removed, 0 Changed, 0 Added function
    Variables changes summary: 0 Removed, 2 Changed, 0 Added variables

    2 Changed variables:

      [C] 'void (X::* pmf)(int)' was changed to 'void (X::* pmf)(int, char)' at test-ptr-to-mbr-v1.cc:8:1:
	type of variable changed:
	  pointer-to-member type changed from: 'void (X::*)(int) to: 'void (X::*)(int, char)'
	  in containing type 'struct X' of pointed-to-member type 'void (X::*)(int)' at test-ptr-to-mbr-v1.cc:1:1:
	    type size changed from 32 to 8 (in bits)
	    1 data member change:
	      type of 'int a' changed:
		type name changed from 'int' to 'char'
		type size changed from 32 to 8 (in bits)

      [C] 'int X::* pmi' was changed to 'char X::* pmi' at test-ptr-to-mbr-v1.cc:7:1:
	type of variable changed:
	  pointer-to-member type changed from: 'int X::* to: 'char X::*'
	  in data member type 'int' of pointed-to-member type 'int X::*':
	    type name changed from 'int' to 'char'
	    type size changed from 32 to 8 (in bits)
	  containing type of pointer-to-member 'struct X' changed at test-ptr-to-mbr-v0.cc:1:1, as reported earlier

    $

	* include/abg-comparison.h (class ptr_to_mbr_diff): Declare new
	class.
	(ptr_to_mbr_diff_sptr): Declare new typedef.
	(compute_diff): Declare new overload for ptr_to_mbr_diff.
	(ptr_to_mbr_type_sptr): Declare new typedef.
	* src/abg-comparison-priv.h (struct ptr_to_mbr_diff::priv): Define
	* src/abg-comparison.cc (compute_diff_for_types): Support new
	ptr_to_mbr_type type.
	(ptr_to_mbr_diff::{ptr_to_mbr_diff, first_ptr_to_mbr_type,
	second_ptr_to_mbr_type, member_type_diff, containing_type_diff,
	has_changes, has_local_changes, get_pretty_representation, report,
	chain_into_hierarchy, ~ptr_to_mbr_diff}): Define member functions
	of class ptr_to_mbr_diff.
	(compute_diff): Define overload for ptr_to_mbr_type_sptr.
	* include/abg-fwd.h (ptr_to_mbr_type_sptr): Declare new typedef.
	(is_ptr_to_mbr_type, is_pointer_to_ptr_to_mbr_type)
	(is_typedef_of_maybe_qualified_class_or_union_type): Declare new
	functions.
	* include/abg-ir.h (type_maps::ptr_to_mbr_types): Declare new
	accessor.
	(POINTER_TO_MEMBER_TYPE): Add new enumerator to enum
	type_or_decl_base::type_or_decl_kind.
	(class ptr_to_mbr_type): Declare new class.
	(equals): Declare new overload for ptr_to_mbr_type.
	(ir_node_visitor::visit_{begin,end}): Declare new member
	functions.
	* src/abg-ir.cc (ptr_to_mbr_declaration_name)
	(ptr_to_mbr_declaration_name, add_outer_ptr_to_mbr_type_expr)
	(add_outer_pointer_to_ptr_to_mbr_type_expr): Define new static
	functions.
	(type_maps::priv::ptr_to_mbr_types_): Define new
	data member.
	(type_maps::ptr_to_mbr_types): Define new accessor.
	(is_ptr_to_mbr_type, is_pointer_to_ptr_to_mbr_type)
	(is_typedef_of_maybe_qualified_class_or_union_type): Define new
	functions.
	(maybe_update_types_lookup_map, equals): Define new overloads for
	ptr_to_mbr_type_sptr.
	(is_npaf_type): Use is_ptr_to_mbr_type.
	(maybe_update_types_lookup_map): In the overload for
	decl_base_sptr, call the new overload for ptr_to_mbr_type_sptr
	above.
	(struct ptr_to_mbr_type::priv): Define new struct.
	(ptr_to_mbr_type::{ptr_to_mbr_type, get_member_type,
	get_containing_type, operator==, get_qualified_name, traverse,
	~ptr_to_mbr_type}): Define member functions of ptr_to_mbr_type.
	(types_have_similar_structure): Support the new ptr_to_mbr_type
	type.
	(ir_node_visitor::visit_{begin,end}): Add new member functions.
	(var_decl::get_pretty_representation): Support pretty-printing
	pointer-to-member types.
	(pointer_declaration_name, array_declaration_name): Likewise.
	* include/abg-reporter.h ({reporter_base, default_reporter,
	leaf_reporter}::report): Add an overload for ptr_to_mbr_diff.
	(default_reporter::report_local_ptr_to_mbr_type_changes): Declare
	a member function.
	private data class of ptr_to_mbr_diff.
	* src/abg-default-reporter.cc
	(default_reporter::report_local_ptr_to_mbr_type_changes): Define
	member functions.
	(default_reporter::report): Define an overload for
	ptr_to_mbr_diff.
	* src/abg-leaf-reporter.cc (leaf_reporter::report): Likewise.
	* src/abg-dwarf-reader.cc (build_ptr_to_mbr_type): Define new
	function.
	(build_ir_node_from_die): Use the new build_ptr_to_mbr_type
	function.
	* src/abg-reader.cc (build_ptr_to_mbr_type): Define new function.
	(build_type): Use the new build_ptr_to_mbr_type above.
	* src/abg-writer.cc (write_ptr_to_mbr_type): Define new function.
	(write_type, write_decl, write_member_type): Use the new
	write_ptr_to_mbr_type above.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-output-1.txt:
	Add new test material.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-v0.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-v0.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-v1.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-v1.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr2-output-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr2-v0.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr2-v0.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr2-v1.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr2-v1.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr3-output-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr3-v0.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr3-v0.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr3-v1.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr3-v1.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr4-output-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr4-v0.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr4-v0.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr4-v1.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr4-v1.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr5-output-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr5-v0.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr5-v0.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr5-v1.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr5-v1.o:
	Likewise.
	* tests/data/test-read-dwarf/test-pointer-to-member-1.cc:
	Likewise.
	* tests/data/test-read-dwarf/test-pointer-to-member-1.o: Likewise.
	* tests/data/test-read-dwarf/test-pointer-to-member-1.o.abi:
	Likewise.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-abidiff-exit.cc (in_out_specs): Add the test material
	above to this test harness.
	* tests/test-annotate.cc (in_out_specs): Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-12-01 15:43:53 +01:00
Dodji Seketeli
19d4131964 Improve type naming
There are a number of glitches when pretty-printing type names.

This is particularly true for derived types like pointer to functions,
array of pointer to functions and the likes.

For instance, we can see in
tests/data/test-abidiff-exit/PR30048-test-2-report-1.txt that a
function N that takes no parameter and returns a pointer to an array
of 7 int is pretty-printed as:

    int[7]* N()

That obviously doesn't respect the type naming rules of C or C++.

With this patch, function N is declared as:

    int(*N(void))[7]

To learn more about the impact of the patch on how types are
pretty-printed, you can look at the parts of the patch that are
adjustments to the expected output of the regression tests.

For instance, here is how the expected output of type pretty-printing
in tests/data/test-abidiff-exit/PR30048-test-2 is modified by this
patch:

    diff --git a/tests/data/test-abidiff-exit/PR30048-test-2-report-1.txt b/tests/data/test-abidiff-exit/PR30048-test-2-report-1.txt
    index 2650b5a0..7bbbc2e2 100644
    --- a/tests/data/test-abidiff-exit/PR30048-test-2-report-1.txt
    +++ b/tests/data/test-abidiff-exit/PR30048-test-2-report-1.txt
    @@ -3,22 +3,22 @@ Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

     7 functions with some indirect sub-type change:

    -  [C] 'function int[7]* N()' at PR30048-test-2-v0.cc:62:1 has some indirect sub-type changes:
    +  [C] 'function int(*N(void))[7]' at PR30048-test-2-v0.cc:62:1 has some indirect sub-type changes:
	 return type changed:
    -      entity changed from 'int[7]*' to 'int'
    +      entity changed from 'int(*)[7]' to 'int'
	   type size changed from 64 to 32 (in bits)

    -  [C] 'function int* O()' at PR30048-test-2-v0.cc:64:1 has some indirect sub-type changes:
    +  [C] 'function int* O(void)' at PR30048-test-2-v0.cc:64:1 has some indirect sub-type changes:
	 return type changed:
	   entity changed from 'int*' to 'int'
	   type size changed from 64 to 32 (in bits)

    -  [C] 'function int ()* P()' at PR30048-test-2-v0.cc:67:1 has some indirect sub-type changes:
    +  [C] 'function int (*P(void))(void)' at PR30048-test-2-v0.cc:67:1 has some indirect sub-type changes:
	 return type changed:
    -      entity changed from 'int ()*' to 'int'
    +      entity changed from 'int (*)(void)' to 'int'
	   type size changed from 64 to 32 (in bits)

Note that the change to the CTF test
tests/data/test-read-ctf/test9.o.abi is triggered by a change in the
sorting of types because types are sorted alphabetically.

All in all, this is clearly an overdue improvement to the type name
pretty-printing.

	* include/abg-fwd.h (is_npaf_type, is_pointer_to_function_type)
	(is_pointer_to_array_type, is_pointer_to_npaf_type): Declare new
	functions.
	(is_pointer_type, is_reference_type, is_array_type): Take a
	boolean parameter to look through qualifiers.
	* include/abg-ir.h (is_pointer_type): Do not make this function a
	friend of the type_or_decl_base class anymore.
	* src/abg-ir.cc (pointer_declaration_name, array_declaration_name)
	(stream_pretty_representation_of_fn_parms)
	(add_outer_pointer_to_fn_type_expr)
	(add_outer_pointer_to_array_type_expr): Define new static
	functions.
	(is_npaf_type, is_pointer_to_function_type)
	(is_pointer_to_array_type, is_pointer_to_npaf_type): Define new
	functions.
	(get_type_representation): Remove the overload for array_type_def.
	(get_function_type_name, get_method_type_name)
	(function_decl::get_pretty_representation_of_declarator): Use the
	new stream_pretty_representation_of_fn_parms.  This actually
	factorizes parameters pretty-printing by reusing
	stream_pretty_representation_of_fn_parms.
	(is_pointer_type, is_reference_type, is_array_type): Take a
	boolean parameter to look through qualifiers.
	(is_void_pointer_type): Use const where it's due.
	(pointer_type_def::get_qualified_name): Use the new
	pointer_declaration_name in lieu of the old and removed
	get_name_of_pointer_to_type.
	(array_type_def::{get_pretty_representation, get_qualified_name}):
	Use the new array_declaration_name instead of the old and removed
	get_type_representation.
	(var_decl::get_pretty_representation): Use the new
	array_declaration_name and pointer_declaration_name.
	(function_decl::get_pretty_representation): Use the new
	add_outer_pointer_to_array_type_expr, and
	add_outer_pointer_to_array_type_expr function to support the
	proper syntax for function returning pointers and arrays.
	(function_decl::parameter::get_pretty_representation): Fix the
	pretty-printing of each function parameter.
	* tests/data/test-abicompat/test0-fn-changed-report-0.txt: Adjust.
	* tests/data/test-abicompat/test0-fn-changed-report-2.txt:
	Likewise.
	* tests/data/test-abicompat/test1-fn-removed-report-0.txt:
	Likewise.
	* tests/data/test-abicompat/test3-fn-removed-report-0.txt:
	Likewise.
	* tests/data/test-abidiff-exit/PR30048-test-2-report-1.txt: Likewise.
	* tests/data/test-abidiff-exit/PR30048-test-report-0.txt: Likewise.
	* tests/data/test-abidiff-exit/PR30329/PR30329-report-1.txt: Likewise.
	* tests/data/test-abidiff-exit/PR30503/libsdl/libsdl-1.2.60-1.2.64-report.txt: Likewise.
	* tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-1.txt: Likewise.
	* tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-2.txt: Likewise.
	* tests/data/test-abidiff-exit/qualifier-typedef-array-report-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test-fun-param-report.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test-ld-2.28-210.so--ld-2.28-211.so.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test-leaf-fun-type-report.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test-leaf-more-report.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test-leaf-peeling-report.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test-leaf-stats-report.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test-net-change-report0.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test-net-change-report2.txt:
	Likewise.
	* tests/data/test-abidiff-exit/test2-filtered-removed-fns-report0.txt:
	Likewise.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Likewise.
	* tests/data/test-abidiff/test-crc-report-0-1.txt: Likewise.
	* tests/data/test-abidiff/test-crc-report-1-0.txt: Likewise.
	* tests/data/test-abidiff/test-crc-report-1-2.txt: Likewise.
	* tests/data/test-annotate/test13-pr18894.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-annotate/test7.so.abi: Likewise.
	* tests/data/test-diff-dwarf/PR25058-liblttng-ctl-report-1.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test18-alias-sym-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test19-soname-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test24-added-fn-parms-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test32-fnptr-changes-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test33-fnref-changes-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test41-PR20476-hidden-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test5-report.txt: Likewise.
	* tests/data/test-diff-filter/test-PR26739-2-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test41-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test6-report.txt: Likewise.
	* tests/data/test-diff-filter/test7-report.txt: Likewise.
	* tests/data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/PR24690-report-0.txt: Likewise.
	* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/libxcrypt-4.1.1-6.el8.x86_64--libxcrypt-compat-4.4.18-3.el9.x86_64-report-1.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt:
	Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt:
	Likewise.
	* tests/data/test-diff-pkg-ctf/gmp-6.x.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg-ctf/test-rpm-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-0.txt:
	Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-3.txt:
	Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-5.txt:
	Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-7.txt:
	Likewise.
	* tests/data/test-diff-suppr/test15-suppr-added-fn-report-0.txt:
	Likewise.
	* tests/data/test-diff-suppr/test15-suppr-added-fn-report-2.txt:
	Likewise.
	* tests/data/test-diff-suppr/test15-suppr-added-fn-report-5.txt:
	Likewise.
	* tests/data/test-diff-suppr/test16-suppr-removed-fn-report-0.txt:
	Likewise.
	* tests/data/test-diff-suppr/test16-suppr-removed-fn-report-3.txt:
	Likewise.
	* tests/data/test-diff-suppr/test16-suppr-removed-fn-report-5.txt:
	Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-report-0.txt:
	Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-report-3.txt:
	Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-report-4.txt:
	Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-0.txt:
	Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-1.txt:
	Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-2.txt:
	Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-4.txt:
	Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-5.txt:
	Likewise.
	* tests/data/test-diff-suppr/test30-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test32-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test32-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test44-suppr-sym-name-not-regexp-report-1.txt:
	Likewise.
	* tests/data/test-fedabipkgdiff/vte291-0.39.1-1.fc22.x86_64--vte291-0.39.90-1.fc22.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-read-ctf/test9.o.abi: Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test7.so.abi: Likewise.
	* tests/data/test-read-dwarf/test7.so.hash.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-12-01 15:43:53 +01:00
Dodji Seketeli
89ab39de78 suppression: Add "has_strict_flexible_array_data_member_conversion" property
In the past, it was common to have a "fake flex array" at the end of a
structure. Like this:

Nowadays, with improved compiler support, it's more common to use a real
flex array. As this is a common change which changes ABI representation
in a compatible way, we should have a suppression for it.

For example, if you have a change like this:

struct foo
{
  int x;
  int flex[1];
};

...

struct foo
{
  int x;
  int flex[];
};

abidiff reports:

  [C] 'struct foo' changed:
    type size changed from 64 to 32 (in bits)
    1 data member change:
      type of 'int flex[1]' changed:
        type name changed from 'int[1]' to 'int[]'
        array type size changed from 32 to 'unknown'
        array type subrange 1 changed length from 1 to 'unknown'

With a new has_strict_flexible_array_data_member_conversion property,
users can specify a suppression which stops abidiff from emitting
this diff for any "fake" flex arrays being converted to real ones:

[suppress_type]
  type_kind = struct
  has_size_change = true
  has_strict_flexible_array_data_member_conversion = true

	* include/abg-comp-filter.h (has_strict_fam_conversion): Declare
	new functions.
	* include/abg-fwd.h
	(ir::has_fake_flexible_array_data_member): Declare new accessor
	functions.
	* include/abg-suppression.h
	(type_suppression::{,set_}has_strict_fam_conversion): Declare new
	accessor functions.
	* src/abg-comp-filter.cc (has_strict_fam_conversion): Define new
	functions.
	* src/abg-ir.cc
	(ir::has_fake_flexible_array_data_member): Define new accessor
	functions.
	* src/abg-suppression-priv.h
	(type_suppression::priv::has_strict_fam_conv_): Define new
	data member.
	* src/abg-suppression.cc
	(type_suppression::{,set_}has_strict_fam_conversion): Define new
	accessor functions.
	(type_suppression::suppresses_diff): For a type suppression to
	match a fake flex array conversion, either the size of the type
	hasn't change or has_size_change must be true and then the type
	must change from a fake flex array to a real flex array.
	(read_type_suppression): Parse the new
	'has_strict_flexible_array_data_member_conversion' property to
	set the type_suppression::set_has_strict_fam_conversion property.
	* doc/manuals/libabigail-concepts.rst: Add an entry for the new
	'has_strict_flexible_array_data_member_conversion' property.
	* tests/data/test-diff-suppr/test-has-strict-flexible-array-data-member-conversion-{1,2}.suppr:
	Add new test suppression files.
	* tests/data/test-diff-suppr/test-has-strict-flexible-array-data-member-conversion-report-{1,2}.txt:
	Add new test reference output files.
	* tests/data/test-diff-suppr/test-has-strict-flexible-array-data-member-conversion-v{0,1}.c:
	Add source code for new binary test input files.
	* tests/data/test-diff-suppr/test-has-strict-flexible-array-data-member-conversion-v{0,1}.o:
	Add new binary test input files.
	* tests/data/Makefile.am: Add the new test files to the source
	distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the new test input
	files to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Signed-off-by: John Moon <quic_johmoo@quicinc.com>
2023-11-15 09:55:08 +01:00
Dodji Seketeli
b12ba51e62 Support suppressing data member insertion before a flexible array member
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>
2023-10-18 11:08:58 +02:00
Dodji Seketeli
d38ee66d6b comparison: Represent changed unreachable anonymous unions, structs & enums
Following the changes to represent changed anonymous unreachable enums,
this patch does the same for anonymous unreachable unions, classes and
structs.

Basically, without this patch, this change:

    union
    {
      int a;
      int b;
    };

    ------

    union
    {
      int a;
      int b;
      int c;
    };

yields:

    1 removed type unreachable from any public interface:

      [D] 'union {int a; int b;}' at test_1.c:1:1

    1 added type unreachable from any public interface:

      [A] 'union {int a; int b; int c;}' at test_2.c:1:1

But with the patch, it does yield:

    1 changed type unreachable from any public interface:

      [C] 'union {int a; int b;}' changed:
	type size hasn't changed
	1 data member insertion:
	  'int c' at test-anon-union-v1.c:5:1
	type changed from:
	  union {int a; int b;}
	to:
	  union {int a; int b; int c;}

	* include/abg-fwd.h (class_or_union_types_of_same_kind)
	(is_data_member_of_anonymous_class_or_union): Declare new
	functions.
	* include/abg-ir.h (lookup_data_member): Likewise, declare a new overload.
	* src/abg-ir.cc (class_or_union_types_of_same_kind)
	(lookup_data_member, is_data_member_of_anonymous_class_or_union):
	Define news functions & overloads.
	* src/abg-reporter-priv.cc (represent): When representing a change
	in the name of a data member, if the context is an anonymous type,
	use the non-qualified name of the data member, not its qualified
	name.
	* src/abg-comparison.cc
	(corpus_diff::priv::ensure_lookup_tables_populated): Handle
	deleted/added anonymous enums, unions, classes and structs
	similarly.  That is, if an anonymous type was removed and another
	one got added, if they both have data members (or enumerators) in
	common, then we are probably looking at an anonymous type that was
	changed.  This is because these anonymous types are named using
	their flat representation.
	* tests/data/test-abidiff-exit/test-anon-types-report-1.txt: New
	reference test comparison output.
	* tests/data/test-abidiff-exit/test-anon-types-v{0,1}.o: New
	binary tests input files.
	* tests/data/test-abidiff-exit/test-anon-types-v{0,1}.c: Source
	code of new binary test input.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-abidiff-exit.cc (in_out_specs): Add the test inputs
	above to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-17 10:50:51 +02:00
Dodji Seketeli
40f11c58f3 ir,comparison: Represent changed anonymous enums
Now that added/removed non-reachable anonymous enums is supported, we
want to represent changing an anonymous enum.

Strictly speaking, adding or removing an enumerator from an anonymous
enum is represented as deleting of the anonymous enum in the old
state and the addition of an anonymous enum in the new state.

This patch analyses the added/removed anonymous enums and if the old
enum has enumerators contained in the new one, then it assumes we are
looking at anonymous enum change.

	* include/abg-ir.h (is_enumerator_present_in_enum): Declare new
	public function.
	* src/abg-ir.cc (is_enumerator_present_in_enum): Turn this
	static function into a public one.
	* src/abg-comparison.cc
	(corpus_diff::priv::ensure_lookup_tables_populated): Detect that
	an removed/added anonymous enum is actually a changed anonymous
	enum and represent it as such.
	* tests/data/test-abidiff-exit/test-anonymous-enums-change-report-v{0,1}.txt:
	New reference test output files.
	* tests/data/test-abidiff-exit/test-anonymous-enums-change-v{0,1}.c:
	Source code for the some input test binary.
	* tests/data/test-abidiff-exit/test-anonymous-enums-change-v{0,1}.o:
	New test input binaries.
	* tests/data/Makefile.am: Add the new test materials above to
	source distribution.
	* tests/test-abidiff-exit.cc (in_out_specs): Add the new test
	input to the harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-17 10:50:51 +02:00
Dodji Seketeli
2604ff2d28 ir,comparison,corpus: Better support anonymous enums comparison
Anonymous enums are designated using their internal names which are
automatically generated.  The problem however is that whenever a new
anonymous enum gets inserted in the translation unit, that can
randomly change the name of existing anonymous enums.  This makes
reporting of changes in anonymous enums essentially useless.

To address this issue, this patch uses flat representation for
anonymous enums, for the purpose of designating them outside of the
context of type canonicalization.  This is like what is done already
for anonymous classes and unions.

	* include/abg-fwd.h (get_enum_flat_representation)
	(get_class_or_enum_flat_representation): Declare new functions.
	* include/abg-ir.h (enum_type_decl::get_sorted_enumerators):
	Declare new member functions.
	* src/abg-comparison.cc
	(corpus_diff::priv::{ensure_lookup_tables_populated,
	added_unreachable_type_is_suppressed,
	deleted_unreachable_type_is_suppressed,
	record_type_as_reachable_from_public_interfaces}): Use
	non-internal pretty representation to designate ABI artifacts so
	that anonymous enums get designated by their flat representation.
	* src/abg-corpus.cc (corpus::type_is_reachable_from_public_interfaces):
	Likewise.
	* src/abg-ir.cc (get_type_name): The type name of an anonymous
	enum or class should is now the flat representation if we are not
	in the context of type canonicalization.
	(enum_type_decl::get_pretty_representation): If we are not in the
	context of type canonicalization, the pretty representation of an
	enum is its flat representation.
	(get_enum_flat_representation)
	(get_class_or_enum_flat_representation): Define new functions.
	(enum_type_decl::get_sorted_enumerators): Likewise.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-annotate/test-anonymous-members-0.o.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-diff-dwarf/test43-PR22913-report-0.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-17 10:50:51 +02:00
John Moon
b879ba8175 suppression: Add "changed_enumerators_regexp" property
Currently, users are able to suppress changes to enumerator variants
matching names specified in "changed_enumerators", but can't specify
regular expressions.

A common pattern when using enums is to have the final enum variant
labeled as "*_MAX" or "*_LAST" so that users of the enum can have a
way to determine how many variants there are. In these cases, when
expanding an enum, the last variant will change, but that's an
expected result that users may not want to flag as an ABI-breaking
change.

For example, if you have a change like this:

enum foo {
        FOO,
        BAR,
        FOOBAR_MAX,
};

...

enum foo {
        FOO,
        BAR,
        BAZ,
        FOOBAR_MAX,
};

abidiff reports:

1 changed type unreachable from any public interface:

  [C] 'enum foo' changed:
    type size hasn't changed
    1 enumerator insertion:
      'foo::BAZ' value '2'
    1 enumerator change:
      'foo::FOOBAR_MAX' from value '2' to '3' at test_2.c:1:1

With a new changed_enumerators_regexp property, users can specify a
suppression which stops abidiff from emitting this diff for any
members which match the regular expressions in the list:

[suppress_type]
  type_kind = enum
  changed_enumerators_regexp = .*_MAX$, .*_LAST$, .*_NUM$, .*_NBITS$

	* include/abg-suppression.h
	(type_suppression::{g,s}et_changed_enumerators_regexp): Declare new
	accessor functions.
	* src/abg-suppression-priv.h
	(type_suppression::priv::changed_enumerators_regexp_): Define new
	data member.
	* src/abg-suppression.cc
	(type_suppression::{g,s}et_changed_enumerators_regexp): Define new
	accessor function.
	(type_suppression::suppresses_diff): For a type suppression to
	match an enum_diff, the names of all changed enumerators must
	match either the names returned by
	type_suppression::get_changed_enumerator_names or one of the
	regexps returned by the new member function
	type_suppression::get_changed_enumerators_regexp.
	(read_type_suppression): Parse the new
	'changed_enumerators_regexp' property to set the
	type_suppression::get_changed_enumerators_regexp property.
	* doc/manuals/libabigail-concepts.rst: Add an entry for the new
	'changed_enumerators_regexp' property.
	* tests/data/test-diff-suppr/test40.1-enumerator-changes-enumerator-changes-[1-5].suppr:
	Add new test suppression files.
	* tests/data/test-diff-suppr/test40.1-enumerator-changes-enumerator-changes-report-[0-5].txt:
	Add new test reference output files.
	* tests/data/test-diff-suppr/test40.1-enumerator-changes-enumerator-changes-v{0,1}.c:
	Add source code for new binary test input files.
	* tests/data/test-diff-suppr/test40.1-enumerator-changes-enumerator-changes-v{0,1}.o:
	Add new binary test input files.
	* tests/data/Makefile.am: Add the new test files to the source
	distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the new test input
	files to this test harness.

Signed-off-by: John Moon <quic_johmoo@quicinc.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-17 10:50:51 +02:00
Dodji Seketeli
a125607873 Bug 30971 - Wrong interpretation of "has_data_member_inserted_at"
Consider the following construct:

    struct foo
    {
      long x;
      long y;
    };

Then change one of the types (but keep the size the same):

    struct foo
    {
      long x;
      unsigned long y;
    };

If I abidiff this with no suppressions, I get:

      [C] 'struct foo' changed:
	type size hasn't changed
	1 data member change:
	  type of 'long int y' changed:
	    type name changed from 'long int' to 'unsigned long int'
	    type size hasn't changed

However, it seems like if I add any struct suppression involving data member
insertions, it filters out the change. For example:

    [suppress_type]
	    type_kind = struct
	    has_data_member_inserted_at = offset_of(not_present)

The "not_present" member isn't in "struct foo", so I would expect the diff to
still be emitted, but it is not:

    Functions changes summary: 0 Removed, 0 Changed, 0 Added function
    Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
    Unreachable types summary: 0 removed, 0 changed (1 filtered out), 0 added type

This is because during the evaluation of the
"has_data_member_inserted_at" property, we fail to take into account
that if no data member got inserted, evaluation of the
"has_data_member_inserted_at" predicate is falsified, and thus, the
type suppression is falsified.

While looking at this, I also realized that when a data member
replaces another one, we fail to consider that change as a data member
insertion and so the evaluation of the "has_data_member_inserted_at"
predicate is wrongly falsified.

This patch fixes these two related issues.

	* include/abg-comparison.h
	(class_or_union_diff::changed_data_members): Declare new accessor.
	function.
	* src/abg-comparison.cc
	(class_or_union_diff::changed_data_members): Define new accessor.
	function.
	* src/abg-suppression.cc (type_suppression::suppresses_diff): If
	the type suppression specification contains a
	has_data_member_inserted_* property and yet the class contains no
	data member inserted or replacing an existing one, then the type
	suppression is falsified in the context of the current change.
	Also, when a data member replaces an existing one, consider that
	as an insertion for which the has_data_member_inserted_* predicate
	should be evaluated.  Stop considering deleted data members
	because considering replaced data member is really what we meant.
	* tests/data/test-diff-suppr/test-has-data-member-inserted-at-2-report.[1-3].txt:
	New reference test output files.
	* tests/data/test-diff-suppr/test-has-data-member-inserted-at-2-report.txt:
	Likewise.
	* tests/data/test-diff-suppr/test-has-data-member-inserted-at-{2,3}-v{0,1}.o:
	New input test binaries.
	* tests/data/test-diff-suppr/test-has-data-member-inserted-at-{2,3}-v{0,1}.c:
	Source code of the new input test binaries.
	* tests/data/test-diff-suppr/test-has-data-member-inserted-at-2.2.suppr:
	New input test suppression specification.
	* tests/data/test-diff-suppr/test-has-data-member-inserted-at-2.suppr: Likewise.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the test input
	above to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Tested-by: John Moon <quic_johmoo@quicinc.com>
2023-10-17 10:32:38 +02:00
Dodji Seketeli
400673935d ir: Remove redundant virtual member functions
G++ 13.2.1 complains that virtual member functions
{qualified_type_def,pointer_type_def,class_or_union}::operator!= are
redundant with type_base::operator!=, and rightfully so.  This patch
removes those useless virtual member functions.

	* include/abg-ir.h
	({qualified_type_def,pointer_type_def,class_or_union}::operator!=):
	Remove these redundant virtual data members.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-12 13:28:43 +02:00
Dodji Seketeli
04737bcc84 suppression: Fix indentation
* include/abg-suppression.h: Fix indentation of the
	type_suppression::insertion_range::end() accessor.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-05 17:09:45 +02:00
Dodji Seketeli
d8de76cfa8 ir: Use non qualified typedef name for type canonicalization
While looking into fixing self-comparison errors for the gcc-gnat
package[1], I stumbled upon the fact that a typedef that is defined in
the global scope is different from a typedef defined in a scope, even
if they both point to the same underlying type.  This is a spurious
difference that feeds a spurious explosion of the number of canonical
types, for no reason.  It can lead to spurious self-comparison errors
down the road.  Sadly, fixing this issue is not enough to fix the
self-comparison error in [1].

[1]: The command is:

    $ fedabipkgdiff --self-compare  -a --from fc37 gcc-gnat

	* include/abg-ir.h (reference_type_def::{pointed_to_type_,
	is_lvalue_}): Remove these data members.
	(reference_type_def::priv_): Add a unique data member.
	(typedef_decl::get_qualified_name): Add new virtual member
	functions.
	* src/abg-ir.cc (get_decl_name_for_comparison): If the decl we are
	comparing is a typedef, only consider its non-qualified name.
	(get_type_name): For internal purposes, the type name of a typedef
	is its non-qualified name.
	(pointer_type_def::get_qualified_name): For internal purposes, if
	the pointed-to name is a typedef, use the non-qualified name of
	the typedef.
	(reference_type_def::priv): Define new data type.
	(reference_type_def::reference_type_def): Initialize the new
	reference_type_def::priv_ data member and adjust to the move of
	the reference_type_def::pointed_to_type_ data member to
	reference_type_def::priv::pointed_to_type_.
	(reference_type_def::{s,g}et_pointed_to_type): Adjust.
	(reference_type_def::is_lvalue): Likewise.
	(reference_type_def::get_qualified_name): Support caching
	qualified names for internal and non-internal purposes.
	(typedef_decl::get_pretty_representation): For internal purposes,
	use non-qualified typedef name.
	(typedef_decl::get_qualified_name): Define the two overloads for
	this virtual member function.
	(function_decl::get_pretty_representation): Use the
	'qualified_name' parameter.  Also, rather than systematically
	using the qualified name of the return type, use get_type_name
	instead that knows when to use qualified names and when not to.
	(qualified_name_setter::do_update):
	* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test0.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Likewise.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli
0239f89b4f ir: Really avoid canonicalizing decl-only classes
is_non_canonicalized_type uses is_declaration_only_class_or_union_type
to detect decl-only classes, but it doesn't differentiate between
decl-only classes that are associated to a class definition and those
that are not.

We want to avoid canonicalizing decl-only classes that are not
associated to any class definition.

This patch fixes the invocation of
is_declaration_only_class_or_union_type to express the above
assertion.

This fix uncovered another self-comparison issue that was being
expressed when running the command below:

    $ abidw --abidiff tests/data/test-types-stability/PR27086-libstdc++.so.6.0.26

That one was due to an error in method_decl::set_linkage_name which
was making classes contain the wrong overloads of methods.  The patch
fixes that error too.

	* include/abg-fwd.h (is_pointer_to_decl_only_class_or_union_type)
	(is_reference_to_decl_only_class_or_union_type)
	(is_typedef_to_decl_only_class_or_union_type): Remove declarations.
	(is_typedef_ptr_or_ref_to_decl_only_class_or_union_type): Declare
	new function.
	* src/abg-ir.cc (is_pointer_to_decl_only_class_or_union_type)
	(is_reference_to_decl_only_class_or_union_type)
	(is_typedef_to_decl_only_class_or_union_type): Remove definitions.
	(is_typedef_ptr_or_ref_to_decl_only_class_or_union_type): Define
	new function.
	(is_non_canonicalized_type): Change the invocation of
	is_declaration_only_class_or_union_type to make it look through
	decl-only types.  Use
	is_typedef_ptr_or_ref_to_decl_only_class_or_union_type in lieu of
	is_{pointer,reference,typedef}_to_decl_only_class_or_union_type
	that got removed.
	(method_decl::set_linkage_name): Remove the mapping between the
	method and the old linkage name, only if the old name is different
	from the new name.  Duh.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli
4071543456 abipkgdiff: Initialize libxml2 to use it in a multi-thread context
While running some test, I stumbled upon a transient deadlock
happening when using libxml2's text reader to create a reader from a
buffer.  After reading the documentation at
https://gitlab.gnome.org/GNOME/libxml2/-/wikis/Thread-safety, I
realized that users of the library need to initialize libxml2 before
using it in a multi-thread setting.

So this patch is providing the abigail::tools_utils::initialize()
function to be called prior to using the library.  This is going to be
the place where to perform this kind of one-time initialization.

	* include/abg-tools-utils.h (initialize): Declare ...
	* src/abg-tools-utils.cc (initialize): ... new function.
	* tools/abipkgdiff.cc (main): Invoke the new
	abigail::tools_utils::initialize() here.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Giuliano Procida
9ac01c4141 operator!= fixes for C++-20
Without these changes, more recent versions of Clang will start to
emit diagnostics:

src/abg-ir.cc:15407:13: error: member 'operator!=' found in multiple base classes of different types
 15407 |   return *l == *r;
       |             ^
src/abg-ir.cc:14123:12: note: member found by ambiguous name lookup
 14123 | type_base::operator!=(const type_base& other) const
       |            ^
src/abg-ir.cc:5162:12: note: member found by ambiguous name lookup
 5162 | decl_base::operator!=(const decl_base& other) const
      |            ^

This fix was contributed by Ilya Biryukov.

	* include/abg-ir.h
	(qualified_typedef): Add definition of operator!=.
	(pointer_type_def): Likewise.
	(reference_type_def): Likewise.
	(class_or_union): Likewise.

Reported-by: Ilya Biryukov <ibiryukov@google.com>
Signed-off-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:22:44 +02:00
Dodji Seketeli
a30a3146b5 corpus,tools-utils: Support loading a corpus, its deps & other binaries
In preparation of implementing the support for "Handling split
libraries", this patch implements the functions
tools_utils::{get_comma_separated_args_of_option,
find_file_under_dirs, add_binaries_into_corpus_group,
add_dependencies_into_corpus_group,
stick_corpus_and_binaries_into_corpus_group,
stick_corpus_and_dependencies_into_corpus_group, get_dependencies}.

Given an ABI corpus, these functions enable adding arbitrary binaries
and dependencies found in a set of directories to form a corpus group.

	* include/abg-corpus.h (corpus_group::has_corpus): Declare new
	member function.
	* include/abg-tools-utils.h (get_comma_separated_args_of_option)
	(find_file_under_dirs, get_dependencies)
	(add_binaries_into_corpus_group)
	(add_dependencies_into_corpus_group)
	(stick_corpus_and_binaries_into_corpus_group)
	(stick_corpus_and_dependencies_into_corpus_group): Declare new
	functions.
	* src/abg-corpus.cc (corpus_group::priv::corpora_path): Add new
	data member.
	(corpus_group::add_corpus):  Do not add a corpus that was already
	added to the group.  Update the set of paths of added corpora so
	that we can detect if a corpus has already been added.
	* src/abg-tools-utils.cc (find_file_under_dir): If the file found
	is a symbolic link, return it.  Otherwise if the symbolic link is
	not the file we were looking for, then skip it, rather than
	following it, in case it's a directory.
	(get_comma_separated_args_of_option, find_file_under_dirs)
	(get_dependencies, add_binaries_into_corpus_group)
	(add_dependencies_into_corpus_group)
	(stick_corpus_and_binaries_into_corpus_group)
	(stick_corpus_and_dependencies_into_corpus_group): New functions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-07 13:34:39 +02:00
Dodji Seketeli
e8a61b1af2 Make fe_iface::initialize independent from the kind of interface
In the use case laid out by the "Library Splitting support" at
https://sourceware.org/bugzilla/show_bug.cgi?id=30034, tools might
want to be able to re-initialize a given front-end to load several
corpora in a row, independently from the kind of front-end (elf-based,
ABIXML, etc).  So we need a fe_iface::initialize() interface that is
similar to the elf_based_reader::initialize() interface but, unlike
that one, it should not depend on parameters that only make sense in a
elf-based context.  For instance, the fe_iface::initialize() interface
should not contain paths to debug-info as that information does not
make sense in an ABIXML context.

This patch thus renames fe_iface::reset() into fe_iface::initialize()
and makes it virtual.  It adjusts the plumbing accordingly, basically
making the other ::initialize() methods of classes that inherit
fe_iface use fe_iface::initialize() when appropriate.

The patch also provides an elf_based_reader::initialize()
implementation of the fe_iface::initialize() interface, so that
invoking ::initialize on elf_based_reader through the fe_iface
interface does the right thing so that the initial use case presented
at the beginning of this comment is supported.

	* include/abg-elf-based-reader.h (elf_based_reader::initialize):
	Rename elf_based_reader::reset into this.  Add a new virtual
	overload that implements fe_iface::initialize.
	* include/abg-elf-reader.h (reader::initialize): Rename
	elf_reader::reset into this.  Add a new virtual overload that
	implements fe_iface::initialize.
	* include/abg-fe-iface.h (fe_iface::initialize): Rename
	fe_iface::reset into this and make it virtual.
	* src/abg-btf-reader.cc (btf::reader::initialize): Adjust call to
	elf_based_reader::reset to elf_based_reader::initialize.
	* src/abg-ctf-reader.cc (ctf::reader::initialize): Likewise.
	* src/abg-dwarf-reader.cc (dwarf::reader::initialize): Likewise.
	* src/abg-elf-based-reader.cc (elf_based_reader::initialize):
	Rename elf_based_reader::reset into this.  Adjust call to
	elf::reader::reset into elf::reader::initialize.  Add a new
	virtual overload that implements fe_iface::initialize.
	* src/abg-elf-reader.cc (reader::initialize): Rename
	elf::reader::reset into this. Adjust call to fe_iface::reset into
	fe_iface::initialize.  Add a new virtual overload that implements
	fe_iface::initialize.
	* src/abg-fe-iface.cc (fe_iface::priv::initialize): Reset the
	corpus too.
	(fe_iface::initialize): Rename fe_iface::reset into this.  Invoke
	priv::initialize and set the new corpus_path.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-07 13:34:15 +02:00
Dodji Seketeli
7b565f399e Bug 30503 - Fail to compare non-anonymous struct vs named struct data members
Since this commit

    commit 321da66678
    Author: Dodji Seketeli <dodji@redhat.com>
    Date:   Tue Sep 14 18:11:39 2021 +0200

	Bug 28316 - Failure to represent typedef named anonymous enums

It seems like comparing a data member of a non-anonymous struct foo
against the same data member of an anonymous struct named by a typedef
foo wrongly leads yields a spurious difference.

This is because when looking at the data member,
get_decl_name_for_comparison doesn't return the same value in the two
cases (non anonymous struct foo vs anonymous struct named by a typedef
foo).  Looking deeper, it's because get_decl_name_for_comparison
wronly uses scope_anonymous_or_typedef_named.  Fixed thus.

	* src/abg-ir.cc (get_decl_name_for_comparison): Do not use
	scope_anonymous_or_typedef_named.  Rather, use
	decl_base::get_has_anonymous_parent instead.
	(scope_anonymous_or_typedef_named): Remove this as it's not used
	anymore.
	* include/abg-fwd.h (scope_anonymous_or_typedef_named): Remove
	this declaration as the definition has been removed.
	* tests/data/test-abidiff-exit/PR30503/libsdl/1.2.60/lib64/libSDL-1.2.so.1.2.60:
	New test input file.
	* tests/data/test-abidiff-exit/PR30503/libsdl/1.2.60/lib64/libSDL-1.2.so.1.2.60.debug:
	Likewise.
	* tests/data/test-abidiff-exit/PR30503/libsdl/1.2.64/lib64/libSDL-1.2.so.1.2.64:
	Likewise.
	* tests/data/test-abidiff-exit/PR30503/libsdl/1.2.64/lib64/libSDL-1.2.so.1.2.64.debug:
	Likewise.
	* tests/data/test-abidiff-exit/PR30503/libsdl/libsdl-1.2.60-1.2.64-report.txt:
	Likewise.
	* tests/data/Makefile.am: Add the new test inputs above to source
	distribution.
	* tests/test-abidiff-exit.cc (in_out_specs): Add the new test
	inputs above to this test harness.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-06-07 14:12:11 +02:00
Dodji Seketeli
d00a2cc2da Bug 30466 - harfbuzz fails self-check on f38
Since this commit:

    commit 43cbdd1501
    Author: Dodji Seketeli <dodji@redhat.com>
    Date:   Thu Apr 13 16:48:52 2023 +0200

	ir: Recognize "void* as being equal to all other pointers in C

a pointer to void is considered equal to all other pointers to avoid
emitting some spurious changes while self-comparing glibc from fc37.

As a void pointer can now equal several kinds of types, it could no
longer be canonicalized.  But then, the 'exemplar pointer' based
optimization in the ABIXML writer (cf get_exemplar_type) makes it so
that two different void pointer IR nodes (that are structurally
equivalent) would result in two different nodes (with different
type-ids) being serialized out in ABIXML.  Later at ABIXML reading
time, aggregates types using these two different void pointer nodes
might yield canonical types that are different from the original ones,
depending on the order in which ABIXML types are canonicalized as that
order might differ from the order in which they were initially
canonicalized.  This difference leads to spurious self-comparison
errors.

To handle this, I am proposing that the void pointer type be a unique
IR type node in the system.  That way, the exemplar type optimization
would still work and we get rid of the spurious self-comparison error
change.  While doing this, I realized that the void type and the
variadic parameter type that are also unique types were not properly
enforced in all the front-ends as such.  So this patch fixes that.

The patch also make typedefs and pointer to decl-only classes be
non-canonicalized types because decl-only classes are non-canonicalized
already.  Pointers and typedefs to those types being canonicalized can
lead to different canonicalized type depending on the order of
canonicalization.

The rest of the patch is basically adjusting the other moving parts to
these core changes.

	* include/abg-fwd.h (is_pointer_to_decl_only_class_or_union_type)
	(is_reference_to_decl_only_class_or_union_type)
	(is_typedef_to_decl_only_class_or_union_type)
	(is_void_pointer_type_equivalent, is_unique_type): Declare new
	functions.
	(is_typedef, is_void_pointer_type): Declare new overloads.
	(is_declaration_only_class_or_union_type): Add a new
	look_through_decl_only flag as parameter.
	* include/abg-ir.h (environment::{get_void_pointer_type,
	is_void_pointer_type}): Define new member functions.
	* src/abg-ir-priv.h (environment::priv::{void_pointer_type}): Add
	new data member.
	* src/abg-ir.cc (decl_topo_comp::operator()): For unique types,
	use lexicographic sorting.
	(environment::{get_void_pointer_type, is_void_pointer_type}):
	Define new member function.
	(is_typedef, is_pointer_to_decl_only_class_or_union_type)
	(is_reference_to_decl_only_class_or_union_type)
	(is_typedef_to_decl_only_class_or_union_type, is_unique_type):
	Define new functions.
	(is_declaration_only_class_or_union_type): Add a new
	look_through_decl_only parameter.  Some decl-only class or union
	do have an associated definition; this function return false for
	these types if look_through_decl_only is set to true.
	(is_void_pointer_type_equivalent): Rename is_void_pointer_type
	into this.
	(is_void_pointer_type): Now that is_void_pointer_type equals is
	old version of this is_void_poitner, make the new version test if
	the type equals the unique void pointer type, or if it a pointer
	to void type.  It doesn't take typedefs into account, like what
	is_void_pointer_type_equivalent does.
	(equals): In the overload for pointer_type_def, use the new
	is_void_pointer_type_equivalent instead of
	is_void_pointer_type_equivalent.
	(is_non_canonicalized_type): Re-organize this.  Now, all unique
	types are non-canonicalized.  This was sort-of the case already
	but was not clearly stated as such.  The decl-only class-or-union
	types were already non-canonicalized, but pointers and typedefs to
	class-or-unions should also be non-canonicalized for the system to
	work because a decl-only class-or-unions equals all defined types
	in C++.
	* src/abg-btf-reader.cc
	(reader::build_ir_node_for_void_pointer_type): Define new member
	function that return a unique type for void pointer types.
	(reader::build_pointer_type): Use
	build_ir_node_for_void_pointer_type to build void pointer types.
	(reader::{build_ir_node_for_void_type,
	build_ir_node_for_variadic_parameter_type}): Simplify.
	* src/abg-ctf-reader.cc (build_ir_node_for_void_type)
	(build_ir_node_for_void_pointer_type): Define new functions.
	(process_ctf_function_type): Use build_ir_node_for_void_type for
	void types.
	(process_ctf_pointer_type): Use
	build_ir_node_for_void_pointer_type for void pointer types.
	* src/abg-dwarf-reader.cc (build_ir_node_for_void_pointer_type):
	Define a new function that returns a unique type for void pointer
	types.
	(build_pointer_type_def): Use the new
	build_ir_node_for_void_pointer_type to build void pointers.
	(build_ir_node_for_variadic_parameter_type): Simplify.
	* src/abg-reader.cc (read_type_id_string): Define this even
	not debugging self-comparison.
	(build_ir_node_for_void_type)
	(build_ir_node_for_void_pointer_type): Define new functions.
	(reader::{get_scope_for_node, get_scope_ptr_for_node}): New member
	functions.
	(reader::push_decl_to_current_scope): Remove this member function.
	This was using the scope of the last IR node built as the current
	scope.  The problem is that the scope of a unique IR node is the
	scope where it was used the first time; that has nothing to do
	with the current scope.  So this function is obsolete now that we
	are using unique IR nodes for real.
	(reader::push_decl_to_scope): New member function.  This is the
	one to use, now that push_decl_to_current_scope is no more.
	(reader::push_and_key_type_decl): Pass the scope_decl to use.
	Make this push the decl to the scope passed in parameter.  Add an
	overload that has the XML node to use to determine the scope to
	push the decl to.
	(reader::get_scope_for_node): Support template parameter type
	composition nodes.  Also, add an overload that takes just an XML
	node.
	(reader::get_scope_ptr_for_node): Define new member function.
	(build_namespace_decl, build_function_decl, build_var_decl): Use
	to reader::push_decl_to_scope, now that
	reader::push_decl_to_current_scope is gone.
	(build_type_decl): Use build_ir_node_for_void_type to build a void
	type.  Adjust the call to reader::push_and_key_type_decl.
	(build_qualified_type_decl, build_reference_type_def)
	(build_subrange_type, build_array_type_def, build_enum_type_decl)
	(build_typedef_decl, build_class_decl, build_union_decl)
	(build_function_tdecl, build_function_tdecl, build_class_tdecl)
	(build_type_tparameter, build_type_composition)
	(build_non_type_tparameter, build_template_tparameter): Adjust the
	call to reader::push_and_key_type_decl.
	(build_pointer_type_def): Likewise.  Use
	build_ir_node_for_void_pointer_type to build a void pointer IR
	node.  Also, build the pointed-to-type before the pointer type
	itself; this is required to catch a void pointer type early and
	use build_ir_node_for_void_pointer_type to build it.
	* src/abg-comp-filter.cc (has_void_ptr_to_ptr_change): Use the new
	is_void_pointer_type_equivalent in lieu of is_void_pointer_type.
	This is because the former takes typedefs into account and so is
	more accurate.
	* src/abg-comparison.cc
	(scope_diff::ensure_lookup_tables_populated): Do not consider
	unique types when accounting for added/removed types.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test-anonymous-members-0.o.abi: Likewise.
	* tests/data/test-annotate/test0.abi: Likewise.
	* tests/data/test-annotate/test1.abi: Likewise.
	* tests/data/test-annotate/test13-pr18894.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test2.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-annotate/test3.so.abi: Likewise.
	* tests/data/test-annotate/test5.o.abi: Likewise.
	* tests/data/test-read-btf/test1.o.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test8.o.abi: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR24378-fn-is-not-scope.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise.
	* tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR27700/test-PR27700.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-PR26568-1.o.abi: Likewise.
	* tests/data/test-read-dwarf/test-PR26568-2.o.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-suppressed-alias.o.abi:
	Likewise.
	* tests/data/test-read-dwarf/test0.abi: Likewise.
	* tests/data/test-read-dwarf/test0.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test2.so.abi: Likewise.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test3-alias-1.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-3.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-4.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3.so.abi: Likewise.
	* tests/data/test-read-dwarf/test3.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test5.o.abi: Likewise.
	* tests/data/test-read-dwarf/test5.o.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test17.xml: Likewise.
	* tests/data/test-read-write/test18.xml: Likewise.
	* tests/data/test-read-write/test19.xml: Likewise.
	* tests/data/test-read-write/test20.xml: Likewise.
	* tests/data/test-read-write/test21.xml: Likewise.
	* tests/data/test-read-write/test22.xml: Likewise.
	* tests/data/test-read-write/test23.xml: Likewise.
	* tests/data/test-read-write/test26.xml: Likewise.
	* tests/data/test-read-write/test27.xml: Likewise.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Likewise.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-06-02 17:46:57 +02:00
Dodji Seketeli
0f48cb2172 reader: Recognize variadic parameter type from abixml
When reading a variadic parameter type from the ABIXML, the reader
forget to recognize it as THE unique variadic parameter type as
returned by abigail::ir::environment::get_variadic_parameter_type().
That makes abigil::ir::environment::is_variadic_parameter_type() to
fail on the variadic type that is build from ABIXML.

Fixed thus.

	* include/abg-ir.h (environment::get_variadic_parameter_type_name)
	Declare ...
	* src/abg-ir.cc (environment::get_variadic_parameter_type_name):
	... a new static member function.
	(environment::get_variadic_parameter_type): Use
	the new environment::get_variadic_parameter_type_name rather than
	using an open coded constant here.
	* src/abg-dwarf-reader.cc
	(die_return_and_parm_names_from_fn_type_die): Likewise.
	* src/abg-reader.cc (build_type_decl):  For a variadic parameter
	type, return
	abigail::ir::environment::get_variadic_parameter_type() rather
	than building a new type.
	* tests/data/test-read-ctf/test2.so.abi: Adjust.
	* tests/data/test-read-ctf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test8.o.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-04-25 15:50:26 +02:00