Commit Graph

1596 Commits

Author SHA1 Message Date
Dodji Seketeli
e95f8cbac2 Update 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
After the preceding patch series to handle ABI corpora in which the
ODR is not applicable (and the inevitable fallouts) this patch updates
the reference output for the test-diff-pkg test harness.

	* 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: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:23:39 +01:00
Dodji Seketeli
772414848e Update tests/data/test-read-write/test27.xml
After the preceding patch series to handle ABI corpora in which the
ODR is not applicable (and the inevitable fallouts) this patch updates
the reference output for the test-read-write test harness.

	* tests/data/test-read-write/test27.xml: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:22:54 +01:00
Dodji Seketeli
1fcdebe47a [dwarf-reader] Handle per translation-unit type de-duplication
Until now, when the elf/dwarf reader builds ABI artifacts, it performs
type de-duplication by considering that a type with a given name should
be defined only once in a given ABI corpus.  This is per-corpus
de-duplication.

The problem with that approach is that it assumes that the binary
respects the One Definition Rule[1], aka ODR.  But then many non-C++
binaries don't respect the ODR.

So, for non-c++ binaries, we shouldn't assume the ODR.  We should be
able to assume a per translation unit (aka per-tu) de-duplication.
That is, consider that a type with a given name is defined just once
in a given translation unit.  Or perform no de-deplication at all,
depending on the kind of type we are looking at.

And this is what this patch does.  It allows the ELF/DWARF reader to
perform per-tu type de-duplication by assuming that it's only in a given
translation unit that a type definition must be unique.  It also allows it
perform no de-duplication at all for some kind of types.

In practice, function types are de-duplicated on a per-tu basis if ODR
is not relevant, otherwise, they are de-duplicated on a per-corpus
basis when ODR is relevant.

For most of the other types, if ODR is not relevant, then no
de-duplication is performed at all.  Otherwise, for these types, if
ODR is relevant, per-corpus de-duplication is performed.

	* src/abg-dwarf-reader.cc
	(read_context::per_tu_name_artefacts_map_): New data member.
	(read_context::clear_per_translation_unit_data): Clear the new
	read_context::per_tu_name_artefacts_map_.
	(read_context::associate_die_to_decl): Take a flag to say if we
	should associate a DIE to its representation and another one to
	say if the association should be done per-tu or per-corpus.
	(read_context::lookup_{type_artifact, artifact}_from_die): Update
	apidoc.
	(read_context::lookup_artifact_from_die_representation): Likewise.
	(read_context::{associate_die_to_artifact_by_repr,
	associate_die_to_artifact_by_repr_internal,
	associate_die_to_type}): Take a flag to say if the associating
	should be done on a per-tu basis.
	(read_context::lookup_{type_artifact, artifact}_from_die_per_tu):
	New member functions.
	(read_context::{lookup_artifact_from_per_tu_die_representation,
	odr_is_relevant}): Likewise.
	(build_enum_type, add_or_update_class_type)
	(add_or_update_union_type): If ODR is not relevant, do not perform
	per-corpus de-duplication.
	(build_pointer_type_def, build_typedef_type): Do not associate the
	type to its representation as these kinds of typs are not
	de-duplicated.
	(build_function_type):  If ODR is not relevant, perform per-tu
	de-duplication.  When ODR is relevant, per-corpus de-duplication
	is performed.
	(build_or_get_fn_decl_if_not_suppressed): Function decls are
	always de-duplicated per-corpus.
	(build_ir_node_from_die): For data members, do not update the die
	representation map as data members are not de-duplicated.  Do not
	do it for function decls either.

[1]: https://en.wikipedia.org/wiki/One_Definition_Rule

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:33 +01:00
Dodji Seketeli
c495a5c5f0 Handle per translation unit and per corpus types maps
Today, whenever a type is added to its scope, a map that associates
the qualified type name to the type is updated.  There is only one
such map in a given ABI corpus.

So whenever a type is looked up from its name, it's that per-corpus
type map that is used.

This setup makes libabigail type lookup be tailored only for binaries
that respect the One Definition Rule of C++[1] (aka ODR) which
basically says that there should be only one type of a given name in
an ABI corpus.

It turns out that many binaries, especically C binaries, don't respect
the ODR.  So a type "struct foo" can be defined in a file a.c and
another *different* type "struct foo" can also be defined in b.c.
What a useful and safe feature! Not.

For those binaries, just having one type map doesn't work.  We need to
have one type map per translation unit, and one map per-corpus map.

This is the strategy implemented by this patch.

With this patch, whenever a type is added to its scope, a
per translation unit type map is updated.  The per corpus map is
updated as well.  If there are more than one type of a given name, the
entry in the per corpus type map for that type is left empty.

Type lookup now potentially becomes a two phases lookup.  Whenever a
type is looked up from its name, the per corpus type map is looked at
first.  If the type is not in that per corpus type map, then the per
translation unit type maps are lookup up, in sequence.

The patch thus re-visits the type maps updating and lookup routines to
adapt them to the new scheme.  The patch also updates the clients of
the type map updating and lookup code.

Note that this patch is part of a series of patches which aims to move
libabigails away from its ODR-centric organization to make it work
well also on binary where the ODR is not relevant.  As such, the patch
doesn't assure that "make check" passes.  To have "make check" pass,
you need to have all the patches of the series applied.

[1]: https://en.wikipedia.org/wiki/One_Definition_Rule

	* include/abg-fwd.h (lookup_type_in_corpus): Remove.  This is to
	be replaced by the new lookup_type below.
	(lookup_{basic, class, union, enum, typedef, qualified, pointer,
	reference, array, function, class_or_typedef,
	class_typedef_or_enum}_type):
	(lookup_class_type_through_scopes, lookup_type)
	(lookup_type_through_scopes, lookup_or_synthesize_fn_type)
	* src/abg-ir-priv.h (struct translation_unit::priv):  Move this
	private type here, from abg-ir.h.
	(synthesize_type_from_translation_unit): Declare new functions.
	* include/abg-ir.h (class type_maps): Define new type.
	(translation_unit::get_function_types): Remove.
	(translation_unit::get_types): Now return a type_maps.
	(translation_unit::get_live_fn_types): Declare new type.
	(class decl_base): Make canonicalize be a friend of this class.
	* src/abg-ir.cc (struct translation_unit::priv): Move this to
	abg-ir-priv.h
	(struct type_maps::priv): Define new type.
	(type_maps::{basic, class, union, enum, typedef, qualified,
	pointer, reference, array, function}_types): Define new accessors.
	(translation_unit::bind_function_type_life_time): Adjust.
	(translation_unit::get_function_types): Remove accessor.
	(translation_unit::get_types, get_live_fn_types): Define new
	accessors.
	(lookup_type_in_translation_unit)
	(lookup_class_type_in_translation_unit)
	(lookup_function_type_in_translation_unit)
	(synthesize_type_from_translation_unit)
	(synthesize_function_type_from_translation_unit)
	(lookup_class_type_in_translation_unit) Remove function
	definitions.
	(lookup_type_in_map): Define function template.
	(lookup_{basic, class, union, typedef, class_or_typedef,
	class_typedef_or_enum, qualified, pointer, reference, array,
	function}_type): Define functions.
	(lookup_function_type, lookup_type_through_scopes)
	(lookup_class_type_through_scopes)
	(lookup_basic_type_through_translation_units)
	(lookup_union_type_through_translation_units)
	(lookup_enum_type_through_translation_units)
	(lookup_class_type_through_translation_units)
	(lookup_typedef_type_through_translation_units)
	(lookup_qualified_type_through_translation_units)
	(lookup_pointer_type_through_translation_units)
	(lookup_reference_type_through_translation_units)
	(lookup_array_type_through_translation_units)
	(lookup_function_type_through_translation_units)
	(lookup_type_through_translation_units)
	(lookup_or_synthesize_fn_type, lookup_type): Likewise.
	(maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Define function
	template, specilizations and functions.
	(synthesize_type_from_translation_unit)
	(synthesize_function_type_from_translation_unit): Define
	functions.
	* include/abg-corpus.h (corpus::get_types): Declare new accessor.
	* src/abg-corpus.cc (corpus::priv::get_types): Define new
	accessor.
	(corpus::get_types): Likewise.
	(lookup_type_in_corpus, lookup_class_type_in_corpus)
	(lookup_type_in_corpus, lookup_function_type_in_corpus)
	(maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Remove.
	(lookup_{basic, class, union, enum, typedef, qualified, pointer,
	reference, array, function, class_or_typedef,
	class_typedef_or_enum}_type): Likewise.
	* src/abg-corpus-priv.h (corpus::priv::{basic, class, union,
	typedef, qualified, pointer, reference, array, function}_types):
	Remove these data members.
	(corpus::priv::get_scopes): Remove member function.
	(corpus::priv::get_{basic, class, union, enum, typedef, qualified,
	pointer, reference, array, function}_types): Remove member
	function declarations.
	(corpus::priv::types_): New data member.
	(corpus::priv::get_types): Declare new member function.
	(lookup_{basic, class, enum, typedef, class_or_typedef, qualified,
	pointer, reference, array, function}_type): Declare new functions.
	* src/abg-dwarf-reader.cc
	(read_context::resolve_declaration_only_classes)
	(build_translation_unit_and_add_to_ir): Adjust use of
	lookup_class_type.
	* src/abg-reader.cc (read_context::type_is_from_translation_unit):
	Adjust to the use of lookup_function_type_in_translation_unit that
	got renamed into lookup_function_type.
	* src/abg-writer.cc (type_ptr_cmp::operator()): New operator
	implementation.
	(read_context::sort_type): Add new overloads.
	(write_translation_unit): Adjust to get the function types from
	the new translation_unit::get_live_fn_types and sort them.
	* tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust
	to use the new lookup_or_synthesize_fn_type, in lieu of
	lookup_function_type_in_corpus.  Adjust to use lookup_type in lieu
	of lookup_type_in_corpus.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:33 +01:00
Dodji Seketeli
bca3f9d163 Make abg-fwd.h use *_sptr typedefs
Until now, the abg-fwd.h where the necessary forward generic
declarations where put didn't contain the convenience typedefs of the
form foo_sptr that designate a shared pointer to type foo.

This patch moves these convenience typedefs as well as the missing
forward declarations from abg-ir.h to abg-fwd.h.  The patch also
adjusts the function declarations in abg-fwd.h to make them use these
convenience typedefs.

	* include/abg-ir.h: Move convience typedef declarations and some
	necessary forward declarations to ...
	* include/abg-fwd.h: ... here.
	(is_enum_type, is_var_decl): Take a pointer to type_or_decl_base.
	(lookup_type_in_scope): Return a type_base_sptr.
	(lookup_type_through_scopes): Introduce this to later replace the
	overload of lookup_type_in_translation_unit that takes a list of
	strings.
	(lookup_type_in_scope): Return a type_base_sptr, not a
	decl_base_sptr.
	* src/abg-ir.cc (lookup_type_in_scope, lookup_node_in_scope)
	(lookup_var_decl_in_scope): Adjust.
	(is_enum_type, is_var_decl): Take a pointer to type_or_decl_base.
	(lookup_node_in_scope): Return a type_or_decl_base_sptr.
	(lookup_type_in_scope): Return a type_base_sptr.
	(lookup_node_in_translation_unit): Return a
	type_or_decl_base_sptr.
	(lookup_type_through_scopes): Replace
	lookup_type_in_translation_unit.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:32 +01:00
Chenxiong Qi
6167026544 Fix wrong variable name
* tools/fedabipkgdiff: (diff_latest_rpms_based_on_distros): Fix
	wrong variable name distro.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-12-19 12:31:02 +01:00
Chenxiong Qi
a028c1735d Warn properly when cannot find peer RPM
* tools/fedabipkgdiff: (RPMCollection.get_peer_rpm): Return None
	when cannot find peer RPM due to nonexistent arch.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-12-19 12:30:18 +01:00
Chenxiong Qi
f8ca17190b Read Koji config via Koji API
Besides reading Koji config via Koji API read_config, option --topdir is
also renamed to --topurl that is the correct one should be used.

	* tools/fedabipkgdiff: Read DEFAULT_KOJI_TOPURL and
	DEFAULT_KOJI_SERVER from Koji config via Koji API read_config.
	(build_commandline_args_parser): --topdir is renamed to
	--topurl.
	* doc/manuals/fedabipkgdiff.rst: Rename --topdir to --topurl.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-12-19 12:29:22 +01:00
Chenxiong Qi
8ac5e078c5 Follow moved packages when download
This patch makes fedabipkgdiff able to follow the new place to download
packages.

	* tools/fedabipkgdiff: (download_rpm) Add --location to curl
	CLI.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-12-19 12:28:55 +01:00
Chenxiong Qi
0011e5b0b6 More document for local RPMs comparison
* doc/manuals/fedabipkgdiff.rst: Add more document for local RPMs
	comparison. Also fixed a typo.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-12-19 12:03:19 +01:00
Ondrej Oprala
ee00b09f21 Properly report missing files for abipkgdiff
Currently, if abipkgdiff is given a path to a nonexistent file,
it propagates all the way until package classification
and ends up being reported as "PKG should be a valid package file",
which doesn't hint it's not there at all.

        * tools/abipkgdiff.cc: (class options): Add the "nonexistent_file" flag
        (parse_command_line): Check if the files given exist.
        (main): Check the nonexistent_file flag. If any of the input
        files don't exist, report it and exit. Also, for present and future test
        uniformity, only show the base names of the packages when using their
        names in error output.
        * tests/test-diff-pkg.cc: Add a new regression test.
        * tests/data/test-diff-pkg/test-nonexistent-report-0.txt: The
        expected output of the above regression test.
        * tests/data/Makefile.am: Add the above file to the list.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
2016-12-15 20:16:01 +01:00
Dodji Seketeli
6eb35fd54f Misc style cleanup
* src/abg-dwarf-reader.cc (build_function_type): Remove
	unnecessary new line.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-15 16:25:41 +01:00
Dodji Seketeli
7dbe1f7249 make is_anonymous_type work for unions and classes
* src/abg-ir.cc (is_anonymous_type): Make this work for class or
	union types, no only classes.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-15 16:25:41 +01:00
Dodji Seketeli
0b47f8dc67 Naming typedefs of classes are not read properly from abixml
When loading a class from abixml and when that class has a naming
typedef, build_class_decl fails to build the naming typedef from its
ID because it calls read_context::get_type_decl() instead of
read_context::build_or_get_type_decl().

This patch fixes that issue by using
read_context::build_or_get_type_decl rather than
read_context::get_type_decl.

Also, as read_context::build_or_get_type_decl can trigger the creation
of a class (and recursively call build_class_decl), it needs to be
called after the class type being built is marked as work-in-progress
(aka WIP).  So the handling of the naming typedef is moved to after
the class type being built is marked as WIP.

	* src/abg-reader.cc (build_class_decl): Use
	read_context::build_or_get_type_decl rather than
	read_context::get_type_decl to build the naming typedef referred
	to by the class being built.  Move the handling of naming typedefs
	after the class is marked as WIP and keyed.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-15 16:25:41 +01:00
Dodji Seketeli
f7bb9cad09 Don't early-canonicalize function types when reading abixml
When reading from an abixml file, we sometimes canonicalize function
types before the entire abixml file is read.  This can lead to, e.g, a
function type that is not yet fully built being canonicalized too
early and so its canonical type being wrong because it reflects the
state of the function type at canonicalization time -- but then that
state changed later.

This patch fixes that by forcing us to late-canonicalize function
types, just like we do for all aggregate types.

	* src/abg-reader.cc (read_context::maybe_canonicalize_type):
	late-canonicalize function types too.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-15 16:25:41 +01:00
Ondrej Oprala
c7ec20acc9 Check --enable-rpm dependencies more rigorously
If a user has explicitly specified --enable-rpm when running
"configure", it will now fail unless both rpm2cpio and cpio
are present on the system.

        * configure.ac: Check if both rpm2cpio and cpio
        exist on the system. If not, disable the option and fail the
        configuration if --enable-rpm was specified explicitly.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
2016-12-13 20:55:00 +01:00
Ondrej Oprala
744417d396 abipkgdiff doesn't mention --no-default-suppression in help
* tools/abipkgdiff.cc (display_usage): Mention
        --no-default-suppression as one of the options.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
2016-12-13 20:51:42 +01:00
Ondrej Oprala
fda52842d9 Fix a few remarks made by cppcheck
* src/abg-comparison.cc (types_or_decls_equal::operator()): Pass
	arguments by reference.
        (class_diff::ensure_lookup_tables_populated): Expression
        !A || (A && B) can be reduced to !A || B.
	* src/abg-suppression.cc (suppression_matches_type_no_name):
	Likewise.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
2016-12-12 21:24:28 +01:00
Ondrej Oprala
125c0c3c7c Bug 19272 - abipkgdiff doesn't report arch change
Previously, architecture change wasn't included in the incompatible
changes check.

This patch makes corpus_diff::has_incompatible_changes take
architecture change into account.

It turns out corpus_diff::has_net_changes wasn't taking architecture
or soname change into account either.  This patch fixes that as well.

The patch also updates abicompat.cc to make it use
corpus_diff::has_net_changes() and
corpus_diff::has_incompatible_changes(), instead of open-coding these
member functions.

	* src/abg-comparison.cc (corpus_diff::has_incompatible_changes):
	The architecture change into account.
	(corpus_diff::has_net_changes): Take architecture and soname
	changes into account.
	* tools/abicompat.cc (perform_compat_check_in_normal_mode): Use
	corpus_diff::{has_net_changes, has_incompatible_changes}.
	* tests/data/test-diff-pkg/dbus-glib-0.104-3.fc23.armv7hl.rpm: New
	test input.
	* tests/data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64--dbus-glib-0.104-3.fc23.armv7hl-report-0.txt:
	New test reference output.
 	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-pkg.cc (in_out_spec): Compare the new package
	above against an x86_64 one.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-12 19:55:23 +01:00
Chenxiong Qi
783099cd25 Bug 20380 - Compare two local RPMs
Bug 20270 is also fixed.

This patch allows developer to compare two local RPMs in form

    fedabipkgdiff some/place/foo.rpm another/place/bar.rpm

But, network is still needed to talk with Koji.

This patch also introduces new terms for libabigail, that is the
subject, ancillary package, and comparison half. Subject represents a
package that is subject of the ABI comparison, a subject could be a RPM
and maybe it would be a DEB or some other kind of "package". A subject
may have several ancillary packages that are used to compare the
subject.  Generally, a subject may have devel, debuginfo, or both.

	* configure.ac: add dependent mimetype module.
	* doc/manuals/fedabipkgdiff.rst: Update to add document for the
	new use case of comparing two local RPMs.
	* tests/data/Makefile.am: Include new RPMs for tests.
	* tests/data/test-fedabipkgdiff/dbus-glib/dbus-glib-0.100.2-2.fc20.x86_64.rpm:
	New RPM for running test.
	* tests/data/test-fedabipkgdiff/dbus-glib/dbus-glib-0.106-1.fc23.x86_64.rpm:
	Likewise.
	* tests/data/test-fedabipkgdiff/nss-util/nss-util-3.12.6-1.fc14.x86_64.rpm:
	Likewise.
	* tests/data/test-fedabipkgdiff/nss-util/nss-util-3.24.0-2.0.fc25.x86_64.rpm:
	Likewise.
	* tests/data/test-fedabipkgdiff/nss-util/nss-util-devel-3.24.0-2.0.fc25.x86_64.rpm:
	Likewise.
	* tests/data/test-fedabipkgdiff/test4-glib-0.100.2-2.fc20.x86_64.rpm-glib-0.106-1.fc23.x86_64.rpm-report-0.txt:
	Rename filename by adding .rpm extension.
	* tests/data/test-fedabipkgdiff/test5-same-dir-dbus-glib-0.100.2-2.fc20.x86_64--dbus-glib-0.106-1.fc23.x86_64-report-0.txt:
	New reference output for testing comparing local RPMs.
	* tests/data/test-fedabipkgdiff/test6-missing-devel-debuginfo-nss-util-3.12.6-1.fc14.x86_64--nss-util-3.24.0-2.0.fc25.x86_64-report-0.txt:
	New reference output for testing comparison without non-existent
	debuginfo or development package.
	* tests/runtestfedabipkgdiff.py.in (FEDABIPKGDIFF_TEST_SPECS):
	Rename filename for test4. Add two new test cases.
	(run_fedabipkgdiff_tests): Remove semicolon and trailing
	whitespaces.
	(main): Likewise.
	(ensure_output_dir_created): Likewise.
	* tools/fedabipkgdiff: Require some new modules.
	Fix of return code.
	(PkgInfo): Renamed to ComparisonHalf.
	(match_nvr): New method to determine if a string matches format
	of N-V-R.
	(match_nvra): New method to determine if a string matches format
	of N-V-R.A.
	(is_rpm_file): New method to guess if a file is a RPM file.
	(RPM.is_peer): New method to determine if current RPM is a peer
	of another.
	(RPM.filename): Use Koji module API to construct the filename.
	(RPM.nvra): Get nvra from filename instead of constructing
	manually that is duplicated with Koji module API.
	(RPMCollection): New class to represent a set of RPMs.
	(generate_pkg_info_pair_for_abipkgdiff): New method working as a
	generator to yeild comparison halves for running abipkgdiff.
	(Brew.getRPM): Fix string format with incorrect argument.
	(Brew.select_rpms_from_a_build): Return instance of
	RPMCollection.
	(abipkgdiff): If there is no debuginfo or development package,
	just ignore it and leave a warning. If --error-on-warning is
	specified, raise an exception instead. Arguments are modified
	to represent the new name ComparisonHalf, and relative docstring
	is also updated.
	(magic_construct): Removed.
	(run_abipkgdiff): Rewrite.
	(make_rpms_usable_for_abipkgdiff): Removed.
	(diff_local_rpm_with_latest_rpm_from_koji): Rewrite by using
	RPMCollection.
	(diff_latest_rpms_based_on_distros): Likewise.
	(diff_two_nvras_from_koji): Likewise.
	(diff_from_two_rpm_files): New method to compare two local RPMs.
	(build_commandline_args_parser): Add new option
	--error-on-warning.
	(main): Add support to compare local RPMs.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-12 15:21:10 +01:00
Dodji Seketeli
85318068cd Fix template_decl:#️⃣:operator()
While hashing template_decl we inadvertently forget the contribution
of the name of the type to the hash.

This was spotted by Ondrej Oprala.

Fixed thus.

	* src/abg-hash.cc (template_decl:#️⃣:operator()): Combine the
	contribution of the qualified name to the contribution of the type
	name to the hash.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-12 12:14:21 +01:00
Dodji Seketeli
d7faae38f6 Fix aborting when reading .foo symbols from a ppc64 binary
On ppc64, the value of a function symbol is *usually* the pointer to
the function.  That function pointer value refers to an index inside
the ".opd" (Official Procedure Descriptor) section.  That section is a
record of tripplets values.  One of these values is the address of the
entry point of the function.  A debug information entry for a
function, in DWARF, refers to the entry point of the function; not to
the function pointer address.

So libabigail builds a table that associates a function entry point
address to its function pointer address.

So, if a function is named "foo", it has an entry in the symbol table
for the symbol name "foo"; the value of that symbol is the function
pointer address of foo, which refers to an offset in the ".opd"
section.

But then it turns out that there is also going to be an entry in the
symbol table for an artificial symbol named ".foo".  Pleast note the
dot before the suffix "foo".  The value of the ".foo" symbol is the
address of the entry point of the function "foo"; it's an address in
the ".text" section this time.

Libabigail's ELF symbols reading code was (wrongly) expecting all
entries in the symbol table that refer to function to have values that
are offset in the ".opd" section.  It wasn't expecting the ".foo"
symbols whose value are an address in the ".text" section.

This patch fixes the ELF symbol reading code to make it be aware of
the ".foo" symbols too.

	* abg-dwarf-reader.cc (read_context::find_opd_section): Fix
	comment.
	(read_context::load_symbol_maps): If for a given function entry
	point (that we got by looking at the ".opd" section for a given
	function pointer value) we already had an entry in the
	function_entry_address -> symbol, maybe it means that the previous
	entry that we had was from an entry in the symbol table which
	value was directly the entry point address of a function.  In that
	case, if the name of the symbol is "foo", the name of the symbol
	which value is directly the entry point address is ".foo".  What
	we do in this case is that we just keep the reference to the "foo"
	symbol in the function_entry_address -> symbol map.
	(read_context::address_is_in_opd_section): Define new member
	function.
	* tests/data/test-diff-pkg/gmp-4.3.1-10.el6.ppc64.rpm: New test input.
	* tests/data/test-diff-pkg/gmp-4.3.1-7.el6_2.2.ppc64.rpm: Likewise.
	* tests/data/test-diff-pkg/gmp-debuginfo-4.3.1-10.el6.ppc64.rpm: Likewise.
	* tests/data/test-diff-pkg/gmp-debuginfo-4.3.1-7.el6_2.2.ppc64.rpm: Likewise.
	* tests/data/test-diff-pkg/gmp-4.3.1-7.el6_2.2.ppc64--gmp-4.3.1-10.el6.ppc64-report-0.txt:
	New test reference output.
	* tests/data/Makefile.am: Add the new test input and reference
	output to source distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Add the new test inputs
	and reference output to the set of inputs that are compared.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-09 01:07:05 +01:00
Dodji Seketeli
985397a47a Bug 20927 - Segfault when $HOME is not set
When comparing two binaries with abi{pkg}diff, if $HOME is not set, we
segfault at some places because we don't expect that.  I ran "make
check" after doing "unset HOME" to help me catch most of those places.
This patch updates the code to handle that case.

	* src/abg-tools-utils.cc
          (get_default_user_suppression_file_path): Handle the case where
	the HOME environment variable is not set.
	* tools/abipkgdiff.cc (package::extracted_packages_parent_dir):
	Likewise.  When $HOME is empty set then use $TMPDIR.  If it's
	empty too then use "/tmp".

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-05 10:21:13 +01:00
Dodji Seketeli
5ed0e40bfd Bug 20887 - Show relative change of offsets
Until now, an offset change is reported by showing the old and new
offsets of the data member that changed.

This patch adds the string "(by +N bits)" with 'N' being the number of
bits by which the offset of the data member was increased, or "(by -N
bits) if the offset of the data member was decreased of N bits.

The patch also emits a string that says "size hasn't changed" if the
size of the structure did not change.

This can be disabled by a new --no-show-relative-offset-changes
option.

	* doc/manuals/abidiff.rst: Document the new
	--no-show-relative-offset-changes.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* include/abg-comparison.h
	(diff_context::show_relative_offset_changes): New accessors.
	* include/abg-ir.h ({set,get}_data_member_offset): Return uint64_t
	instead of the less portable size_t.
	* src/abg-comparison.cc
	(diff_context::priv::show_relative_offset_changes_): New data
	member.
	(dif_context::show_relative_offset_changes): Define accessor.
	(maybe_show_relative_offset_change): Define new function.
	(represent): In the overload for var_diff, call the new
	maybe_show_relative_offset_change.
	(report_size_and_alignment_changes):  If the size of the type
	didn't change then say it now.
	* src/abg-ir.cc (set_data_member_offset, get_data_member_offset):
	Take or return a uint64_t instead of a size_t.
	* tools/abidiff.cc (options::show_relative_offset_changes): New
	data member.
	(options::options): Initialize it.
	(display_usage): Display help string for the new
	--no-show-relative-offset-changes.
	(parse_command_line): Parse the new
	--no-show-relative-offset-changes options.
	(set_diff_context_from_opts): Set the
	"show-relative-offset-changes" flag according to the new option.n
	* tools/abipkgdiff.cc (options::show_relative_offset_changes): New
	data member.
	(options::options): Initialize it.
	(display_usage): Add help string for the new
	--no-show-relative-offset-changes option.
	(set_diff_context_from_opts): Set the
	"show-relative-offset-changes" flag according to the new option.
	(parse_command_line): Parse the new command line option.
	* tests/data/test-diff-dwarf/test40-report-0.txt: Add new
	reference output.
	* tests/data/test-diff-dwarf/test40-v0.c: Source code of the first
	test binary.
	* tests/data/test-diff-dwarf/test40-v1.c: Source code of the
	second test binay.
	* tests/data/test-diff-dwarf/libtest40-v0.so: New first test binary.
	* tests/data/test-diff-dwarf/libtest40-v1.so: New second test binary.
	* tests/test-diff-dwarf.cc (in_out_spec): Add the new test
	binaries above to the set of binaries that are compared.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/data/test-abicompat/test7-fn-changed-report-0.txt: Adjust.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Likewise.
	* tests/data/test-abidiff/test-enum0-report.txt: Likewise.
	* tests/data/test-abidiff/test-enum1-report.txt: Likewise.
	* tests/data/test-abidiff/test-struct1-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test0-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test1-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/test13-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test15-enum-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test27-local-base-diff-report.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/test38-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test4-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test5-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test6-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/test1-report.txt: Likewise.
	* tests/data/test-diff-filter/test13-report.txt: Likewise.
	* tests/data/test-diff-filter/test16-report-2.txt: Likewise.
	* tests/data/test-diff-filter/test16-report.txt: Likewise.
	* tests/data/test-diff-filter/test17-0-report.txt: Likewise.
	* tests/data/test-diff-filter/test17-1-report.txt: Likewise.
	* tests/data/test-diff-filter/test18-report.txt: Likewise.
	* tests/data/test-diff-filter/test19-enum-report-1.txt: Likewise.
	* tests/data/test-diff-filter/test2-report.txt: Likewise.
	* tests/data/test-diff-filter/test23-redundant-fn-parm-change-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test24-compatible-vars-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test25-cyclic-type-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test25-cyclic-type-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-0.t:
	Likewise.xt
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-2.txt:
	Likewise.
	* tests/data/test-diff-filter/test29-finer-redundancy-marking-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/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.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/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/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/test1-typedef-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test1-typedef-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test10-changed-parm-c-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test2-struct-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test23-alias-filter-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test23-alias-filter-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test30-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test4-local-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test4-local-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-7.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-8.txt: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-02 21:29:28 +01:00
Dodji Seketeli
4f9d682d0b Rename tests/update-test-read-dwarf-output.py
Renamed tests/update-test-read-dwarf-output.py into
tests/update-test-output.py as it can be used for all tests that emit
an output and compare it against a reference output.

	* tests/update-test-output.py: renamed
	tests/update-test-read-dwarf-output.py into this.  Update its
	comments.  Make this script executable.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-02 12:59:32 +01:00
Dodji Seketeli
b4fc841a73 Add tests/data/test-diff-suppr/test33-report-0.txt to tarball
I forgot to add the file testing file
tests/data/test-diff-suppr/test33-report-0.txt to
tests/data/Makefile.am.  This makes the test runtestdiffsupp fail
under 'make distcheck'.

Fixed thus.

	* tests/data/Makefile.am: Add test-diff-suppr/test33-report-0.txt.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-30 11:01:38 +01:00
Dodji Seketeli
b859adc08f Bug 20670 - abipkgdiff aborts if $XDG_CACHE_HOME does not exist
This patch creates $XDG_CACHE_HOME if it doesn't exist, rather than
just aborting.

	* tools/abipkgdiff.cc (package::extracted_packages_parent_dir):
	Ensure that the cache directory is created, even when
	XDG_CACHE_HOME is set.  Also, remove the now useless "using
	abigail::tools_utils::get_random_number_as_string" statement.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-30 10:40:01 +01:00
Dodji Seketeli
72f50a16ce Very light speed improvements
When comparing of two kernel trees showed that for huge changesets
involving highly recursive types, leaf functions used by the
categorization code dominate the performance profile.

This patch introduces some changes that help gain around 30 seconds
(out of 14 minutes) on a non-optimized build, when comparing 4.7 nd
4.8 fedora kernels (between fedora 24 and 26).

	* include/abg-comp-filter.h (has_harmless_name_change): Pass smart
	pointers by reference.
	* src/abg-comp-filter.cc (access_changed)
	(function_name_changed_but_not_symbol)
	(non_static_data_member_type_size_changed)
	(static_data_member_type_size_changed, is_compatible_change)
	(decl_name_changed, has_harmless_name_change):  Pass smart
	pointers by reference.
	* include/abg-ir.h (decl_base::set_context_rel): Take a bare
	pointer, not a smart pointer.
	* src/abg-ir.cc (decl_base::priv::context_): Make this data member
	be a naked pointer, not a smart pointer.
	(decl_base::priv::priv): Initialize it.
	(decl_base::priv::~priv): New constructor.
	(decl_base::{get_context_rel, set_scope}): Adjust.
	(class_decl::method_decl::{method_decl, set_scope}): Likewise.
	(equals): In the overload for var_decl, compare the type of the
	var first as that might be faster (to detect var_decls with
	different types) in the general case where types are
	canonicalized.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 17:08:19 +01:00
Dodji Seketeli
e861bd3368 Introduce on-the-fly type canonicalization
During canonicalization of a type T, when T is structurally compared
to an already canonicalized type C, it can happen that
non-canonicalized sub-types of T are structurally compared again and
again to canonicalized sub-types of C.

This patch introduces a new optimization or those cases: on-the-fly
type canonicalized.

That means, if a not-yet-canonicalized sub-type S of the type T being
canonicalized structurally compares equal to a canonicalized sub-type,
then the canonical type of S is said to be the canonical type of the
canonicalized sub-type.  So sub-type S is canonicalized, on-the-fly,
during canonicalization of type T.

This considerably speeds up the canonicalization process while doing
"abidiff vmlinux vmlinux".  It goes from taking forever to taking 45
seconds on a non-optimized build.

	* include/abg-ir.h (environment::do_on_the_fly_canonicalization):
	Declare new member functions.
	({type_base, function_type}::priv_): Make this public so that
	static non-member functions defined in abg-ir.cc can access it.
	* src/abg-ir.cc
	(environment::priv::do_on_the_fly_canonicalization_): New data
	member.
	(environment::priv::priv): Initialize it.
	(environment::do_on_the_fly_canonicalization): Define new member
	functions.
	(type_base::get_canonical_type_for): Trigger on-the-fly
	canonicalization during comparison of the type being canonicalized
	and an already canonicalized type.
	(types_are_being_compared, maybe_propagate_canonical_type): Define
	new static functions.
	(equals): In overloads for class_decl and function_type, call
	maybe_propagate_canonical_type when the two types compare equal.
	* 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-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 17:07:28 +01:00
Dodji Seketeli
bd3fe4c748 Fix pretty representation of array types
It turned out we were wrongly emitting the pretty representation of
array types in two cases:

  1/ in case of qualified array types: a const array of string type
  was being pretty-represented as: "const string[]" instead of
  "string[] const".

  2/ in case of array with an empty sub-range DIE; that is a sub-range
  DIE with no attribute at all.  For instance an array of char with an
  empty sub-range DIE was being represented as: "char", instead of
  "char[]".

This patch fixes 1 and 2.  It also updates numerous test reference
output files.

	* include/abg-ir.h (array_type_def::is_infinite): Fix indentation.
	* src/abg-ir.cc (qualified_type_def::build_name): An empty set of
	sub-ranges for a vector is represented by "[]".
	(array_type_def::is_infinite): If a vector has no sub-range, that
	means it has an infinite size.  Adjust comment.
	* tests/data/test-diff-filter/test33-report-0.txt: Adjust.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:51:19 +01:00
Dodji Seketeli
3981244c9d Support naming typedef and use them to speed up type canonicalization
There is a common C idiom in which an anonymous struct is named using
a typedef:

    typedef struct {int member;} anonymous_struct_type;

The typedef name "anonymous_struct_type" becomes the name of the
otherwise anonymous struct.  That is what a naming typedef is.

So, the nice thing about naming typedefs is that an anonymous class
type suddenly becomes non anymous.  So that type becomes eligible to
the ODR-based optimization during type canonicalization.  That speeds
up type canonicalization, at least for 'abidw'.

This patch represents naming typedefs for class_decl types in the
internal representation.  The patch also changes the meaning of an
anonymous class.  Whenever such a class becomes named by a typedef,
the class is not considered anonymous anymore, at least for the
purpose of type canonicalization.

	* include/abg-ir.h (typedef_decl_wptr): New typedef.
	(class_decl::{g,s}et_naming_typedef): Declare new member
	functions.
	* src/abg-dwarf-reader.cc (build_typedef_type): When the
	underlying type of a typedef is an anonymous class, the class type
	is said to have a naming typedef.
	* src/abg-ir.cc (is_anonymous_type):  An anonymous class that has
	a naming typedef is said to not be anonymous anymore.
	(class_decl::priv::naming_typedef): New data member.
	(class_decl::{g,s}et_naming_typedef): Define new member functions.
	(class_decl::get_pretty_representation): When called for internal
	purposes (e.g, for type canonicalization) compute the pretty
	representation of the class by using its typedef name, when class
	is anonymous and has a naming typedef.
	* src/abg-reader.cc (build_class_decl): Read the new
	"naming-typedef-id" attribute.
	* src/abg-writer.cc (write_naming_typedef): New function.
	(write_class_decl_opening_tag): Use the new write_naming_typedef
	function.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* 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/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/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>
2016-11-29 16:44:06 +01:00
Dodji Seketeli
cfaa7d42b6 Implement de-duplication for types and decls at DWARF loading time
Many types and decls are redefined in every translation unit that make
up an ELF binary.  This patch detects that a DIE represents a type or
decl that has already been defined in the current corpus and so will
not create a new internal representation for it.

The patch defines facilities to build the pretty representation of a
type or decl.  It's by looking at the pretty representation of a DIE
that the patch detects that a different DIE has already defined the
same type or decl.

The patch also fixes detection of the const-ness of member functions
as there were many cases where const member functions were not
recognized as const.  This fix makes it so that the pretty
representation of the DIE of said member functions match the pretty
representation of their internal representation, as far as the
const-ness is concerned.

One bit of infrastructure change that is used by the const-ness fix is
that method_type now carries const-ness.  So a method_decl that has a
const method_type is going to be const itself.

	* include/abg-ir.h (method_type::priv_): Introduce new pimpl
	pointer here.
	(method_type::class_type_): Move this into the pimpl idiom.
	(method_type::method_type): Take a new is_const flag.
	(method_type::get_class_type): Make this method out-of-line.
	(method_type::{s,g}et_is_const): Declare new member functions.
	(get_method_type_name): Declare this function as a friend of
	the method_type type.
	* src/abg-dwarf-reader.cc: Include the new abg-ir-priv.h and
	abg-corpus-priv.h.
	(typedef die_tu_map_type): Fix comment.
	(typedef die_istring_map_type): New typedef.
	(class read_context::die_source_dependant_container_set): New
	class template.
	(read_context::{die_qualified_name_maps_, die_pretty_repr_maps_,
	die_pretty_type_repr_maps_}): Define new data members.
	(read_context::{get_die_qualified_name, get_die_qualified_name,
	get_die_qualified_type_name, get_die_pretty_type_representation,
	get_die_pretty_representation, lookup_type_artifact_from_die,
	lookup_artifact_from_die, lookup_artifact_from_die_representation,
	associate_die_to_artifact_by_repr,
	associate_die_to_artifact_by_repr_internal,
	lookup_type_from_die}): Define new member functions.
	(read_context::lookup_type_from_die_offset): Fix comment.
	(get_parent_die, get_scope_die, die_is_decl)
	(die_is_namespace, die_is_unspecified, die_is_void_type)
	(die_is_pointer_type, die_is_reference_type)
	(die_is_pointer_or_reference_type, die_is_class_type)
	(die_has_object_pointer, die_this_pointer_from_object_pointer)
	(die_this_pointer_is_const, is_decl_tag)
	(die_object_pointer_is_for_const_method, die_is_at_class_scope)
	(die_name, die_qualified_type_name, die_qualified_decl_name)
	(die_qualified_name, die_qualified_type_name_empty)
	(die_return_and_parm_names_from_fn_type_die)
	(die_function_signature, die_peel_qual_ptr)
	(die_function_type_is_method_type, die_pretty_print_type)
	(die_pretty_print_decl, die_pretty_print)
	(build_subranges_from_array_type_die)
	(build_or_get_fn_decl_if_not_suppressed)
	(lookup_class_or_typedef_type)
	(lookup_class_typedef_or_enum_type_from_corpus)
	(is_function_for_die_a_member_of_class)
	(add_or_update_member_function): Define new static functions.
	(read_context::associate_die_to_decl): Call
	associate_die_to_artifact_by_repr.
	(read_context::{associate_die_to_type,
	schedule_type_for_late_canonicalization}): Take just one "die"
	parameter rather than taking a die offset and a die source; adjust
	accordingly.
	(maybe_canonicalize_type): Likewise.
	(finish_member_function_reading): Take a const reference to
	function_decl_sptr.
	(die_loc_and_name): Use the new die_name function.
	(die_is_type): Rename is_type_die into this.
	(build_type_decl): Take a new "where_offset" parameter.  Adjust.
	If a type of the same name as the one for the current DIE is is
	already present, do not create a new type; just return the
	already-existing one.
	(build_enum_type): Take a new "where_offset" parameter.  Adjust.
	(finish_member_function_reading): Pass two smart pointers by const
	reference.  Assert that the type of the member function is a
	method_type.  Some light cleanups.
	(add_or_update_class_type): Rename build_class_type_and_add_to_ir.
	If a DIE defining the same class has already been seen, then
	return that class; don't construct any other internal
	representation for the same class.  Better handle the updating of
	member data and functions.  Do not duplicate member types.
	(build_qualified_type, build_pointer_type_def)
	(build_reference_type): Support de-duplication here.
	(build_function_type): Likewise.  Support detection and building
	of method type.  This also supports *const* method type building.
	(build_array_type): Use the new
	build_subranges_from_array_type_die.
	(build_type_decl): Cleanup logic.
	(build_or_get_var_decl_if_not_suppressed): Renamed
	build_var_decl_if_not_suppressed into this.  Perform
	de-duplication for data members.
	(build_function_decl): Don't set an empty source location.  If the
	function type cannot be constructed, do not construct the function
	decl either.  Adjust.
	(build_ir_node_from_die): Adjust.  When building a function for a
	DW_TAG_subroutine_type DIE, use the new
	build_or_get_fn_decl_if_not_suppressed.
	* src/abg-ir.cc (translation_unit::bind_function_type_life_time):
	Fix comment.
	(strip_typedef): Adjust.
	(qualified_type_def::build_name): Set the prefix name of a the
	name of a noop qualifier to "noop-qual", just like what is done in
	the new die_qualified_name function.
	(struct method_type::priv): New priv type for the method_type
	class.
	(method_type::method_type): Take a new 'is_const' parameter.
	Adjust as the method_type is now pimpl'ed.
	(method_type::{get_class_type, set_is_const, get_is_const}):
	Define new member functions.
	(function_decl::get_pretty_representation_of_declarator): Better
	detecter of const-ness.
	(class_decl::insert_member_decl):  Better setting of the
	const-ness.
	(class_decl::method_decl::method_decl): Adjust.  Deduce the
	const-ness of the method_decl from the const-ness of its
	method_type.
	(copy_member_function): Adjust.
	(set_member_is_static): Do not assume a non-nil scope anymore
	because member_decl can now be scope-less, at least for a little
	while.
	* src/abg-reader.cc (push_decl_to_current_scope): Adjust.
	(build_function_decl): Style adjustment.  Adjust for method_type
	const-ness changes.
	(build_function_type): Likewise.  Also, support the new
	"method-class-id" property that flags a function type as being a
	method type.
	* src/abg-writer.cc (write_function_decl): Style fixes.
	(write_function_type): Likewise.  Emit a new "method-class-id"
	property for function type that is actually a method type.  That
	property's value is the id of the class of the method type.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi: Adjust.
	* tests/data/test-diff-dwarf/test0-report.txt: Adjust.
	* tests/data/test-diff-filter/test0-report.txt: Adjust.
	* tests/data/test-diff-filter/test01-report.txt: Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Adjust.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Adjust.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Adjust.
	* 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: Adjust.
	* 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: Adjust.
	* 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.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Adjust.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:16:56 +01:00
Dodji Seketeli
ccdc44b3eb Setup per-corpus type maps indexed by type names
This patch creates per-corpus maps that associate, for a certain kind
of type, the fully qualified name of the type to the type.

So there is a map for class_decl, one for enum_type_decl, one for
type_decl, etc.

These maps are populated when a new type is added to its scope.

The patch defines overloads of the function
maybe_update_types_lookup_map() that update the right map, depending
on the kind of type we are looking at.

Note that there also is a map in each class that associates a
signature string to a member functions.  This is so that member
functions of a given class can be looked up by signature.

This is so that looking up a type becomes now much faster than having
to walk all the translation units of a corpus to find one.

Note that this patch is specifically part of the series of patches
that implements types and declarations de-duplication while reading
DWARF information.

The patch might slightly change the output of abi serialization or
comparison so it needs some adjustments of some test reference files.
That adjustment is not done here.  Rather, it's done at once in
another patch of the set.

	* include/abg-corpus.h (corpus::priv_): Make this public so that
	functions from outside of the class can access it.  These
	functions are meant to be used only by code that is *inside*
	libabigail.so, though.
	* src/abg-corpus-priv.h: New file.
	* src/abg-corpus.cc: Include the new abg-corpus-priv.h file.
	(struct regex_t_deleter): Move this to abg-sptr-utils.h.
	(build_sptr<regex_t>): Move the declaration of this function
	template specialization to abg-sptr-utils.h and its definition to
	abg-sptr-utils.cc.
	(typedef regex_t_sptrs_type, typedef str_var_ptr_map_type)
	(struct corpus::exported_decls_builder::priv, struct
	corpus::priv): Move these declarations to the new
	abg-corpus-priv.h.
	(maybe_update_types_lookup_map): Define overloads of this (one per
	kind of type).
	(lookup_{basic, class, enum, typedef, class_or_typedef,
	class_typedef_or_enum, qualified, pointer, reference, array,
	function}_type): Define new functions.
	* include/abg-ir.h (typedef istring_type_base_wptr_map_type)
	(typedef istring_type_or_decl_base_sptr_map_type): Declare new
	typedefs.
	(class_decl::find_member_function_from_signature): Declare new
	member function.
	* src/abg-ir.cc: Include the new abg-corpus-priv.h file.
	(maybe_update_types_lookup_map): Remove this initial function.
	There are now new overloads in abg-corpus.cc for it.
	(scope_decl::{add_member_decl, insert_member_decl}): Adjust.
	(class_decl::{set_is_declaration_only, find_member_function,
	add_member_function}): Adjust.
	(class_decl::find_member_function_from_signature): Define new
	member function.
	* include/abg-sptr-utils.h (struct regex_t_deleter): Declare new
	type.
	(build_sptr<regex_t>): New build function template
	specializations.
	* src/abg-sptr-utils.cc: New file.
	* src/Makefile.am: Add src/abg-sptr-utils.cc and
	src/abg-corpus-priv.h to the build system.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:16:43 +01:00
Dodji Seketeli
1b94d60780 Allow pretty printing function decls for internal purposes
It appears that function_decl::get_pretty_representation doesn't make
the difference between internal and non-internal purposes.  This patch
fixes that by making the helper
get_pretty_representation_of_declarator() take an "internal" flag and
calls that.

	* include/abg-ir.h
	(function_decl::get_pretty_representation_of_declarator): Take an
	"internal" flag.
	* src/abg-ir.cc
	(function_decl::get_pretty_representation_of_declarator): Take an
	"internal" flag.
	(function_decl::get_pretty_representation): Pass the "internal"
	flag to the function
	function_decl::get_pretty_representation_of_declarator.
	(function_decl::parameter::get_type_name):  Better handle variadic
	parameter type.
	(function_decl::parameter::get_type_pretty_representation):
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:16:31 +01:00
Dodji Seketeli
484a5ad172 Make bash completion files non-executable
* bash-completion/abicompat: Make this be non-executable.
	* bash-completion/abidiff: Likewise.
	* bash-completion/abidw: Likewise.
	* bash-completion/abilint: Likewise.
	* bash-completion/abinilint: Likewise.
	* bash-completion/abipkgdiff: Likewise.
	* bash-completion/abisym: Likewise.
	* bash-completion/fedabipkgdiff: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-26 12:29:12 +01:00
Dodji Seketeli
f27520d767 A suppressed diff node implies suppressing all equivalent nodes too
When a diff node N is suppressed (for instance, using the
--headers-dir{1,2} option of abidiff}, it's only that diff node that
is suppressed.  We forget to suppress diff nodes that are equivalent
to N.

Here is why we forget to suppress diff ndoes that are equivalent.

apply_suppressions walks the diff node graph to mark diff nodes as
suppressed.  But it does the walking by making sure each diff node's
*class of equivalence* is visited once.  This is not only a way to
prevent infinite loops while visiting the graph, but also an
optimization as it avoids walking two equivalent diff nodes.

But then it can happen that we forget to categorize some diff nodes
inside a given class of equivalence, even though we categorized some
others.

This patch makes it so that when a diff node inside a class of
equivalence is categorized as SUPPRESSED, the canonical diff node of
that class of equivalence is categorized as SUPPRESSED too.  That way,
to know if a diff node is suppressed, we just need to look at its
canonical diff node.

While doing this, I noticed that abidiff and abipkgdiff are not
dropping private types from libabigail's internal representation, even
though the Library now has that capability.  The patch fixes that.
But then the patch adds a --dont-drop-private-types option to abidiff
to avoid dropping those private types from the IR, so that regression
tests can make sure that a suppressed diff node implies suppression
all equivalent nodes too.

	* doc/manuals/abidiff.rst b/doc/manuals/abidiff.rst: Document the
	new --dont-drop-private-types option.
	* src/abg-comparison.cc (diff::is_filtered_out): If the canonical
	type was suppressed then the current diff node is filtered out.
	(suppression_categorization_visitor::visit_{begin,end}):
	Categorized the canonical node as SUPPRESSED if the current node
	is suppressed.
	* tools/abidiff.cc (options::drop_private_types): New data member.
	(options::options): Initialize it.
	(display_usage): Add new help string for the new
	--dont-drop-private-types option.
	(parse_command_line): Parse the new --dont-drop-private-types
	option.
	(set_suppressions): Generate suppression specification from header
	directories given in parameter and stick them to the read context.
	* tools/abipkgdiff.cc (compare): Likewise.
	* tests/data/test-diff-suppr/libtest34-v0.so: New test input.
	* tests/data/test-diff-suppr/libtest34-v1.so: Likewise.
	* tests/data/test-diff-suppr/test34-report-0.txt: New reference
	report.
	* tests/data/test-diff-suppr/test34-v0.c: Source code for the new
	test input.
	* tests/data/test-diff-suppr/test34-v1.c: Likewise.
	* tests/data/test-diff-suppr/test34-priv-include-dir-v0/test34-priv-include-v0.h:
	Likewise.
	* tests/data/test-diff-suppr/test34-priv-include-dir-v1/test34-priv-include-v1.h:
	Likewise.
	* tests/data/test-diff-suppr/test34-pub-include-dir-v0/test34-pub-include-v0.h:
	Likewise.
	* tests/data/test-diff-suppr/test34-pub-include-dir-v1/test34-pub-include-v1.h:
	Likewise.
	* tests/data/Makefile.am: Add new test input material above to
	source distribution.
	* tests/test-diff-suppr.cc (in_out_spec): Compare the two new test
	library provided.  Add --dont-drop-private-types to test30*.

signed-off-by: Dodji Seketeli <dodji@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-26 11:54:19 +01:00
Dodji Seketeli
eac363eb66 Forgot to consider libtest33-v{0,1}.so in test-diff-suppr.cc
I forgot the make test-diff-suppr.cc run over libtest33-v{0,1}.so even
though this test was added to the source distribution.  Fixed thus.

	* tests/data/test-diff-suppr/test33-report-0.txt: New refernce report.
	* tests/test-diff-suppr.cc (in_out_specs): Compare libtest33-v0.so
	and libtest33-v1.so.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-26 10:37:19 +01:00
Dodji Seketeli
03d5abdd24 Bump version number to 1.0.rc7
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-24 17:53:20 +01:00
Dodji Seketeli
a02d433aab Update website for 1.0.rc6
* doc/website/mainpage.txt: Update for 1.0.rc6 release

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-24 17:52:27 +01:00
Dodji Seketeli
14d48647a4 Update NEWS and ChangeLog for 1.0.rc6
* ChangeLog: Update this automatically using "make
	update-changelog".
	* NEWS: update this by editing the output of 'git shortlog
	libabigail-1.0.rc5..HEAD'.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-24 15:28:29 +01:00
Dodji Seketeli
10384b66de Avoid using size_t to get DWARF data
This can cause issues on i686 compared to x86_64 as size_t has
different size on these two platforms.  Rather, use int64_t which has
the same fixed size on both platforms.

	* src/abg-dwarf-reader.cc (die_size_in_bits, die_location_expr):
	Take uint64_t rather than size_t and adjust.
	(expr_result::const_value_): Make this be int64_t rather than
	ssize_t.
	(expr_result::expr_result): Take int64_t rather than ssize_t.
	(expr_result::const_value): Return int64_t rather than ssize_t.
	(expr_result::{operator(), operator=, operator+=}): Make these
	operators return or take int64_t.
	too.
	(op_pushes_constant_value, op_manipulates_stack)
	(op_is_arith_logic, op_is_control_flow)
	(eval_last_constant_dwarf_sub_expr, die_member_offset)
	(die_virtual_function_index): Take
	uint64_t rather than size_t, or int64_t rather than ssize_t.
	(finish_member_function_reading, build_class_type_and_add_to_ir)
	(build_union_type_and_add_to_ir): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-24 15:25:44 +01:00
Dodji Seketeli
ab9d7b3bca Fix a compiler warning issued by GCC 6.2.1
* src/abg-dwarf-reader.cc (find_import_unit_point_between_dies):
	Parameter 5 of find_import_unit_point_between_dies is not of type
	Dwarf_Off.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-24 15:25:44 +01:00
Dodji Seketeli
b970ed1dda Fix offset type mismatch
* src/abg-dwarf-reader.cc (die_member_offset): The last two
	parameters of die_unsigned_constant_attribute must be of type
	uint64_t.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-24 15:25:43 +01:00
Dodji Seketeli
889898152c Fix indentation in abg-writer.cc
* src/abg-writer.cc (write_union_decl_opening_tag): Fix
	indentation.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-24 15:25:43 +01:00
Dodji Seketeli
09a15b6e60 Support reading data member offset from DW_AT_bit_offset
There are times where the DW_AT_data_member_location attribute is set
to zero and where the actual offset of the data member is the value of
the DW_AT_bit_offset.  This seems to be happening when a union type is
involved.

To get the offset of a data member, this patch makes us read the
DW_AT_bit_offset when it's present.  Otherwise, it gets the offset
from the DW_AT_data_member_location as we used to do.

In the passing the patch fixes the offset of base classes; the
nubmer of bytes value was what was being used, rather than the number
bits value.

	* src/abg-dwarf-reader.cc (die_member_offset): Better comments.
	Support reading the bit offset also from the DW_AT_bit_offset
	attribute when it's present.  Make sure this always returns a
	value in bits.
	(build_class_type_and_add_to_ir): No need to multiply (by 8) the
	value returned by die_member_offset anymore because it's now in
	bits directly.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Adjust.
	* tests/data/test-read-dwarf/test1.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Adjust.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-24 15:25:43 +01:00
Dodji Seketeli
630c334705 Lexicographically sort union data members in change reports
Until now, when reporting about struct or union changes, data members
were sorted by using their offset; the data member with the smallest
offset coming first.

But then in unions, all data member have the same offset.  In that
case, the patch sort them lexicographically, by taking their name into
account.

	* src/abg-comparison.cc (data_member_comp::operator()): Data
	members with the same offset are sorted lexicographically, by
	taking their name into account.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-23 15:00:51 +01:00
Dodji Seketeli
a44a4c1068 Better diagnostics when wget is missing
When wget is missing building the fedabipkgdiff tool is disabled.
This patch fixes diagnostics in that case.

	* configure.ac: When wget is missing then make the disabling of
	the building of the fedabipkgdiff tool show up in the
	configuration summary and emit a notice.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-23 13:15:02 +01:00
Dodji Seketeli
e7c920edbc Support union types
This patch makes Libabigail understand C and C++ union types.  It
defines a new class abigail::ir::union_decl to represent the
declaration of a union type.  It also defines a new type
abigail::comparison::union_diff to represent the changes between two
union types.  The patch then adds facilities to read union types from
DWARF and abixml and also to write union types into the abixml format.

As union types and class types have a lot in common, the patch tries
very hard to share code between the abigail::ir::class_decl and
abigail::ir::union_decl.  To do so, a new class
abigail::ir::class_or_union is created.  It's the base class for both
abigai::ir::class_decl and abigail::ir::union_decl.  Its data members
and methods represent the set of data and behaviour that are common to
classes and unions.  A lot of code and data that were initially in
abigail::ir::class_decl got moved into the new
abigail::ir::class_or_union class.

Similary, the patch creates a new class
abigail::comparison::class_or_union_diff that is a base class for both
the existing class abigail::comparison::class_diff and the newly
created class abigail::comparison::union_diff.  The new class
abigail::comparison::class_or_union_diff contains data and behaviour
that are common to both union_diff and class_diff and that were
previously in class_diff.

The rest of the patch is mostly adjustment so that code that was
supposed to work with class class_decl only can now work with class
class_or_union when it makes sense.  Similarly for class_diff and
class_or_union_diff.

The patch adds regression tests into the test suite and adjust many
existing tests involving binaries that contain union types; the
reference output of those tests now take union types into account.

	* include/abg-fwd.h (class_or_union, union_decl): Forward-declare
	new types.
	(is_class_or_union_type, is_union_type): Declare new functions.
	* include/abg-ir.h (method_type::class_type_): Make this be of
	class_or_union_wptr type.
	(method_type::method_type): Make the class_type parameter be of
	class_or_union_wptr type.
	(method_type::{g,s}et_class_type): Take or return a
	class_or_union_sptr.
	(member_base, method_decl, member_function_template)
	(member_class_template, member_base::hash)
	(member_function_template::hash, member_class_template::hash):
	Take these class types out of the class_decl scope.
	(is_method_decl): Adjust.
	(operator==, opertor!=): Adjust overloads for
	member_function_template_sptr and member_class_template_sptr.
	(class class_or_union): Declare new type.
	(class class_decl): Make this class inherit class_or_union class.
	(class_decl::{add_member_decl, insert_member_decl,
	remove_member_decl, set_size_in_bits, get_size_in_bits,
	get_alignment_in_bits, set_alignment_in_bits,
	get_is_declaration_only, set_is_declaration_only,
	set_definition_of_declaration, get_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	insert_member_type, add_member_type, remove_member_type,
	get_member_type, find_member_type, add_data_member,
	get_data_members, find_data_member, get_non_static_data_members,
	add_member_function, get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates): Move these
	to the parent class class_or_union.
	(copy_member_function, equals): Add overloads for class_or_union.
	(struct class_or_union::hash): Declare new type.
	(class union_decl): Declare new type.
	(equals, copy_member_function): New overloads for class union_decl
	type.
	(ir_node_visitor::visit): Add new overloads for union_decl* and
	class_or_union*.
	* src/abg-ir.cc (get_member_function_is_ctor)
	(set_member_function_is_ctor, get_member_function_is_dtor)
	(set_member_function_is_dtor, get_member_function_is_const)
	(set_member_function_is_const, get_member_function_vtable_offset)
	(set_member_function_vtable_offset)
	(get_member_function_is_virtual, set_member_function_is_virtual)
	(maybe_update_types_lookup_map, get_location)
	(get_method_type_name, is_at_global_scope, is_at_class_scope):
	Adjust.
	(is_class_or_union_type, is_union_type): Define new functions.
	(type_base::get_canonical_type_for, maybe_adjust_canonical_type)
	(method_type::method_type, method_type::set_class_type)
	(function_decl::get_pretty_representation)
	(function_decl::get_first_non_implicit_parm)
	(function_decl::clone): Adjust.
	(equals): Adjust the overload for function_type.
	(struct class_or_union::priv): Define new type.
	(class::priv::{declaration_, definition_of_declaration_,
	member_types_, data_members_, non_static_data_members_,
	member_functions_, mem_fns_map_, member_function_templates_,
	member_class_templates_, is_declaration_only_}): Move these data
	member into class_or_union::priv.
	(class_priv::{mark_as_being_compared, unmark_as_being_compared,
	comparison_started}): Moved these member functions to
	class_or_union::priv.
	(class_or_union::{class_or_union, traverse, ~class_or_union,
	add_member_decl, remove_member_decl, insert_member_type,
	add_member_type, get_size_in_bits, remove_member_type,
	get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits,
	get_is_declaration_only, set_is_declaration_only,
	set_definition_of_declaration, get_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	get_member_types, find_member_type, add_data_member,
	get_data_member, find_data_member, add_member_function,
	get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates,
	has_no_member, insert_member_decl, operator==}): Define new member
	functions.
	(class_decl::{add_member_decl, remove_member_decl,
	insert_member_type, add_member_type, get_size_in_bits,
	remove_member_type, get_alignment_in_bits, set_alignment_in_bits,
	set_size_in_bits, get_is_declaration_only,
	set_is_declaration_only, set_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	get_member_types, find_member_type, add_data_member,
	get_data_member, find_data_member, add_member_function,
	get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates): Move these
	member functions into class_or_union.
	(class_decl::{class_decl, get_definition_of_declaration,
	insert_member_decl, add_member_function, has_no_base_nor_member}):
	Adjust.
	(equals, copy_member_function): Define new overloads for
	class_or_union.
	(equals): Adjust the overload for class_decl.
	(method_decl::{method_decl, set_linkage_name, ~method_decl,
	get_type, set_scope}): Remove from the class_decl scope.
	(member_base::operator==, member_function_template::operator==):
	Likewise.
	(member_function_template::traverse)
	(member_class_template::operator==)
	(member_class_template::traverse): Likewise.
	(operator==, operator!=): Adjust the overlod for
	member_function_template_sptr.
	(is_method_decl, fixup_virtual_member_function)
	(set_member_is_static): Adjust.
	(virtual_member_function_less_than::operator()): Likewise.
	(union_decl::{union_decl, get_pretty_representation, operator==,
	traverse}): Define new member functions.
	(equals, copy_member_function): Define new overloads for
	union_decl.
	(hash_type_or_decl): Adjust.
	(ir_node_visitor::visit_{begin, end}): Adjust. Add new overloads
	for class_or_union* and union_decl*.
	* include/abg-comparison.h (changed_member_function_sptr)
	(string_member_function_sptr_map): Adjust these typedefs.
	(class class_or_union_diff): Declare new type.
	(class_diff): Adjust to make this inherit the new
	class_or_union_diff type.
	(class_diff::{get_priv, member_types_changes,
	data_members_changes, inserted_data_members, deleted_data_members,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes}): These member functions got moved
	into -- and shared with -- class_or_union_diff class.
	(class union_diff): Declare new type.
	(typedef union_diff_sptr): New typedef.
	(compute_diff): New overload for union_diff
	(is_class_diff, is_union_diff): Declare new functions.
	* src/abg-comparison.cc (is_class_diff, is_union_diff): Define new
	functions.
	(compute_diff_for_types): Support union_decl.
	(represent):  Adjust.
	(represent_data_member): Do not show offset information for data
	members of unions as all union data members are at offset 0.
	(struct class_or_union_diff::priv): New type.
	(class_or_union_diff::priv::{member_type_has_changed,
	subtype_changed_dm, member_class_tmpl_has_changed,
	get_deleted_non_static_data_members_number,
	get_inserted_non_static_data_members_number,
	count_filtered_subtype_changed_dm, count_filtered_changed_dm,
	count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns,
	count_filtered_deleted_mem_fns}): Define new member functions.
	(class_or_union_diff::{class_or_union_diff, finish_diff_type,
	lookup_tables_empty, lookup_tables_empty,
	ensure_lookup_tables_populated, allocate_priv_data, get_priv,
	~class_or_union_diff, first_class_or_union, second_class_or_union,
	member_types_changes, member_types_changes, data_members_changes,
	inserted_data_members, deleted_data_members, member_fns_changes,
	changed_member_fns, member_fns_changes, inserted_member_fns,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes, member_class_tmpls_changes,
	has_changes, has_local_changes, report, chain_into_hierarchy}):
	Define new member functions.
	(class_diff::priv::{member_types_changes_, data_members_changes,
	member_fn_tmpls_changes_, member_class_tmpls_changes_,
	deleted_member_types_, inserted_member_types_,
	changed_member_types_, sorted_changed_member_types_,
	deleted_data_members_, deleted_dm_by_offset_,
	inserted_data_members_, inserted_dm_by_offset_,
	subtype_changed_dm_, sorted_subtype_changed_dm_, changed_dm_,
	sorted_changed_dm_, deleted_member_functions_,
	inserted_member_functions_, changed_member_functions_,
	sorted_changed_member_functions_, deleted_member_class_tmpls_,
	inserted_member_class_tmpls_, changed_member_class_tmpls_,
	sorted_changed_member_class_tmpls_}): Move these data members into
	class_or_union_diff::priv.
	(class_diff::{clear_lookup_tables, lookup_tables_empty,
	ensure_lookup_tables_populate}): Adjust.
	(class_diff::allocate_priv_data): Define new function.
	(class_diff::priv::{count_filtered_changed_mem_fns,
	count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns,
	chain_into_hierarchy, class_diff}): Likewise.
	(class_diff::{member_types_changes, data_members_changes,
	inserted_data_members, deleted_data_members,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes}): These are deleted as they got moved
	to class_or_union_diff.
	(class_diff::report): Adjust.
	(union_diff::{clear_lookup_tables, lookup_tables_empty,
	ensure_lookup_tables_populated, allocate_priv_data, union_diff,
	finish_diff_type, first_union_decl, second_union_decl,
	get_pretty_representation, report}): Define new functions.
	(compute_diff): Define an overload for union_decl_sptr.
	(function_decl_diff::report): Adjust.
	(corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars):
	Adjust.
	(corpus_diff::report): Adjust.
	* src/abg-hash.cc (member_base:#️⃣:operator)
	(member_function_template:#️⃣:operator)
	(member_class_template:#️⃣:operator): Move these out of the
	class_decl scope.
	(class_or_union:#️⃣:operator): Define new member function.
	(class_decl:#️⃣:operator): Adjust.
	(type_base::dynamic_hash::operator): Support hashing of
	union_decl.  Adjust.
	* src/abg-suppression.cc (type_suppression::suppresses_diff):
	Adjust.
	* src/abg-dwarf-reader.cc (typedef die_class_or_union_map_type):
	Define new typedef.
	(read_context::{die_wip_classes_map_,
	alternate_die_wip_classes_map_, type_unit_die_wip_classes_map_):
	Make these data member have type die_class_or_union_map_type.
	(read_context::{lookup_type_from_die_offset, die_wip_classes_map,
	is_wip_class_die_offset, resolve_declaration_only_classes}):
	Adjust.
	(finish_member_function_reading, build_class_type_and_add_to_ir)
	(build_function_type, build_function_decl, build_reference_type)
	(type_is_suppressed, build_function_decl)
	(maybe_canonicalize_type, maybe_set_member_type_access_specifier):
	Adjust.
	(build_union_type_and_add_to_ir): Define new static function.
	(build_ir_node_from_die): Support DW_TAG_union_type DIE tag.
	* src/abg-reader.cc (handle_element_node): Handle union_decl.
	(build_function_decl, build_function_decl_if_not_suppressed):
	Adjust.
	(build_union_decl_if_not_suppressed, build_union_decl)
	(handle_union_decl): Define new functions.
	(build_class_decl): Adjust.
	* src/abg-writer.cc (record_decl_only_type_as_emitted): Adjust.
	(write_decl): Adjust. Support writting union_decl type.
p	(write_class_decl_opening_tag, write_class_decl): Adjust.  Call
	the new write_class_or_union_is_declaration_only.
	(write_union_decl_opening_tag, write_union_decl): Define new
	static functions.
	(write_member_tpe): Support writting union decl.
	* tests/test-diff-dwarf.cc (in_out_specs): Add new tests for this
	union type support.
	* tests/data/test-diff-dwarf/libtest37-union-v0.so: New test input.
	* tests/data/test-diff-dwarf/libtest37-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/libtest38-union-v0.so: Likewise.
	* tests/data/test-diff-dwarf/libtest38-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/libtest39-union-v0.so: Likewise.
	* tests/data/test-diff-dwarf/libtest39-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/test37-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test39-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test37-union-v0.cc: Source code for
	new test input.
	* tests/data/test-diff-dwarf/test37-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf/test38-union-v0.cc: Likewise.
	* tests/data/test-diff-dwarf/test38-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf/test39-union-v0.cc: Likewise.
	* tests/data/test-diff-dwarf/test39-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Update test reference.
	* 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-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/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/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>
2016-11-22 16:22:25 +01:00
Dodji Seketeli
f9ed75b8c4 Support empty properties in INI files
The ini file parser doesn't support parsing properties with no value.
This patch adds that feature, as it turned out to be a pre-requisite
for reading Linux Kernel ABI whitelist files.

	* include/abg-ini.h (simple_property::simple_property): Add a new
	constructor for empty values.
	(simple_property::has_empty_value): Declare new member function.
	* src/abg-ini.cc (simple_property::{simple_property,
	has_empty_value}): Define new member functions.
	(read_context::read_property): Support reading a property with no
	value.
	(write_property_value, write_property): Support writting a
	property with empty value.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-10 14:09:51 +01:00
Dodji Seketeli
b96ecbc065 Rename config::property_vector into config::properties_type
This renaming makes the code looks more consistent.

	* include/abg-ini.h (config::properties_type): Rename the typedef
	config::property_vector into this.
	(config::section::{section, get_properties, set_properties}):
	Adjust.
	* src/abg-ini.cc (config::section::priv::properties_): Adjust the
	name of its type.
	(config::section::{section, get_properties, set_properties,
	find_property}): Adjust.
	(write_section): Adjust.
	* src/abg-suppression.cc (read_function_suppression): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-10 14:09:50 +01:00