From ef7198310de071963ea0c0e408aafb11c16efe3f Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Wed, 9 May 2018 08:51:50 +0200 Subject: [PATCH] Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli --- include/abg-comparison.h | 6 + include/abg-fwd.h | 63 ++- include/abg-ir.h | 3 + src/abg-comparison.cc | 34 ++ src/abg-ir.cc | 446 ++++++++++++++++++++- src/abg-leaf-reporter.cc | 17 +- src/abg-reporter-priv.cc | 94 +++-- tests/data/Makefile.am | 6 + tests/data/test-annotate/libtest23.so.abi | 4 +- .../data/test-annotate/libtest24-drop-fns-2.so.abi | 8 +- tests/data/test-annotate/libtest24-drop-fns.so.abi | 8 +- tests/data/test-annotate/test13-pr18894.so.abi | 48 +-- tests/data/test-annotate/test14-pr18893.so.abi | 18 +- tests/data/test-annotate/test15-pr18892.so.abi | 126 +++--- tests/data/test-annotate/test17-pr19027.so.abi | 364 ++++++++--------- .../test18-pr19037-libvtkRenderingLIC-6.1.so.abi | 6 +- .../test19-pr19023-libtcmalloc_and_profiler.so.abi | 64 +-- .../test20-pr19025-libvtkParallelCore-6.1.so.abi | 6 +- tests/data/test-annotate/test21-pr19092.so.abi | 180 ++++----- .../test-diff-dwarf/test43-PR22913-report-0.txt | 2 +- .../libtest44-anonymous-data-member-v0.so | Bin 0 -> 9208 bytes .../libtest44-anonymous-data-member-v1.so | Bin 0 -> 9232 bytes .../test30-pr18904-rvalueref-report0.txt | 23 +- .../test30-pr18904-rvalueref-report1.txt | 23 +- .../test30-pr18904-rvalueref-report2.txt | 23 +- .../test31-pr18535-libstdc++-report-0.txt | 12 +- .../test31-pr18535-libstdc++-report-1.txt | 12 +- .../test35-pr18754-no-added-syms-report-0.txt | 23 +- .../test44-anonymous-data-member-report-0.txt | 30 ++ .../test44-anonymous-data-member-report-1.txt | 26 ++ .../test44-anonymous-data-member-v0.c | 25 ++ .../test44-anonymous-data-member-v1.c | 27 ++ ...x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt | 4 +- ...-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt | 2 +- ...-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt | 4 +- tests/test-diff-filter.cc | 14 + 36 files changed, 1199 insertions(+), 552 deletions(-) create mode 100755 tests/data/test-diff-filter/libtest44-anonymous-data-member-v0.so create mode 100755 tests/data/test-diff-filter/libtest44-anonymous-data-member-v1.so create mode 100644 tests/data/test-diff-filter/test44-anonymous-data-member-report-0.txt create mode 100644 tests/data/test-diff-filter/test44-anonymous-data-member-report-1.txt create mode 100644 tests/data/test-diff-filter/test44-anonymous-data-member-v0.c create mode 100644 tests/data/test-diff-filter/test44-anonymous-data-member-v1.c diff --git a/include/abg-comparison.h b/include/abg-comparison.h index 5d25508..592009b 100644 --- a/include/abg-comparison.h +++ b/include/abg-comparison.h @@ -2664,6 +2664,12 @@ is_class_diff(const diff* diff); const union_diff* is_union_diff(const diff* diff); +const class_or_union_diff* +is_class_or_union_diff(const diff* d); + +const class_or_union_diff* +is_anonymous_class_or_union_diff(const diff* d); + const array_diff* is_array_diff(const diff* diff); diff --git a/include/abg-fwd.h b/include/abg-fwd.h index 9fd2e3e..24e37ec 100644 --- a/include/abg-fwd.h +++ b/include/abg-fwd.h @@ -362,13 +362,13 @@ is_at_global_scope(const decl_base&); bool is_at_global_scope(const decl_base_sptr); -bool +class_or_union* is_at_class_scope(const decl_base_sptr); -bool +class_or_union* is_at_class_scope(const decl_base*); -bool +class_or_union* is_at_class_scope(const decl_base&); bool @@ -428,6 +428,9 @@ is_typedef(type_base*); enum_type_decl_sptr is_enum_type(const type_or_decl_base_sptr&); +bool +is_class_type(const type_or_decl_base&); + class_decl* is_class_type(const type_or_decl_base*); @@ -440,6 +443,9 @@ is_class_or_union_type(const type_or_decl_base*); class_or_union_sptr is_class_or_union_type(const type_or_decl_base_sptr&); +bool +is_union_type(const type_or_decl_base&); + union_decl* is_union_type(const type_or_decl_base*); @@ -586,6 +592,42 @@ is_data_member(const var_decl_sptr); var_decl_sptr is_data_member(const decl_base_sptr&); +var_decl* +is_data_member(const decl_base *); + +bool +is_anonymous_data_member(const decl_base&); + +const var_decl* +is_anonymous_data_member(const decl_base*); + +var_decl_sptr +is_anonymous_data_member(const decl_base_sptr&); + +var_decl_sptr +is_anonymous_data_member(const var_decl_sptr&); + +const var_decl* +is_anonymous_data_member(const var_decl*); + +bool +is_anonymous_data_member(const var_decl&); + +const class_or_union* +anonymous_data_member_to_class_or_union(const var_decl*); + +class_or_union_sptr +anonymous_data_member_to_class_or_union(const var_decl_sptr&); + +const class_or_union_sptr +data_member_has_anonymous_type(const var_decl& d); + +const class_or_union_sptr +data_member_has_anonymous_type(const var_decl* d); + +const class_or_union_sptr +data_member_has_anonymous_type(const var_decl_sptr& d); + array_type_def* is_array_type(const type_or_decl_base* decl); @@ -844,6 +886,21 @@ string get_pretty_representation(const method_type_sptr&, bool internal = false); +string +get_class_or_union_flat_representation(const class_or_union& cou, + const string& indent, + bool one_line); + +string +get_class_or_union_flat_representation(const class_or_union* cou, + const string& indent, + bool one_line); + +string +get_class_or_union_flat_representation(const class_or_union_sptr& cou, + const string& indent, + bool one_line); + bool odr_is_relevant(const type_or_decl_base&); diff --git a/include/abg-ir.h b/include/abg-ir.h index 47816d8..a5c755f 100644 --- a/include/abg-ir.h +++ b/include/abg-ir.h @@ -2479,6 +2479,9 @@ public: interned_string get_id() const; + virtual const interned_string& + get_qualified_name(bool internal = false) const; + virtual size_t get_hash() const; diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc index d40f4db..0401440 100644 --- a/src/abg-comparison.cc +++ b/src/abg-comparison.cc @@ -593,6 +593,33 @@ const union_diff* is_union_diff(const diff* diff) {return dynamic_cast(diff);} +/// Test if a diff node is a @ref class_or_union_diff node. +/// +/// @param d the diff node to consider. +/// +/// @return a non-nil pointer to the @ref class_or_union_diff denoted +/// by @p d iff @p d is a @ref class_or_union_diff. +const class_or_union_diff* +is_class_or_union_diff(const diff* d) +{return dynamic_cast(d);} + +/// Test if a diff node is a @ref class_or_union_diff between two +/// anonymous classes or unions. +/// +/// @param d the diff node to consider. +/// +/// @return a non-nil pointer to the @ref class_or_union_diff iff @p +/// denoted by @p d iff @p is pointer to an anonymous class or union +/// diff. +const class_or_union_diff* +is_anonymous_class_or_union_diff(const diff* d) +{ + if (const class_or_union_diff *dif = is_class_or_union_diff(d)) + if (dif->first_class_or_union()->get_is_anonymous()) + return dif; + return 0; +} + /// Test if a diff node is a @ref typedef_diff node. /// /// @param diff the diff node to consider. @@ -9819,6 +9846,13 @@ struct leaf_diff_node_marker_visitor : public diff_node_visitor // part of the variable change whose pointer type changed, for // instance. && !is_pointer_diff(d) + // An anonymous class or union diff doesn't make sense on its + // own. It must have been described already by the diff of + // the enclosing struct or union if 'd' is from an anonymous + // data member, or from a typedef change if 'd' is from a + // typedef change which underlying type is an anonymous + // struct/union. + && !is_anonymous_class_or_union_diff(d) // Don't show decl-only-ness changes of classes either. && !filtering::has_class_decl_only_def_change(d)) { diff --git a/src/abg-ir.cc b/src/abg-ir.cc index d731ddd..703ff99 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -3787,6 +3787,171 @@ is_data_member(const decl_base_sptr& d) return var_decl_sptr(); } +/// Test if a decl is a data member. +/// +/// @param d the decl to consider. +/// +/// @return a pointer to the data member iff @p d is a data member, or +/// a null pointer. +var_decl* +is_data_member(const decl_base *d) +{ + if (var_decl *v = is_var_decl(d)) + if (is_data_member(v)) + return v; + return 0; +} + +/// Test if a decl is an anonymous data member. +/// +/// @param d the decl to consider. +/// +/// @return true iff @p d is an anonymous data member. +bool +is_anonymous_data_member(const decl_base& d) +{return is_anonymous_data_member(&d);} + +/// Test if a decl is an anonymous data member. +/// +/// @param d the decl to consider. +/// +/// @return a non-nil pointer to the @ref var_decl denoted by @p d if +/// it's an anonymous data member. Otherwise returns a nil pointer. +const var_decl* +is_anonymous_data_member(const decl_base* d) +{ + if (const var_decl* v = is_data_member(d)) + { + if (is_anonymous_data_member(v)) + return v; + } + return 0; +} + +/// Test if a decl is an anonymous data member. +/// +/// @param d the decl to consider. +/// +/// @return a non-nil pointer to the @ref var_decl denoted by @p d if +/// it's an anonymous data member. Otherwise returns a nil pointer. +var_decl_sptr +is_anonymous_data_member(const decl_base_sptr& d) +{ + if (var_decl_sptr v = is_data_member(d)) + return is_anonymous_data_member(v); + return var_decl_sptr(); +} + +/// Test if a @ref var_decl is an anonymous data member. +/// +/// @param d the @ref var_decl to consider. +/// +/// @return a non-nil pointer to the @ref var_decl denoted by @p d if +/// it's an anonymous data member. Otherwise returns a nil pointer. +var_decl_sptr +is_anonymous_data_member(const var_decl_sptr& d) +{ + if (is_anonymous_data_member(d.get())) + return d; + return var_decl_sptr(); +} + +/// Test if a @ref var_decl is an anonymous data member. +/// +/// @param d the @ref var_decl to consider. +/// +/// @return a non-nil pointer to the @ref var_decl denoted by @p d if +/// it's an anonymous data member. Otherwise returns a nil pointer. +const var_decl* +is_anonymous_data_member(const var_decl* d) +{ + if (d && is_anonymous_data_member(*d)) + return d; + return 0; +} + +/// Test if a @ref var_decl is an anonymous data member. +/// +/// @param d the @ref var_decl to consider. +/// +/// @return true iff @p d is an anonymous data member. +bool +is_anonymous_data_member(const var_decl& d) +{ + return (is_data_member(d) + && d.get_name().empty() + && is_class_or_union_type(d.get_type())); +} + +/// Get the @ref class_or_union type of a given anonymous data member. +/// +/// @param d the anonymous data member to consider. +/// +/// @return the @ref class_or_union type of the anonymous data member +/// @p d. +const class_or_union* +anonymous_data_member_to_class_or_union(const var_decl* d) +{ + if ((d = is_anonymous_data_member(d))) + return is_class_or_union_type(d->get_type().get()); + return 0; +} + +/// Test if a data member has annonymous type or not. +/// +/// @param d the data member to consider. +/// +/// @return the anonymous class or union type iff @p turns out to have +/// an anonymous type. Otherwise, returns nil. +const class_or_union_sptr +data_member_has_anonymous_type(const var_decl& d) +{ + if (is_data_member(d)) + if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type())) + if (cou->get_is_anonymous()) + return cou; + + return class_or_union_sptr(); +} + +/// Test if a data member has annonymous type or not. +/// +/// @param d the data member to consider. +/// +/// @return the anonymous class or union type iff @p turns out to have +/// an anonymous type. Otherwise, returns nil. +const class_or_union_sptr +data_member_has_anonymous_type(const var_decl* d) +{ + if (d) + return data_member_has_anonymous_type(*d); + return class_or_union_sptr(); +} + +/// Test if a data member has annonymous type or not. +/// +/// @param d the data member to consider. +/// +/// @return the anonymous class or union type iff @p turns out to have +/// an anonymous type. Otherwise, returns nil. +const class_or_union_sptr +data_member_has_anonymous_type(const var_decl_sptr& d) +{return data_member_has_anonymous_type(d.get());} + +/// Get the @ref class_or_union type of a given anonymous data member. +/// +/// @param d the anonymous data member to consider. +/// +/// @return the @ref class_or_union type of the anonymous data member +/// @p d. +class_or_union_sptr +anonymous_data_member_to_class_or_union(const var_decl_sptr &d) +{ + if (var_decl_sptr v = is_anonymous_data_member(d)) + return is_class_or_union_type(v->get_type()); + return class_or_union_sptr(); +} + /// Set the offset of a data member into its containing class. /// /// @param m the data member to consider. @@ -6022,6 +6187,141 @@ string get_pretty_representation(const method_type_sptr method, bool internal) {return get_pretty_representation(method.get(), internal);} +/// Get the flat representation of an instance of @ref class_or_union +/// type. +/// +/// The flat representation of a given @ref class_or_union type is the +/// actual definition of the type, for instance: +/// +/// struct foo {int a; char b;} +/// +///@param cou the instance of @ref class_or_union to consider. +/// +///@param indent the identation spaces to use in the representation. +/// +///@param one_line if true, then the flat representation stands on one +///line. Otherwise, it stands on multiple lines. +/// +///@return the resulting flat representation. +string +get_class_or_union_flat_representation(const class_or_union& cou, + const string& indent, + bool one_line) +{ + string repr; + string local_indent = " "; + + if (class_decl* clazz = is_class_type(&cou)) + { + repr = indent; + if (clazz->is_struct()) + repr += "struct"; + else + repr += "class"; + } + else if (is_union_type(cou)) + repr = indent + "union"; + else + return ""; + + repr += " "; + + string name = cou.get_qualified_name(); + + if (!cou.get_is_anonymous()) + repr += name; + + repr += "{"; + + if (!one_line) + repr += "\n"; + + string real_indent; + const class_or_union::data_members &dmems = cou.get_data_members(); + for (class_or_union::data_members::const_iterator dm = dmems.begin(); + dm != dmems.end(); + ++dm) + { + if (dm != dmems.begin()) + { + if (one_line) + real_indent = " "; + else + real_indent = "\n" + indent + local_indent; + } + + if (var_decl_sptr v = is_anonymous_data_member(*dm)) + repr += + get_class_or_union_flat_representation + (anonymous_data_member_to_class_or_union(*dm), + real_indent, one_line); + else + { + if (one_line) + { + if (dm != dmems.begin()) + repr += real_indent; + repr += (*dm)->get_pretty_representation(); + } + else + repr += real_indent+ (*dm)->get_pretty_representation(); + } + repr += ";"; + } + + repr += indent + "}"; + + return repr; +} + +/// Get the flat representation of an instance of @ref class_or_union +/// type. +/// +/// The flat representation of a given @ref class_or_union type is the +/// actual definition of the type, for instance: +/// +/// struct foo {int a; char b;} +/// +///@param cou the instance of @ref class_or_union to consider. +/// +///@param indent the identation spaces to use in the representation. +/// +///@param one_line if true, then the flat representation stands on one +///line. Otherwise, it stands on multiple lines. +/// +///@return the resulting flat representation. +string +get_class_or_union_flat_representation(class_or_union* cou, + const string& indent, + bool one_line) +{ + if (cou) + return get_class_or_union_flat_representation(*cou, indent, one_line); + return ""; +} + +/// Get the flat representation of an instance of @ref class_or_union +/// type. +/// +/// The flat representation of a given @ref class_or_union type is the +/// actual definition of the type, for instance: +/// +/// struct foo {int a; char b;} +/// +///@param cou the instance of @ref class_or_union to consider. +/// +///@param indent the identation spaces to use in the representation. +/// +///@param one_line if true, then the flat representation stands on one +///line. Otherwise, it stands on multiple lines. +/// +///@return the resulting flat representation. +string +get_class_or_union_flat_representation(const class_or_union_sptr& cou, + const string& indent, + bool one_line) +{return get_class_or_union_flat_representation(cou.get(), indent, one_line);} + /// By looking at the language of the TU a given ABI artifact belongs /// to, test if the ONE Definition Rule should apply. /// @@ -6207,7 +6507,7 @@ is_at_global_scope(const decl_base_sptr decl) /// @param decl the decl to consider. /// /// @return true iff decl is at class scope. -bool +class_or_union* is_at_class_scope(const decl_base_sptr decl) {return is_at_class_scope(decl.get());} @@ -6216,11 +6516,11 @@ is_at_class_scope(const decl_base_sptr decl) /// @param decl the decl to consider. /// /// @return true iff decl is at class scope. -bool +class_or_union* is_at_class_scope(const decl_base* decl) { if (!decl) - return false; + return 0; return is_at_class_scope(*decl); } @@ -6230,11 +6530,15 @@ is_at_class_scope(const decl_base* decl) /// @param decl the decl to consider. /// /// @return true iff decl is at class scope. -bool +class_or_union* is_at_class_scope(const decl_base& decl) { scope_decl* scope = decl.get_scope(); - return (is_class_type(scope) || is_union_type(scope)); + if (class_or_union* cl = is_class_type(scope)) + return cl; + if (class_or_union* cl = is_union_type(scope)) + return cl; + return 0; } /// Tests whether a given decl is at template scope. @@ -6514,6 +6818,15 @@ is_compatible_with_class_type(const decl_base_sptr& t) /// /// @parm t the type to consider. /// +/// @return true iff @p t is a class_decl. +bool +is_class_type(const type_or_decl_base& t) +{return is_class_type(&t);} + +/// Test whether a type is a class. +/// +/// @parm t the type to consider. +/// /// @return the class_decl if @p t is a class_decl or null otherwise. class_decl* is_class_type(const type_or_decl_base* t) @@ -6552,8 +6865,17 @@ is_class_or_union_type(const shared_ptr& t) /// /// @param t the type to consider. /// +/// @return true iff @p t is a union_decl. +bool +is_union_type(const type_or_decl_base& t) +{return is_union_type(&t);} + +/// Test if a type is a @ref union_decl. +/// +/// @param t the type to consider. +/// /// @return the @ref union_decl is @p is a @ref union_decl, or nil -/// otherwise.n +/// otherwise. union_decl* is_union_type(const type_or_decl_base* t) {return dynamic_cast(const_cast(t));} @@ -13821,6 +14143,46 @@ var_decl::get_hash() const return hash_var(this); } +/// Get the qualified name of a given variable or data member. +/// +/// +/// Note that if the current instance of @ref var_decl is an anonymous +/// data member, then the qualified name is actually the flat +/// representation (the definition) of the type of the anonymous data +/// member. We chose the flat representation because otherwise, the +/// name an *anonymous* data member is empty, by construction, e.g: +/// +/// struct foo { +/// int a; +/// union { +/// char b; +/// char c; +/// }; // <---- this data member is anonymous. +/// int d; +/// } +/// +/// The string returned for the anonymous member here is going to be: +/// +/// "union {char b; char c}" +/// +/// @param internal if true then this is for a purpose to the library, +/// otherwise, it's for being displayed to users. +/// +/// @return the resulting qualified name. +const interned_string& +var_decl::get_qualified_name(bool internal) const +{ + if (is_anonymous_data_member(this) + && decl_base::get_qualified_name().empty()) + { + // Display the anonymous data member in a way that makes sense. + string r = get_pretty_representation(internal); + set_qualified_name(get_environment()->intern(r)); + } + + return decl_base::get_qualified_name(internal); +} + /// Build and return the pretty representation of this variable. /// /// @param internal set to true if the call is intended for an @@ -13836,13 +14198,68 @@ var_decl::get_pretty_representation(bool internal) const if (is_member_decl(this) && get_member_is_static(this)) result = "static "; + + // Detect if the current instance of var_decl is a member of + // an anonymous class or union. + bool member_of_anonymous_class = false; + if (class_or_union* scope = is_at_class_scope(this)) + if (scope->get_is_anonymous()) + member_of_anonymous_class = true; + if (array_type_def_sptr t = is_array_type(get_type())) - result += - get_type_declaration(t->get_element_type())->get_qualified_name(internal) - + " " + get_qualified_name(internal) + t->get_subrange_representation(); + { + string name; + if (member_of_anonymous_class) + name = get_name(); + else + name = get_qualified_name(internal); + + result += + get_type_declaration(t->get_element_type())->get_qualified_name(internal) + + " " + name + t->get_subrange_representation(); + } else - result += get_type_declaration(get_type())->get_qualified_name(internal) - + " " + get_qualified_name(internal); + { + if (is_anonymous_data_member(this)) + { + // Display the anonymous data member in a way that + // makes sense. + result += + get_class_or_union_flat_representation + (is_class_or_union_type(get_type()), + "", /*one_line=*/true); + } + else if (data_member_has_anonymous_type(this)) + { + result += get_class_or_union_flat_representation + (is_class_or_union_type(get_type()), + "", /*one_line=*/true); + result += " "; + if (member_of_anonymous_class) + // It doesn't make sense to name the member of an + // anonymous class or union like: + // "__anonymous__::data_member_name". So let's just use + // its non-qualified name. + result += get_name(); + else + result += get_qualified_name(internal); + } + else + { + result += + get_type_declaration(get_type())->get_qualified_name(internal) + + " "; + + if (member_of_anonymous_class) + // It doesn't make sense to name the member of an + // anonymous class or union like: + // "__anonymous__::data_member_name". So let's just use + // its non-qualified name. + result += get_name(); + else + result += get_qualified_name(internal); + } + } return result; } @@ -16744,8 +17161,11 @@ equals(const class_or_union& l, const class_or_union& r, change_kind* k) if (k) { *k |= SUBTYPE_CHANGE_KIND; - // TODO: continue this by reporting any representation - // change as being local. + // Report any representation change as being local. + string repr1 = (*d0)->get_pretty_representation(); + string repr2 = (*d1)->get_pretty_representation(); + if (repr1 != repr2) + *k |= LOCAL_CHANGE_KIND; break; } else diff --git a/src/abg-leaf-reporter.cc b/src/abg-leaf-reporter.cc index b458591..c675ca3 100644 --- a/src/abg-leaf-reporter.cc +++ b/src/abg-leaf-reporter.cc @@ -634,10 +634,10 @@ leaf_reporter::report(const class_or_union_diff& d, // report changes size_t numchanges = - d.class_or_union_diff::get_priv()->sorted_subtype_changed_dm_.size(); + d.class_or_union_diff::get_priv()->sorted_changed_dm_.size(); size_t num_filtered = d.class_or_union_diff::get_priv()-> - count_filtered_subtype_changed_dm(/*local_only =*/ true); + count_filtered_changed_dm(/*local_only =*/ true); assert(numchanges >= num_filtered); size_t net_numchanges = numchanges - num_filtered; @@ -647,9 +647,9 @@ leaf_reporter::report(const class_or_union_diff& d, report_mem_header(out, subtype_change_kind, "data member", indent); for (var_diff_sptrs_type::const_iterator it = d.class_or_union_diff::get_priv()-> - sorted_subtype_changed_dm_.begin(); + sorted_changed_dm_.begin(); it != d.class_or_union_diff::get_priv()-> - sorted_subtype_changed_dm_.end(); + sorted_changed_dm_.end(); ++it) { if (diff_to_be_reported((*it).get())) @@ -662,10 +662,11 @@ leaf_reporter::report(const class_or_union_diff& d, } } - numchanges = d.class_or_union_diff::get_priv()->sorted_changed_dm_.size(); + numchanges = + d.class_or_union_diff::get_priv()->sorted_subtype_changed_dm_.size(); num_filtered = d.class_or_union_diff::get_priv()-> - count_filtered_changed_dm(/*local_only =*/ true); + count_filtered_subtype_changed_dm(/*local_only =*/ true); assert(numchanges >= num_filtered); net_numchanges = numchanges - num_filtered; @@ -674,8 +675,8 @@ leaf_reporter::report(const class_or_union_diff& d, if (!emitted_data_members_changes) report_mem_header(out, change_kind, "data member", indent); for (var_diff_sptrs_type::const_iterator it = - d.class_or_union_diff::get_priv()->sorted_changed_dm_.begin(); - it != d.class_or_union_diff::get_priv()->sorted_changed_dm_.end(); + d.class_or_union_diff::get_priv()->sorted_subtype_changed_dm_.begin(); + it != d.class_or_union_diff::get_priv()->sorted_subtype_changed_dm_.end(); ++it) { if (diff_to_be_reported((*it).get())) diff --git a/src/abg-reporter-priv.cc b/src/abg-reporter-priv.cc index 0663942..5d1da6c 100644 --- a/src/abg-reporter-priv.cc +++ b/src/abg-reporter-priv.cc @@ -414,39 +414,55 @@ represent(const var_diff_sptr &diff, string name1 = o->get_qualified_name(); string name2 = n->get_qualified_name(); string pretty_representation = o->get_pretty_representation(); + bool is_anonymous_data_member_change = false; - if (diff_sptr d = diff->type_diff()) - { - if (local_only) - { - string tr1 = get_pretty_representation(o->get_type()); - string tr2 = get_pretty_representation(n->get_type()); - if (tr1 != tr2) - { - out << indent << "type of " - << pretty_representation - << " changed from '" << tr1 - << "' to '" << tr2 << "'\n"; - } - } - else - { - if (ctxt->get_reporter()->diff_to_be_reported(d.get())) - { - out << indent - << "type of '" << pretty_representation << "' changed:\n"; - if (d->currently_reporting()) - out << indent << " details are being reported\n"; - else if (d->reported_once()) - out << indent << " details were reported earlier\n"; - else - d->report(out, indent + " "); - begin_with_and = true; - } - } - } - - if (name1 != name2) + if (is_anonymous_data_member(o) && is_anonymous_data_member(n)) + { + is_anonymous_data_member_change = true; + string tr1 = o->get_pretty_representation(); + string tr2 = n->get_pretty_representation(); + if (tr1 != tr2) + { + out << indent << "anonymous data member at offset "; + emit_num_value(get_data_member_offset(o), *ctxt, out); + out << " changed from:\n" + << indent << " " << tr1 << "\n" + << indent << "to:\n" + << indent << " " << tr2 << "\n"; + } + } + else if (diff_sptr d = diff->type_diff()) + { + if (local_only) + { + string tr1 = get_pretty_representation(o->get_type()); + string tr2 = get_pretty_representation(n->get_type()); + if (tr1 != tr2) + { + out << indent << "type of " + << pretty_representation + << " changed from '" << tr1 + << "' to '" << tr2 << "'\n"; + } + } + else + { + if (ctxt->get_reporter()->diff_to_be_reported(d.get())) + { + out << indent + << "type of '" << pretty_representation << "' changed:\n"; + if (d->currently_reporting()) + out << indent << " details are being reported\n"; + else if (d->reported_once()) + out << indent << " details were reported earlier\n"; + else + d->report(out, indent + " "); + begin_with_and = true; + } + } + } + + if (!is_anonymous_data_member_change && name1 != name2) { if (filtering::has_harmless_name_change(o, n) && !(ctxt->get_allowed_category() @@ -494,7 +510,12 @@ represent(const var_diff_sptr &diff, begin_with_and = false; } else if (!emitted) - out << indent << "'" << pretty_representation << "' "; + { + if (is_anonymous_data_member_change) + out << indent; + else + out << indent << "'" << pretty_representation << "' "; + } else out << ", "; @@ -517,7 +538,12 @@ represent(const var_diff_sptr &diff, begin_with_and = false; } else if (!emitted) - out << indent << "'" << pretty_representation << "' "; + { + if (is_anonymous_data_member_change) + out << indent; + else + out << indent << "'" << pretty_representation << "' "; + } else out << ", "; diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 7fe60d4..0834f11 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -651,6 +651,12 @@ test-diff-filter/libtest43-decl-only-def-change-leaf-report-v1.so \ test-diff-filter/test43-decl-only-def-change-leaf-report-0.txt \ test-diff-filter/test43-decl-only-def-change-leaf-report-v0.cc \ test-diff-filter/test43-decl-only-def-change-leaf-report-v1.cc \ +test-diff-filter/libtest44-anonymous-data-member-v0.so \ +test-diff-filter/libtest44-anonymous-data-member-v1.so \ +test-diff-filter/test44-anonymous-data-member-report-0.txt \ +test-diff-filter/test44-anonymous-data-member-report-1.txt \ +test-diff-filter/test44-anonymous-data-member-v0.c \ +test-diff-filter/test44-anonymous-data-member-v1.c \ \ test-diff-suppr/test0-type-suppr-v0.cc \ test-diff-suppr/test0-type-suppr-v1.cc \ diff --git a/tests/data/test-annotate/libtest23.so.abi b/tests/data/test-annotate/libtest23.so.abi index 2ee06b9..811dcff 100644 --- a/tests/data/test-annotate/libtest23.so.abi +++ b/tests/data/test-annotate/libtest23.so.abi @@ -242,11 +242,11 @@ - + - + diff --git a/tests/data/test-annotate/libtest24-drop-fns-2.so.abi b/tests/data/test-annotate/libtest24-drop-fns-2.so.abi index f350547..896bf4b 100644 --- a/tests/data/test-annotate/libtest24-drop-fns-2.so.abi +++ b/tests/data/test-annotate/libtest24-drop-fns-2.so.abi @@ -2562,21 +2562,21 @@ - + - + - + - + diff --git a/tests/data/test-annotate/libtest24-drop-fns.so.abi b/tests/data/test-annotate/libtest24-drop-fns.so.abi index f350547..896bf4b 100644 --- a/tests/data/test-annotate/libtest24-drop-fns.so.abi +++ b/tests/data/test-annotate/libtest24-drop-fns.so.abi @@ -2562,21 +2562,21 @@ - + - + - + - + diff --git a/tests/data/test-annotate/test13-pr18894.so.abi b/tests/data/test-annotate/test13-pr18894.so.abi index 9480011..80d67a7 100644 --- a/tests/data/test-annotate/test13-pr18894.so.abi +++ b/tests/data/test-annotate/test13-pr18894.so.abi @@ -3334,23 +3334,23 @@ - + - + - + - + - + @@ -3602,79 +3602,79 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/tests/data/test-annotate/test14-pr18893.so.abi b/tests/data/test-annotate/test14-pr18893.so.abi index f102abe..e863842 100644 --- a/tests/data/test-annotate/test14-pr18893.so.abi +++ b/tests/data/test-annotate/test14-pr18893.so.abi @@ -1101,7 +1101,7 @@ - + @@ -1114,11 +1114,11 @@ - + - + @@ -1219,7 +1219,7 @@ - + @@ -8585,17 +8585,17 @@ - + - + - + @@ -12492,11 +12492,11 @@ - + - + diff --git a/tests/data/test-annotate/test15-pr18892.so.abi b/tests/data/test-annotate/test15-pr18892.so.abi index dfbdd62..88c4dff 100644 --- a/tests/data/test-annotate/test15-pr18892.so.abi +++ b/tests/data/test-annotate/test15-pr18892.so.abi @@ -16731,7 +16731,7 @@ - + @@ -26260,17 +26260,17 @@ - + - + - + @@ -32404,35 +32404,35 @@ - + - + - + - + - + - + - + - + @@ -35361,35 +35361,35 @@ - + - + - + - + - + - + - + - + @@ -36814,17 +36814,17 @@ - + - + - + @@ -37350,21 +37350,21 @@ - + - + - + - + @@ -37549,11 +37549,11 @@ - + - + @@ -40596,7 +40596,7 @@ - + @@ -40683,69 +40683,69 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -40775,11 +40775,11 @@ - + - + @@ -40788,26 +40788,26 @@ - + - + - + - + - + @@ -40823,11 +40823,11 @@ - + - + @@ -40843,7 +40843,7 @@ - + @@ -40891,47 +40891,47 @@ - + - + - + - + - + - + - + - + diff --git a/tests/data/test-annotate/test17-pr19027.so.abi b/tests/data/test-annotate/test17-pr19027.so.abi index b064e79..9f032ed 100644 --- a/tests/data/test-annotate/test17-pr19027.so.abi +++ b/tests/data/test-annotate/test17-pr19027.so.abi @@ -1916,35 +1916,35 @@ - + - + - + - + - + - + - + - + @@ -1953,35 +1953,35 @@ - + - + - + - + - + - + - + - + @@ -1990,35 +1990,35 @@ - + - + - + - + - + - + - + - + @@ -2036,15 +2036,15 @@ - + - + - + @@ -3518,47 +3518,47 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -3567,47 +3567,47 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -3616,47 +3616,47 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -3670,15 +3670,15 @@ - + - + - + @@ -8740,27 +8740,27 @@ - + - + - + - + - + @@ -8864,15 +8864,15 @@ - + - + - + @@ -8902,7 +8902,7 @@ - + @@ -10536,11 +10536,11 @@ - + - + @@ -10550,7 +10550,7 @@ - + @@ -10615,21 +10615,21 @@ - + - + - + - + @@ -15118,51 +15118,51 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -15525,17 +15525,17 @@ - + - + - + @@ -21991,17 +21991,17 @@ - + - + - + @@ -22409,17 +22409,17 @@ - + - + - + @@ -23028,17 +23028,17 @@ - + - + - + @@ -23290,21 +23290,21 @@ - + - + - + - + @@ -24485,25 +24485,25 @@ - + - + - + - + - + @@ -24619,25 +24619,25 @@ - + - + - + - + - + @@ -24688,25 +24688,25 @@ - + - + - + - + - + @@ -24975,21 +24975,21 @@ - + - + - + - + @@ -25062,41 +25062,41 @@ - + - + - + - + - + - + - + - + - + @@ -25160,25 +25160,25 @@ - + - + - + - + - + @@ -25256,17 +25256,17 @@ - + - + - + @@ -25382,21 +25382,21 @@ - + - + - + - + @@ -25640,17 +25640,17 @@ - + - + - + @@ -26079,55 +26079,55 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -30453,17 +30453,17 @@ - + - + - + @@ -30733,17 +30733,17 @@ - + - + - + @@ -30858,17 +30858,17 @@ - + - + - + @@ -30924,17 +30924,17 @@ - + - + - + @@ -31067,21 +31067,21 @@ - + - + - + - + @@ -31364,21 +31364,21 @@ - + - + - + - + @@ -32117,7 +32117,7 @@ - + diff --git a/tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi b/tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi index bf57848..817112b 100644 --- a/tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi +++ b/tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi @@ -4778,11 +4778,11 @@ - + - + @@ -4792,7 +4792,7 @@ - + diff --git a/tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi b/tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi index 50d4736..6695b5f 100644 --- a/tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi +++ b/tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi @@ -6071,11 +6071,11 @@ - + - + @@ -6085,7 +6085,7 @@ - + @@ -7099,19 +7099,19 @@ - + - + - + - + @@ -7121,7 +7121,7 @@ - + @@ -33627,11 +33627,11 @@ - + - + @@ -33640,15 +33640,15 @@ - + - + - + @@ -33657,15 +33657,15 @@ - + - + - + @@ -33674,23 +33674,23 @@ - + - + - + - + - + @@ -33699,7 +33699,7 @@ - + @@ -33708,41 +33708,41 @@ - + - + - + - + - + - + - + - + - + @@ -33760,7 +33760,7 @@ - + diff --git a/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi b/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi index 2aad69f..3b5432c 100644 --- a/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi +++ b/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi @@ -7003,11 +7003,11 @@ - + - + @@ -7017,7 +7017,7 @@ - + diff --git a/tests/data/test-annotate/test21-pr19092.so.abi b/tests/data/test-annotate/test21-pr19092.so.abi index 01edfd3..7026d1c 100644 --- a/tests/data/test-annotate/test21-pr19092.so.abi +++ b/tests/data/test-annotate/test21-pr19092.so.abi @@ -2084,31 +2084,31 @@ - + - + - + - + - + - + - + @@ -2157,11 +2157,11 @@ - + - + @@ -2183,23 +2183,23 @@ - + - + - + - + - + @@ -4620,19 +4620,19 @@ - + - + - + - + @@ -5343,19 +5343,19 @@ - + - + - + - + @@ -5585,7 +5585,7 @@ - + @@ -5969,11 +5969,11 @@ - + - + @@ -5982,21 +5982,21 @@ - + - + - + - + @@ -6005,11 +6005,11 @@ - + - + @@ -6023,7 +6023,7 @@ - + @@ -6031,7 +6031,7 @@ - + @@ -6059,15 +6059,15 @@ - + - + - + @@ -6373,23 +6373,23 @@ - + - + - + - + - + @@ -6579,7 +6579,7 @@ - + @@ -6676,26 +6676,26 @@ - + - + - + - + - + @@ -9423,7 +9423,7 @@ - + @@ -9505,69 +9505,69 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -9597,11 +9597,11 @@ - + - + @@ -9610,15 +9610,15 @@ - + - + - + @@ -9627,11 +9627,11 @@ - + - + @@ -9646,11 +9646,11 @@ - + - + @@ -9665,7 +9665,7 @@ - + @@ -9713,47 +9713,47 @@ - + - + - + - + - + - + - + - + @@ -10877,11 +10877,11 @@ - + - + @@ -10892,37 +10892,37 @@ - + - + - + - + - + - + - + diff --git a/tests/data/test-diff-dwarf/test43-PR22913-report-0.txt b/tests/data/test-diff-dwarf/test43-PR22913-report-0.txt index d48ef3d..d9665b6 100644 --- a/tests/data/test-diff-dwarf/test43-PR22913-report-0.txt +++ b/tests/data/test-diff-dwarf/test43-PR22913-report-0.txt @@ -9,7 +9,7 @@ Variables changes summary: 0 Removed, 0 Changed, 0 Added variable in pointed to type 'struct __anonymous_struct__': type size changed from 16 to 8 (in bits) 1 data member deletion: - 'char __anonymous_struct__::m2', at offset 8 (in bits) + 'char m2', at offset 8 (in bits) diff --git a/tests/data/test-diff-filter/libtest44-anonymous-data-member-v0.so b/tests/data/test-diff-filter/libtest44-anonymous-data-member-v0.so new file mode 100755 index 0000000000000000000000000000000000000000..a77687d01ff66daae5de67edc823e38d187892ab GIT binary patch literal 9208 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 i>kHp|WE-tlZ0UZ*9SMs|#2uJ7{b;} + +int +bar(struct S2* p) +{return p->b;} diff --git a/tests/data/test-diff-filter/test44-anonymous-data-member-v1.c b/tests/data/test-diff-filter/test44-anonymous-data-member-v1.c new file mode 100644 index 0000000..6f4bb77 --- /dev/null +++ b/tests/data/test-diff-filter/test44-anonymous-data-member-v1.c @@ -0,0 +1,27 @@ +struct S1 { + int a; + union { + int b; + float c; + char e; + }; + int d; +}; + +struct S2 { + int a; + struct { + int b; + float c; + char e; + }; + int d; +}; + +int +foo(struct S1* p) +{return p->b;} + +int +bar(struct S2* p) +{return p->b;} diff --git a/tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt b/tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt index 104f48b..f479a23 100644 --- a/tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt +++ b/tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt @@ -10,13 +10,13 @@ underlying type 'union __anonymous_union__' at dvd.h:122:1 changed: type size hasn't changed 2 data member changes: - type of 'cdio_dvd_disckey_t __anonymous_union__::disckey' changed: + type of 'cdio_dvd_disckey_t disckey' changed: underlying type 'struct cdio_dvd_disckey' at dvd.h:100:1 changed: type size hasn't changed 1 data member change: 'unsigned int cdio_dvd_disckey::agid' offset changed from 30 to 22 (in bits) (by -8 bits) - type of 'cdio_dvd_physical_t __anonymous_union__::physical' changed: + type of 'cdio_dvd_physical_t physical' changed: underlying type 'struct cdio_dvd_physical' at dvd.h:86:1 changed: type size hasn't changed 1 data member change: diff --git a/tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt b/tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt index fc81b39..40c8d05 100644 --- a/tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt +++ b/tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt @@ -105,7 +105,7 @@ underlying type 'struct __anonymous_struct__' at red_channel.h:195:1 changed: type size hasn't changed 1 data member changes (9 filtered): - type of 'channel_alloc_msg_recv_buf_proc __anonymous_struct__::alloc_recv_buf' changed: + type of 'channel_alloc_msg_recv_buf_proc alloc_recv_buf' changed: underlying type 'uint8_t* (RedChannelClient*, typedef uint16_t, typedef uint32_t)*' changed: in pointed to type 'function type uint8_t* (RedChannelClient*, typedef uint16_t, typedef uint32_t)': parameter 1 of type 'RedChannelClient*' has sub-type changes: diff --git a/tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt b/tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt index 94884f9..bf92542 100644 --- a/tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt +++ b/tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt @@ -1,6 +1,6 @@ ================ changes of 'libspice-server.so.1.8.0'=============== -Leaf changes summary: 14 artifacts changed (7 filtered out) - Changed leaf types summary: 3 (7 filtered out) leaf types changed +Leaf changes summary: 14 artifacts changed (8 filtered out) + Changed leaf types summary: 3 (8 filtered out) leaf types changed Removed/Changed/Added functions summary: 1 Removed, 2 Changed, 8 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable diff --git a/tests/test-diff-filter.cc b/tests/test-diff-filter.cc index ddbe538..6e99bb1 100644 --- a/tests/test-diff-filter.cc +++ b/tests/test-diff-filter.cc @@ -500,6 +500,20 @@ InOutSpec in_out_specs[] = "data/test-diff-filter/test43-decl-only-def-change-leaf-report-0.txt", "output/test-diff-filter/test43-decl-only-def-change-leaf-report-0.txt", }, + { + "data/test-diff-filter/libtest44-anonymous-data-member-v0.so", + "data/test-diff-filter/libtest44-anonymous-data-member-v1.so", + "--no-default-suppression", + "data/test-diff-filter/test44-anonymous-data-member-report-0.txt", + "output/test-diff-filter/test44-anonymous-data-member-report-0.txt", + }, + { + "data/test-diff-filter/libtest44-anonymous-data-member-v0.so", + "data/test-diff-filter/libtest44-anonymous-data-member-v1.so", + "--no-default-suppression --leaf-changes-only", + "data/test-diff-filter/test44-anonymous-data-member-report-1.txt", + "output/test-diff-filter/test44-anonymous-data-member-report-1.txt", + }, // This should be the last entry {NULL, NULL, NULL, NULL, NULL} }; -- 2.7.4