mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-14 14:04:45 +00:00
The Git repository of the Libabigail Project
5eb4d7627a
We ought to detect when a data member is replaced by an anonymous data member in a way that doesn't change the ABI in an incompatible way, especially when that change is non equivocal. For instance, consider this ABI-visible struct: struct S { int a; }; Now, consider that it's changed into: struct S { union { int a; char b; }; }; Stricto sensu, the bit-layout of struct S doesn't change and so that change isn't ABI-incompatible. The current version of libabigail however flags that change as a /potential/ issue and asks the user for further review. It appears that this class of changes is frequent enough to be annoying, especially in semi-automatic ABI compliance checking setups where we want the least possible "false positives". This patch detects that kind of change patterns where a data member is replaced by an anonymous data member in a benign way, in terms of ABI. So now let's look at a more complicated example where an ABI-visible type looks like: struct S { int a; int b; int c; }; Now suppose that type was changed into: struct S { union { int tag[3]; struct { int a; int b; int c; }; }; }; The patch allows abidiff to recognise that kind of pattern, filter out the detected change and report by default that the two binaries are ABI compatible. Here are the output that we'd get: $ abidiff test-v0.o test-v1.o Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function Variables changes summary: 0 Removed, 0 Changed, 0 Added variable When asked to show the detailed of the filtered out changes, we get: $ abidiff --harmless test-v0.o test-v1.o 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(S*)' at test-v1.cc:18:1 has some indirect sub-type changes: parameter 1 of type 'S*' has sub-type changes: in pointed to type 'struct S' at test-v1.cc:1:1: type size hasn't changed data members 'S::a', 'S::b', 'S::c' were replaced by anonymous data member: 'union {int tag[3]; struct {int a; int b; int c;};}' And using the leaf-node reporter, that would give: $ abidiff --leaf-changes-only --harmless test-v0.o test-v1.o Leaf changes summary: 1 artifact changed Changed leaf types summary: 1 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 0 Added function Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 'struct S at test-v0.cc:1:1' changed: type size hasn't changed data members 'S::a', 'S::b', 'S::c' were replaced by anonymous data member: 'union {int tag[3]; struct {int a; int b; int c;};}' * include/abg-comp-filter.h (has_data_member_replaced_by_anon_dm): Declare new function. * include/abg-comparison.h (changed_var_sptr) (changed_var_sptrs_type): Declare new typedefs. (HARMLESS_DATA_MEMBER_CHANGE_CATEGORY): Add a new enumerator to the diff_category enum. (EVERYTHING_CATEGORY): In the diff_category, adjust this enumerator to OR the new HARMLESS_DATA_MEMBER_CHANGE_CATEGORY into it. (SUPPRESSED_CATEGORY, PRIVATE_TYPE_CATEGORY) (SIZE_OR_OFFSET_CHANGE_CATEGORY, VIRTUAL_MEMBER_CHANGE_CATEGORY) (CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY) (FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY) (FN_RETURN_TYPE_CV_CHANGE_CATEGORY, VAR_TYPE_CV_CHANGE_CATEGORY) (VOID_PTR_TO_PTR_CHANGE_CATEGORY) (BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY): Adjust the value of these enumerators of the diff_category enum. (class_or_union_diff::{data_members_replaced_by_adms, ordered_data_members_replaced_by_adms}): Declare new member functions. * include/abg-fwd.h (var_decl_wptr): Declare new typedef. (get_next_data_member, get_first_non_anonymous_data_member) (find_data_member_from_anonymous_data_member) (get_absolute_data_member_offset): Declare new functions. * include/abg-ir.h (struct anonymous_dm_hash): Declare new type. (anonymous_data_member_sptr_set_type): Declare new typedef. (class decl_base): Befriend class class_or_union. (class dm_context_rel): Pimpl-ify this class. (dm_context_rel::{g,s}et_anonymous_data_member_types): Declare new member functions. (var_decl::get_anon_dm_reliable_name): Declare new member function. (class var_decl): Make get_absolute_data_member_offset, get_absolute_data_member_offset be friends of this. (class_or_union::maybe_fixup_members_of_anon_data_member): Declare new protected member function. * src/abg-comp-filter.cc (has_data_member_replaced_by_anon_dm): Define new function. (categorize_harmless_diff_node): Use the above. * src/abg-comparison-priv.h (class_or_union_diff::priv::{dms_replaced_by_adms_, changed_var_sptrs_type dms_replaced_by_adms_ordered_}): Add new data members. (data_member_comp::compare_data_members): Factorize this out of ... (data_member_comp::operator()(decl_base_sptr&, decl_base_sptr&)): ... this. (data_member_comp::operator()(changed_var_sptr&, changed_var_sptr&)): Add new member function. (sort_changed_data_members): Declare ... * src/abg-comparison.cc (sort_changed_data_members): ... new function. (get_default_harmless_categories_bitmap): Adjust to take the new abigail::comparison::HARMLESS_DATA_MEMBER_CHANGE_CATEGORY into account. (operator<<(ostream& o, diff_category c)): Likewise. (class_or_union_diff::ensure_lookup_tables_populated): Handle Handle the insertion of anonymous data members to replace existing data members. (class_or_union_diff::{data_members_replaced_by_adms, ordered_data_members_replaced_by_adms}): Define new accessors. (suppression_categorization_visitor::visit_end): Propagate the SUPPRESSION_CATEGORIZATION_VISITOR from changes to the type of the data member if the data member doesn't have real local changes. * src/abg-default-reporter.cc (default_reporter::report): Report about anonymous data members that replace data members. * src/abg-ir.cc (struct dm_context_rel::priv): Define new data structure. (dm_context_rel::{dm_context_rel, get_is_laid_out, set_is_laid_out, get_offset_in_bits, set_offset_in_bits, operator==, operator!=, get_anonymous_data_member, set_anonymous_data_member}): Define the member functions here as they are not inline anymore. (class_or_union::maybe_fixup_members_of_anon_data_member): Define new member function. (class_or_union::add_data_member): Use it. (get_first_non_anonymous_data_member, get_next_data_member) (get_absolute_data_member_offset) (find_data_member_from_anonymous_data_member): Define new functions. * src/abg-reporter-priv.h (maybe_report_data_members_replaced_by_anon_dm): Declare ... * src/abg-reporter-priv.cc (maybe_report_data_members_replaced_by_anon_dm): ... new function. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report data members replaced by anonymous data members. * tests/data/test-diff-filter/test-PR25661-[1-6]-report-[1-4].txt: New test reference outputs. * tests/data/test-diff-filter/test-PR25661-[1-6]-v{0,1}.c: Test source code files. * tests/data/test-diff-filter/test-PR25661-[1-6]-v{0,1}.o: Test binary input files. * tests/data/Makefile.am: Add the new test files above to source distribution. * tests/test-diff-filter.cc (in_out_specs): Add the binary test inputs above to this test harness. * tests/data/test-diff-dwarf/test45-anon-dm-change-report-0.txt: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
---|---|---|
autoconf-archive | ||
bash-completion | ||
doc | ||
include | ||
m4 | ||
scripts | ||
src | ||
tests | ||
tools | ||
.clang-format | ||
.gitignore | ||
abigail.m4 | ||
AUTHORS | ||
ChangeLog | ||
COMMIT-LOG-GUIDELINES | ||
COMPILING | ||
configure.ac | ||
CONTRIBUTING | ||
COPYING | ||
COPYING-GPLV3 | ||
COPYING-LGPLV2 | ||
COPYING-LGPLV3 | ||
default.abignore | ||
gen-changelog.py | ||
install-sh | ||
libabigail.pc.in | ||
ltmain.sh | ||
Makefile.am | ||
NEWS | ||
README | ||
release-text-template.txt | ||
update-copyright.sh | ||
VISIBILITY |
This is the Application Binary Interface Generic Analysis and Instrumentation Library. It aims at constructing, manipulating, serializing and de-serializing ABI-relevant artifacts. The set of artifacts that we are intersted is made of quantities like types, variable, fonctions and declarations of a given library or program. For a given library or program this set of quantities is called an ABI corpus. This library aims at (among other things) providing a way to compare two ABI Corpora (apparently the plural of corpus is copora, heh, that's cool), provide detailed information about their differences, and help build tools to infer interesting conclusions about these differences. You are welcome to contribute to this project after reading the files CONTRIBUTING and COMMIT-LOG-GUIDELINES files in the source tree. Communicating with the maintainers of this project -- including sending patches to be include to the source code -- happens via email at libabigail@sourceware.org.