diff --git a/include/abg-comparison.h b/include/abg-comparison.h index 48818577..2c1008da 100644 --- a/include/abg-comparison.h +++ b/include/abg-comparison.h @@ -898,6 +898,15 @@ public: edit_script& base_changes(); + const string_base_sptr_map& + deleted_bases() const; + + const string_base_sptr_map& + inserted_bases() const; + + const string_changed_base_map& + changed_bases(); + const edit_script& member_types_changes() const; diff --git a/src/abg-comp-filter.cc b/src/abg-comp-filter.cc index 4ea9ce6e..a6247086 100644 --- a/src/abg-comp-filter.cc +++ b/src/abg-comp-filter.cc @@ -484,6 +484,28 @@ static bool has_non_virtual_mem_fn_change(const diff* diff) {return has_non_virtual_mem_fn_change(dynamic_cast(diff));} +/// Test if a class_diff carries base classes adding or removals. +/// +/// @param diff the class_diff to consider. +/// +/// @return true iff @p diff carries base classes adding or removals. +static bool +base_classes_added_or_removed(const class_diff* diff) +{ + if (!diff) + return false; + return diff->deleted_bases().size() || diff->inserted_bases().size(); +} + +/// Test if a class_diff carries base classes adding or removals. +/// +/// @param diff the class_diff to consider. +/// +/// @return true iff @p diff carries base classes adding or removals. +static bool +base_classes_added_or_removed(const diff* diff) +{return base_classes_added_or_removed(dynamic_cast(diff));} + /// The visiting code of the harmless_filter. /// /// @param d the diff node being visited. @@ -552,7 +574,8 @@ harmful_filter::visit(diff* d, bool pre) if (type_size_changed(f, s) || data_member_offset_changed(f, s) || non_static_data_member_type_size_changed(f, s) - || non_static_data_member_added_or_removed(d)) + || non_static_data_member_added_or_removed(d) + || base_classes_added_or_removed(d)) category |= SIZE_OR_OFFSET_CHANGE_CATEGORY; if (has_virtual_mem_fn_change(d)) diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc index a1601425..673dbb4a 100644 --- a/src/abg-comparison.cc +++ b/src/abg-comparison.cc @@ -3194,6 +3194,30 @@ const edit_script& class_diff::base_changes() const {return priv_->base_changes_;} +/// Getter for the deleted base classes of the diff. +/// +/// @return a map containing the deleted base classes, keyed with +/// their pretty representation. +const string_base_sptr_map& +class_diff::deleted_bases() const +{return priv_->deleted_bases_;} + +/// Getter for the inserted base classes of the diff. +/// +/// @return a map containing the inserted base classes, keyed with +/// their pretty representation. +const string_base_sptr_map& +class_diff::inserted_bases() const +{return priv_->inserted_bases_;} + +/// Getter for the changed base classes of the diff. +/// +/// @return a map containing the changed base classes, keyed with +/// their pretty representation. +const string_changed_base_map& +class_diff::changed_bases() +{return priv_->changed_bases_;} + /// @return the edit script of the bases of the two classes. edit_script& class_diff::base_changes() diff --git a/tests/Makefile.am b/tests/Makefile.am index f8a1003c..6fcf5494 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -152,6 +152,11 @@ data/test-diff-dwarf/test7-v0.o \ data/test-diff-dwarf/test7-v1.cc \ data/test-diff-dwarf/test7-v1.o \ data/test-diff-dwarf/test7-report.txt \ +data/test-diff-dwarf/test8-v0.cc \ +data/test-diff-dwarf/test8-v0.o \ +data/test-diff-dwarf/test8-v1.cc \ +data/test-diff-dwarf/test8-v1.o \ +data/test-diff-dwarf/test8-report.txt \ \ data/test-read-dwarf/test0 \ data/test-read-dwarf/test0.abi \ @@ -224,7 +229,12 @@ data/test-diff-filter/test12-v0.cc \ data/test-diff-filter/test12-v1.cc \ data/test-diff-filter/test12-v0.o \ data/test-diff-filter/test12-v1.o \ -data/test-diff-filter/test12-report.txt +data/test-diff-filter/test12-report.txt \ +data/test-diff-filter/test13-v0.cc \ +data/test-diff-filter/test13-v1.cc \ +data/test-diff-filter/test13-v0.o \ +data/test-diff-filter/test13-v1.o \ +data/test-diff-filter/test13-report.txt clean-local: clean-local-check .PHONY: clean-local-check diff --git a/tests/data/test-diff-dwarf/test8-report.txt b/tests/data/test-diff-dwarf/test8-report.txt new file mode 100644 index 00000000..aba1e688 --- /dev/null +++ b/tests/data/test-diff-dwarf/test8-report.txt @@ -0,0 +1,30 @@ +Functions changes summary: 0 Removed, 1 Changed, 1 Added functions +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + +1 function with some indirect sub-type change: + + [C]'function void foo(const S&)' has some indirect sub-type changes: + parameter 0 of type 'const S&' has sub-type changes: + in unqualified underlying type 'S&': + in referenced type 'struct S': + size changed from 64 to 96 bits + 1 base class change: + 'struct B0' changed: + 1 data member change: + 'char B0::m0' access changed from 'public' to 'private' + + + 1 base class insertion: + class B1 + 1 data member change: + 'int S::m0' offset changed from 32 to 64, access changed from 'public' to 'private' + and its type 'int' changed: + name changed from 'int' to 'char' + size changed from 32 to 8 bits + alignment changed from 32 to 8 bits + + +1 Added function: + 'method B1::B1()' + + diff --git a/tests/data/test-diff-dwarf/test8-v0.cc b/tests/data/test-diff-dwarf/test8-v0.cc new file mode 100644 index 00000000..a86dd858 --- /dev/null +++ b/tests/data/test-diff-dwarf/test8-v0.cc @@ -0,0 +1,21 @@ +struct B0 +{ + char m0; + + B0() + : m0(0) + {} +}; + +struct S : public B0 +{ + int m0; + + S() + : m0(0) + {} +}; + +void +foo(S&) +{} diff --git a/tests/data/test-diff-dwarf/test8-v0.o b/tests/data/test-diff-dwarf/test8-v0.o new file mode 100644 index 00000000..050c0c21 Binary files /dev/null and b/tests/data/test-diff-dwarf/test8-v0.o differ diff --git a/tests/data/test-diff-dwarf/test8-v1.cc b/tests/data/test-diff-dwarf/test8-v1.cc new file mode 100644 index 00000000..88008643 --- /dev/null +++ b/tests/data/test-diff-dwarf/test8-v1.cc @@ -0,0 +1,33 @@ +class B0 +{ + char m0; + +public: + B0() + : m0(0) + {} +}; + +class B1 +{ + unsigned m0; + +public: + B1() + : m0(0) + {} +}; + +class S : public B0, public B1 +{ + char m0; + +public: + S() + : m0(0) + {} +}; + +void +foo(S&) +{} diff --git a/tests/data/test-diff-dwarf/test8-v1.o b/tests/data/test-diff-dwarf/test8-v1.o new file mode 100644 index 00000000..fd659868 Binary files /dev/null and b/tests/data/test-diff-dwarf/test8-v1.o differ diff --git a/tests/data/test-diff-filter/test13-report.txt b/tests/data/test-diff-filter/test13-report.txt new file mode 100644 index 00000000..7f7a1948 --- /dev/null +++ b/tests/data/test-diff-filter/test13-report.txt @@ -0,0 +1,24 @@ +Functions changes summary: 0 Removed, 1 Changed, 1 Added functions +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + +1 function with some indirect sub-type change: + + [C]'function void foo(const S&)' has some indirect sub-type changes: + parameter 0 of type 'const S&' has sub-type changes: + in unqualified underlying type 'S&': + in referenced type 'struct S': + size changed from 64 to 96 bits + no base class change (1 filtered); + 1 base class insertion: + class B1 + 1 data member change: + 'int S::m0' offset changed from 32 to 64 + and its type 'int' changed: + size changed from 32 to 8 bits + alignment changed from 32 to 8 bits + + +1 Added function: + 'method B1::B1()' + + diff --git a/tests/data/test-diff-filter/test13-v0.cc b/tests/data/test-diff-filter/test13-v0.cc new file mode 100644 index 00000000..a86dd858 --- /dev/null +++ b/tests/data/test-diff-filter/test13-v0.cc @@ -0,0 +1,21 @@ +struct B0 +{ + char m0; + + B0() + : m0(0) + {} +}; + +struct S : public B0 +{ + int m0; + + S() + : m0(0) + {} +}; + +void +foo(S&) +{} diff --git a/tests/data/test-diff-filter/test13-v0.o b/tests/data/test-diff-filter/test13-v0.o new file mode 100644 index 00000000..2be53a36 Binary files /dev/null and b/tests/data/test-diff-filter/test13-v0.o differ diff --git a/tests/data/test-diff-filter/test13-v1.cc b/tests/data/test-diff-filter/test13-v1.cc new file mode 100644 index 00000000..88008643 --- /dev/null +++ b/tests/data/test-diff-filter/test13-v1.cc @@ -0,0 +1,33 @@ +class B0 +{ + char m0; + +public: + B0() + : m0(0) + {} +}; + +class B1 +{ + unsigned m0; + +public: + B1() + : m0(0) + {} +}; + +class S : public B0, public B1 +{ + char m0; + +public: + S() + : m0(0) + {} +}; + +void +foo(S&) +{} diff --git a/tests/data/test-diff-filter/test13-v1.o b/tests/data/test-diff-filter/test13-v1.o new file mode 100644 index 00000000..ebd39810 Binary files /dev/null and b/tests/data/test-diff-filter/test13-v1.o differ diff --git a/tests/test-diff-dwarf.cc b/tests/test-diff-dwarf.cc index 51dc3120..7ce154a5 100644 --- a/tests/test-diff-dwarf.cc +++ b/tests/test-diff-dwarf.cc @@ -108,7 +108,13 @@ InOutSpec in_out_specs[] = "data/test-diff-dwarf/test7-v0.o", "data/test-diff-dwarf/test7-v1.o", "data/test-diff-dwarf/test7-report.txt", - "output/test-diff-dwarf/test6-report.txt" + "output/test-diff-dwarf/test7-report.txt" + }, + { + "data/test-diff-dwarf/test8-v0.o", + "data/test-diff-dwarf/test8-v1.o", + "data/test-diff-dwarf/test8-report.txt", + "output/test-diff-dwarf/test8-report.txt" }, // This should be the last entry {NULL, NULL, NULL, NULL} diff --git a/tests/test-diff-filter.cc b/tests/test-diff-filter.cc index 0a3d4866..a1c3614c 100644 --- a/tests/test-diff-filter.cc +++ b/tests/test-diff-filter.cc @@ -152,6 +152,13 @@ InOutSpec in_out_specs[] = "data/test-diff-filter/test12-report.txt", "output/test-diff-filter/test12-report.txt", }, + { + "data/test-diff-filter/test13-v0.o", + "data/test-diff-filter/test13-v1.o", + "--no-harmless", + "data/test-diff-filter/test13-report.txt", + "output/test-diff-filter/test13-report.txt", + }, // This should be the last entry {NULL, NULL, NULL, NULL, NULL} };