@@ -89,6 +89,9 @@ has_anonymous_data_member_change(const diff *d);
bool
has_anonymous_data_member_change(const diff_sptr &d);
+bool
+has_data_member_replaced_by_anon_dm(const diff* diff);
+
struct filter_base;
/// Convenience typedef for a shared pointer to filter_base
typedef shared_ptr<filter_base> filter_base_sptr;
@@ -257,6 +257,15 @@ typedef unordered_map<string, var_decl*> string_var_ptr_map;
/// the changed variable.
typedef std::pair<var_decl*, var_decl*> changed_var_ptr;
+/// Convenience typedef for a pair of @ref var_decl_sptr representing
+/// a @ref var_decl change. The first member of the pair represents
+/// the initial variable and the second member represents the changed
+/// variable.
+typedef std::pair<var_decl_sptr, var_decl_sptr> changed_var_sptr;
+
+/// Convenience typedef for a vector of @changed_var_sptr.gg381
+typedef vector<changed_var_sptr> changed_var_sptrs_type;
+
/// Convenience typedef for a map whose key is a string and whose
/// value is an @ref elf_symbol_sptr.
typedef unordered_map<string, elf_symbol_sptr> string_elf_symbol_map;
@@ -375,61 +384,69 @@ enum diff_category
/// alias change that is harmless.
HARMLESS_SYMBOL_ALIAS_CHANGE_CATEORY = 1 << 6,
+ /// This means that a diff node in the sub-tree carries a harmless
+ /// union change.
HARMLESS_UNION_CHANGE_CATEGORY = 1 << 7,
+ /// This means that a diff node in the sub-tree carries a harmless
+ /// data member change. An example of harmless data member change
+ /// is an anonymous data member that replaces a given data member
+ /// without locally changing the layout.
+ HARMLESS_DATA_MEMBER_CHANGE_CATEGORY = 1 << 8,
+
/// This means that a diff node was marked as suppressed by a
/// user-provided suppression specification.
- SUPPRESSED_CATEGORY = 1 << 8,
+ SUPPRESSED_CATEGORY = 1 << 9,
/// This means that a diff node was warked as being for a private
/// type. That is, the diff node is meant to be suppressed by a
/// suppression specification that was auto-generated to filter out
/// changes to private types.
- PRIVATE_TYPE_CATEGORY = 1 << 9,
+ PRIVATE_TYPE_CATEGORY = 1 << 10,
/// This means the diff node (or at least one of its descendant
/// nodes) carries a change that modifies the size of a type or an
/// offset of a type member. Removal or changes of enumerators in a
/// enum fall in this category too.
- SIZE_OR_OFFSET_CHANGE_CATEGORY = 1 << 10,
+ SIZE_OR_OFFSET_CHANGE_CATEGORY = 1 << 11,
/// This means that a diff node in the sub-tree carries an
/// incompatible change to a vtable.
- VIRTUAL_MEMBER_CHANGE_CATEGORY = 1 << 11,
+ VIRTUAL_MEMBER_CHANGE_CATEGORY = 1 << 12,
/// A diff node in this category is redundant. That means it's
/// present as a child of a other nodes in the diff tree.
- REDUNDANT_CATEGORY = 1 << 12,
+ REDUNDANT_CATEGORY = 1 << 13,
/// This means that a diff node in the sub-tree carries a class type
/// that was declaration-only and that is now defined, or vice
/// versa.
- CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY = 1 << 13,
+ CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY = 1 << 14,
/// A diff node in this category is a function parameter type which
/// top cv-qualifiers change.
- FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY = 1 << 14,
+ FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY = 1 << 15,
/// A diff node in this category has a function parameter type with a
/// cv-qualifiers change.
- FN_PARM_TYPE_CV_CHANGE_CATEGORY = 1 << 15,
+ FN_PARM_TYPE_CV_CHANGE_CATEGORY = 1 << 16,
/// A diff node in this category is a function return type with a
/// cv-qualifier change.
- FN_RETURN_TYPE_CV_CHANGE_CATEGORY = 1 << 16,
+ FN_RETURN_TYPE_CV_CHANGE_CATEGORY = 1 << 17,
/// A diff node in this category is for a variable which type holds
/// a cv-qualifier change.
- VAR_TYPE_CV_CHANGE_CATEGORY = 1 << 17,
+ VAR_TYPE_CV_CHANGE_CATEGORY = 1 << 18,
/// A diff node in this category carries a change from void pointer
/// to non-void pointer.
- VOID_PTR_TO_PTR_CHANGE_CATEGORY = 1 << 18,
+ VOID_PTR_TO_PTR_CHANGE_CATEGORY = 1 << 19,
/// A diff node in this category carries a change in the size of the
/// array type of a global variable, but the ELF size of the
/// variable didn't change.
- BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY = 1 << 19,
+ BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY = 1 << 20,
/// A special enumerator that is the logical 'or' all the
/// enumerators above.
///
@@ -444,6 +461,7 @@ enum diff_category
| HARMLESS_ENUM_CHANGE_CATEGORY
| HARMLESS_SYMBOL_ALIAS_CHANGE_CATEORY
| HARMLESS_UNION_CHANGE_CATEGORY
+ | HARMLESS_DATA_MEMBER_CHANGE_CATEGORY
| SUPPRESSED_CATEGORY
| PRIVATE_TYPE_CATEGORY
| SIZE_OR_OFFSET_CHANGE_CATEGORY
@@ -1610,6 +1628,12 @@ public:
size_t
count_filtered_subtype_changed_data_members(bool local_only = false) const;
+ const string_decl_base_sptr_map&
+ data_members_replaced_by_adms() const;
+
+ const changed_var_sptrs_type&
+ ordered_data_members_replaced_by_adms() const;
+
const edit_script&
member_fn_tmpls_changes() const;
@@ -223,6 +223,9 @@ class var_decl;
/// Convenience typedef for a shared pointer on a @ref var_decl
typedef shared_ptr<var_decl> var_decl_sptr;
+/// Convenience typedef for a weak pointer on a @ref var_decl
+typedef weak_ptr<var_decl> var_decl_wptr;
+
typedef unordered_map<interned_string,
var_decl*,
hash_interned_string> istring_var_decl_ptr_map_type;
@@ -614,6 +617,9 @@ is_data_member(const decl_base *);
var_decl*
is_data_member(const decl_base *);
+const var_decl_sptr
+get_next_data_member(const class_or_union_sptr&, const var_decl_sptr&);
+
bool
is_anonymous_data_member(const decl_base&);
@@ -638,7 +644,14 @@ is_anonymous_data_member(const var_decl*);
bool
is_anonymous_data_member(const var_decl&);
-const class_or_union*
+const var_decl_sptr
+get_first_non_anonymous_data_member(const var_decl_sptr);
+
+var_decl_sptr
+find_data_member_from_anonymous_data_member(const var_decl_sptr&,
+ const string&);
+
+class_or_union*
anonymous_data_member_to_class_or_union(const var_decl*);
class_or_union_sptr
@@ -678,6 +691,9 @@ uint64_t
get_data_member_offset(const decl_base_sptr);
uint64_t
+get_absolute_data_member_offset(const var_decl&);
+
+uint64_t
get_var_size_in_bits(const var_decl_sptr&);
void
@@ -1601,8 +1601,8 @@ public:
friend void
set_member_function_is_virtual(function_decl&, bool);
+ friend class class_or_union;
friend class class_decl;
-
friend class scope_decl;
};// end class decl_base
@@ -2637,61 +2637,45 @@ public:
class dm_context_rel : public context_rel
{
protected:
- bool is_laid_out_;
- size_t offset_in_bits_;
+ struct priv;
+ typedef shared_ptr<priv> priv_sptr;
+
+ priv_sptr priv_;
public:
- dm_context_rel()
- : context_rel(),
- is_laid_out_(!is_static_),
- offset_in_bits_(0)
- {}
+ dm_context_rel();
dm_context_rel(scope_decl* s,
bool is_laid_out,
size_t offset_in_bits,
access_specifier a,
- bool is_static)
- : context_rel(s, a, is_static),
- is_laid_out_(is_laid_out),
- offset_in_bits_(offset_in_bits)
- {}
+ bool is_static);
- dm_context_rel(scope_decl* s)
- : context_rel(s),
- is_laid_out_(!is_static_),
- offset_in_bits_(0)
- {}
+ dm_context_rel(scope_decl* s);
bool
- get_is_laid_out() const
- {return is_laid_out_;}
+ get_is_laid_out() const;
void
- set_is_laid_out(bool f)
- {is_laid_out_ = f;}
+ set_is_laid_out(bool f);
size_t
- get_offset_in_bits() const
- {return offset_in_bits_;}
+ get_offset_in_bits() const;
void
- set_offset_in_bits(size_t o)
- {offset_in_bits_ = o;}
+ set_offset_in_bits(size_t o);
- bool
- operator==(const dm_context_rel& o) const
- {
- if (!context_rel::operator==(o))
- return false;
+ const var_decl*
+ get_anonymous_data_member() const;
- return (is_laid_out_ == o.is_laid_out_
- && offset_in_bits_ == o.offset_in_bits_);
- }
+ void
+ set_anonymous_data_member(var_decl *);
bool
- operator!=(const dm_context_rel& o) const
- {return !operator==(o);}
+ operator==(const dm_context_rel& o) const;
+
+ bool
+ operator!=(const dm_context_rel& o) const;
virtual ~dm_context_rel();
};// end class class_decl::dm_context_rel
@@ -2783,6 +2767,12 @@ public:
friend uint64_t
get_data_member_offset(const var_decl& m);
+ friend uint64_t
+ get_absolute_data_member_offset(const var_decl& m);
+
+ friend uint64_t
+ get_absolute_data_member_offset(const var_decl_sptr& m);
+
friend void
set_data_member_is_laid_out(var_decl_sptr m, bool l);
@@ -3731,6 +3721,9 @@ protected:
virtual void
remove_member_decl(decl_base_sptr);
+ void
+ maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm);
+
public:
/// Hasher.
struct hash;
@@ -533,6 +533,25 @@ non_static_data_member_added_or_removed(const diff* diff)
(dynamic_cast<const class_diff*>(diff));
}
+/// Test if a @ref class_or_union_diff has a data member replaced by
+/// an anonymous data member in a harmless way. That means, the new
+/// anonymous data member somehow contains the replaced data member
+/// and it doesn't break the layout of the containing class.
+///
+/// @param diff the diff node to consider.
+///
+/// @return true iff the @ref class_or_union_diff has a data member
+/// harmlessly replaced by an anonymous data member.
+bool
+has_data_member_replaced_by_anon_dm(const diff* diff)
+{
+ const class_or_union_diff *c = is_class_or_union_diff(diff);
+
+ if (!c)
+ return false;
+ return !c->data_members_replaced_by_adms().empty();
+}
+
/// Test if a class_diff node has static members added or removed.
///
/// @param diff the diff node to consider.
@@ -1521,6 +1540,9 @@ categorize_harmless_diff_node(diff *d, bool pre)
|| static_data_member_type_size_changed(f, s))
category |= STATIC_DATA_MEMBER_CHANGE_CATEGORY;
+ if (has_data_member_replaced_by_anon_dm(d))
+ category |= HARMLESS_DATA_MEMBER_CHANGE_CATEGORY;
+
if ((has_enumerator_insertion(d)
&& !has_harmful_enum_change(d))
|| has_harmless_enum_to_int_change(d))
@@ -502,6 +502,13 @@ struct class_or_union_diff::priv
// member bar at offset N.
unsigned_var_diff_sptr_map changed_dm_;
var_diff_sptrs_type sorted_changed_dm_;
+
+ // This is a data structure to represent data members that have been
+ // replaced by anonymous data members. It's a map that associates
+ // the name of the data member to the anonymous data member that
+ // replaced it.
+ string_decl_base_sptr_map dms_replaced_by_adms_;
+ mutable changed_var_sptrs_type dms_replaced_by_adms_ordered_;
string_member_function_sptr_map deleted_member_functions_;
string_member_function_sptr_map inserted_member_functions_;
string_function_decl_diff_sptr_map changed_member_functions_;
@@ -549,18 +556,18 @@ struct class_or_union_diff::priv
/// offset.
struct data_member_comp
{
- /// @param f the first data member to take into account.
+
+ /// Compare two data members.
///
- /// @param s the second data member to take into account.
+ /// First look at their offset and then their name.
///
- /// @return true iff f is before s.
+ /// @parm first_dm the first data member to consider.
+ ///
+ /// @param second_dm the second data member to consider.
bool
- operator()(const decl_base_sptr& f,
- const decl_base_sptr& s) const
+ compare_data_members(const var_decl_sptr& first_dm,
+ const var_decl_sptr& second_dm) const
{
- var_decl_sptr first_dm = is_data_member(f);
- var_decl_sptr second_dm = is_data_member(s);
-
ABG_ASSERT(first_dm);
ABG_ASSERT(second_dm);
@@ -578,6 +585,40 @@ struct data_member_comp
// sort them lexicographically.
return first_dm_name < second_dm_name;
}
+
+ /// Compare two data members.
+ ///
+ /// First look at their offset and then their name.
+ ///
+ /// @parm first_dm the first data member to consider.
+ ///
+ /// @param second_dm the second data member to consider.
+ bool
+ operator()(const decl_base_sptr& f,
+ const decl_base_sptr& s) const
+ {
+ var_decl_sptr first_dm = is_data_member(f);
+ var_decl_sptr second_dm = is_data_member(s);
+
+ return compare_data_members(first_dm, second_dm);
+ }
+
+ /// Compare two data members.
+ ///
+ /// First look at their offset and then their name.
+ ///
+ /// @parm first_dm the first data member to consider.
+ ///
+ /// @param second_dm the second data member to consider.
+ bool
+ operator()(const changed_var_sptr& f,
+ const changed_var_sptr& s) const
+ {
+ var_decl_sptr first_dm = is_data_member(is_decl(f.first));
+ var_decl_sptr second_dm = is_data_member(is_decl(s.first));
+
+ return compare_data_members(first_dm, second_dm);
+ }
};//end struct data_member_comp
/// The type of the private data (pimpl sub-object) of the @ref
@@ -1347,6 +1388,9 @@ sort_data_members(const string_decl_base_sptr_map &data_members,
vector<decl_base_sptr>& sorted);
void
+sort_changed_data_members(changed_var_sptrs_type& input);
+
+void
sort_string_function_ptr_map(const string_function_ptr_map& map,
vector<function_decl*>& sorted);
@@ -171,8 +171,18 @@ sort_data_members(const string_decl_base_sptr_map &data_members,
std::sort(sorted.begin(), sorted.end(), comp);
}
-/// Sort a an instance of @ref string_function_ptr_map map and stuff
-/// a resulting sorted vector of pointers to function_decl.
+/// Sort (in place) a vector of changed data members.
+///
+/// @param to_sort the vector to sort.
+void
+sort_changed_data_members(changed_var_sptrs_type& to_sort)
+{
+ data_member_comp comp;
+ std::sort(to_sort.begin(), to_sort.end(), comp);
+}
+
+/// Sort an instance of @ref string_function_ptr_map map and stuff a
+/// resulting sorted vector of pointers to function_decl.
///
/// @param map the map to sort.
///
@@ -2946,6 +2956,7 @@ get_default_harmless_categories_bitmap()
| abigail::comparison::HARMLESS_ENUM_CHANGE_CATEGORY
| abigail::comparison::HARMLESS_SYMBOL_ALIAS_CHANGE_CATEORY
| abigail::comparison::HARMLESS_UNION_CHANGE_CATEGORY
+ | abigail::comparison::HARMLESS_DATA_MEMBER_CHANGE_CATEGORY
| abigail::comparison::CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY
| abigail::comparison::FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY
| abigail::comparison::FN_PARM_TYPE_CV_CHANGE_CATEGORY
@@ -3033,6 +3044,14 @@ operator<<(ostream& o, diff_category c)
emitted_a_category |= true;
}
+ if (c & HARMLESS_DATA_MEMBER_CHANGE_CATEGORY)
+ {
+ if (emitted_a_category)
+ o << "|";
+ o << "HARMLESS_DATA_MEMBER_CHANGE_CATEGORY";
+ emitted_a_category |= true;
+ }
+
if (c & HARMLESS_SYMBOL_ALIAS_CHANGE_CATEORY)
{
if (emitted_a_category)
@@ -4688,21 +4707,179 @@ class_or_union_diff::ensure_lookup_tables_populated(void) const
var_decl_sptr added_dm = is_var_decl(d);
string name = added_dm->get_anon_dm_reliable_name();
ABG_ASSERT(priv_->inserted_data_members_.find(name)
- == priv_->inserted_data_members_.end());
- string_decl_base_sptr_map::const_iterator j =
- priv_->deleted_data_members_.find(name);
- if (j != priv_->deleted_data_members_.end())
+ == priv_->inserted_data_members_.end());
+
+ bool ignore_added_anonymous_data_member = false;
+ if (is_anonymous_data_member(added_dm))
{
- if (*j->second != *d)
+ //
+ // Handle insertion of anonymous data member to
+ // replace existing data members.
+ //
+ // For instance consider this:
+ // struct S
+ // {
+ // int a;
+ // int b;
+ // int c;
+ // };// end struct S
+ //
+ // Where the data members 'a' and 'b' are replaced
+ // by an anonymous data member without changing the
+ // effective bit layout of the structure:
+ //
+ // struct S
+ // {
+ // struct
+ // {
+ // union
+ // {
+ // int a;
+ // char a_1;
+ // };
+ // union
+ // {
+ // int b;
+ // char b_1;
+ // };
+ // };
+ // int c;
+ // }; // end struct S
+ //
+ var_decl_sptr replaced_dm, replacing_dm;
+ bool added_anon_dm_changes_dm = false;
+ // The vector of data members replaced by anonymous
+ // data members.
+ vector<var_decl_sptr> dms_replaced_by_anon_dm;
+
+ //
+ // Let's start collecting the set of data members
+ // which have been replaced by anonymous types in a
+ // harmless way. These are going to be collected into
+ // dms_replaced_by_anon_dm and, ultimately, into
+ // priv_->dms_replaced_by_adms_
+ //
+ for (string_decl_base_sptr_map::const_iterator it =
+ priv_->deleted_data_members_.begin();
+ it != priv_->deleted_data_members_.end();
+ ++it)
{
- var_decl_sptr old_dm = is_var_decl(j->second);
- priv_->subtype_changed_dm_[name]=
- compute_diff(old_dm, added_dm, context());
+ // We don't support this pattern for anonymous
+ // data members themselves being replaced. If
+ // that occurs then we'll just report it verbatim.
+ if (is_anonymous_data_member(it->second))
+ continue;
+
+ string deleted_dm_name = it->second->get_name();
+ if ((replacing_dm =
+ find_data_member_from_anonymous_data_member(added_dm,
+ deleted_dm_name)))
+ {
+ // So it looks like replacing_dm might have
+ // replaced the data member which name is
+ // 'deleted_dm_name'. Let's look deeper to be
+ // sure.
+ //
+ // Note that replacing_dm is part (member) of
+ // an anonymous data member that might replace
+ // replaced_dm.
+
+ // So let's get that replaced data member.
+ replaced_dm = is_var_decl(it->second);
+ size_t replaced_dm_offset =
+ get_data_member_offset(replaced_dm),
+ replacing_dm_offset =
+ get_absolute_data_member_offset(replacing_dm);
+
+ if (replaced_dm_offset != replacing_dm_offset)
+ {
+ // So the replacing data member and the
+ // replaced data member don't have the
+ // same offset. This is not the pattern we
+ // are looking for. Rather, it looks like
+ // the anonymous data member has *changed*
+ // the data member.
+ added_anon_dm_changes_dm = true;
+ break;
+ }
+
+ if (replaced_dm->get_type()->get_size_in_bits()
+ == replaced_dm->get_type()->get_size_in_bits())
+ dms_replaced_by_anon_dm.push_back(replaced_dm);
+ else
+ {
+ added_anon_dm_changes_dm = true;
+ break;
+ }
+ }
+ }
+
+ // Now walk dms_replaced_by_anon_dm to fill up
+ // priv_->dms_replaced_by_adms_ with the set of data
+ // members replaced by anonymous data members.
+ if (!added_anon_dm_changes_dm
+ && !dms_replaced_by_anon_dm.empty())
+ {
+ // See if the added data member isn't too big.
+ type_base_sptr added_dm_type = added_dm->get_type();
+ ABG_ASSERT(added_dm_type);
+ var_decl_sptr new_next_dm =
+ get_next_data_member(second_class_or_union(),
+ added_dm);
+ var_decl_sptr old_next_dm =
+ first_class_or_union()->find_data_member(new_next_dm);
+
+ if (!old_next_dm
+ || (old_next_dm
+ && (get_absolute_data_member_offset(old_next_dm)
+ == get_absolute_data_member_offset(new_next_dm))))
+ {
+ // None of the data members that are replaced
+ // by the added union should be considered as
+ // having been deleted.
+ ignore_added_anonymous_data_member = true;
+ for (vector<var_decl_sptr>::const_iterator i =
+ dms_replaced_by_anon_dm.begin();
+ i != dms_replaced_by_anon_dm.end();
+ ++i)
+ {
+ string n = (*i)->get_name();
+ priv_->dms_replaced_by_adms_[n] =
+ added_dm;
+ priv_->deleted_data_members_.erase(n);
+ }
+ }
}
- priv_->deleted_data_members_.erase(j);
}
- else
- priv_->inserted_data_members_[name] = d;
+
+ if (!ignore_added_anonymous_data_member)
+ {
+ // Detect changed data members.
+ //
+ // A changed data member (that we shall name D) is a data
+ // member that satisfies the conditions below:
+ //
+ // 1/ It must have been added.
+ //
+ // 2/ It must have been deleted as well.
+ //
+ // 3/ It there must be a non-empty difference between the
+ // deleted D and the added D.
+ string_decl_base_sptr_map::const_iterator j =
+ priv_->deleted_data_members_.find(name);
+ if (j != priv_->deleted_data_members_.end())
+ {
+ if (*j->second != *d)
+ {
+ var_decl_sptr old_dm = is_var_decl(j->second);
+ priv_->subtype_changed_dm_[name]=
+ compute_diff(old_dm, added_dm, context());
+ }
+ priv_->deleted_data_members_.erase(j);
+ }
+ else
+ priv_->inserted_data_members_[name] = d;
+ }
}
}
@@ -4987,6 +5164,47 @@ size_t
class_or_union_diff::count_filtered_subtype_changed_data_members(bool local) const
{return get_priv()->count_filtered_subtype_changed_dm(local);}
+/// Get the map of data members that got replaced by anonymous data
+/// members.
+///
+/// The key of a map entry is the name of the replaced data member and
+/// the value is the anonymous data member that replaces it.
+///
+/// @return the map of data members replaced by anonymous data
+/// members.
+const string_decl_base_sptr_map&
+class_or_union_diff::data_members_replaced_by_adms() const
+{return get_priv()->dms_replaced_by_adms_;}
+
+/// Get an ordered vector of of data members that got replaced by
+/// anonymous data members.
+///
+/// This returns a vector of pair of two data members: the one that
+/// was replaced, and the anonymous data member that replaced it.
+///
+/// @return the sorted vector data members replaced by anonymous data members.
+const changed_var_sptrs_type&
+class_or_union_diff::ordered_data_members_replaced_by_adms() const
+{
+ if (priv_->dms_replaced_by_adms_ordered_.empty())
+ {
+ for (string_decl_base_sptr_map::const_iterator it =
+ priv_->dms_replaced_by_adms_.begin();
+ it != priv_->dms_replaced_by_adms_.end();
+ ++it)
+ {
+ const var_decl_sptr dm =
+ first_class_or_union()->find_data_member(it->first);
+ ABG_ASSERT(dm);
+ changed_var_sptr changed_dm(dm, is_data_member(it->second));
+ priv_->dms_replaced_by_adms_ordered_.push_back(changed_dm);
+ }
+ sort_changed_data_members(priv_->dms_replaced_by_adms_ordered_);
+ }
+
+ return priv_->dms_replaced_by_adms_ordered_;
+}
+
/// @return the edit script of the member function templates of the two
/// @ref class_or_union.
const edit_script&
@@ -11424,8 +11642,8 @@ void
propagate_categories(corpus_diff_sptr diff_tree)
{propagate_categories(diff_tree.get());}
-/// A tree node visitor that knows how to categorizes a given in the
-/// SUPPRESSED_CATEGORY category and how to propagate that
+/// A tree node visitor that knows how to categorizes a given diff
+/// node in the SUPPRESSED_CATEGORY category and how to propagate that
/// categorization.
struct suppression_categorization_visitor : public diff_node_visitor
{
@@ -11501,6 +11719,12 @@ struct suppression_categorization_visitor : public diff_node_visitor
// Note that all pointer/reference diff node changes are
// potentially considered local, i.e, local changes of the
// pointed-to-type are considered local to the pointer itself.
+ //
+ // Similarly, changes local to the type of function parameters,
+ // variables (and data members) and classe (that are not of
+ // LOCAL_NON_TYPE_CHANGE_KIND kind) and that have been
+ // suppressed can propagate their SUPPRESSED_CATEGORY-ness to
+ // those kinds of diff node.
!(d->get_category() & SUPPRESSED_CATEGORY)
&& (!d->has_local_changes()
|| is_pointer_diff(d)
@@ -11512,6 +11736,10 @@ struct suppression_categorization_visitor : public diff_node_visitor
|| (is_fn_parm_diff(d)
&& (!(d->has_local_changes() & LOCAL_NON_TYPE_CHANGE_KIND)))
|| (is_function_type_diff(d)
+ && (!(d->has_local_changes() & LOCAL_NON_TYPE_CHANGE_KIND)))
+ || (is_var_diff(d)
+ && (!(d->has_local_changes() & LOCAL_NON_TYPE_CHANGE_KIND)))
+ || (is_class_diff(d)
&& (!(d->has_local_changes() & LOCAL_NON_TYPE_CHANGE_KIND)))))
{
// Note that we handle private diff nodes differently from
@@ -11544,8 +11772,8 @@ struct suppression_categorization_visitor : public diff_node_visitor
has_private_child = true;
else if (child->get_class_of_equiv_category()
& SUPPRESSED_CATEGORY)
- // Propagation of the SUPPRESSED_CATEGORY is going
- // to be handled later below.
+ // Propagation of the SUPPRESSED_CATEGORY has been
+ // handled above already.
;
else
has_non_private_child = true;
@@ -1016,6 +1016,10 @@ default_reporter::report(const class_or_union_diff& d,
if ((*it)->to_be_reported())
represent(*it, ctxt, out, indent + " ");
}
+
+ // Report about data members replaced by an anonymous union data
+ // member.
+ maybe_report_data_members_replaced_by_anon_dm(d, out, indent);
}
// member types
@@ -2537,8 +2537,98 @@ elf_symbol::version::operator=(const elf_symbol::version& o)
// </elf_symbol stuff>
+// <class dm_context_rel stuff>
+struct dm_context_rel::priv
+{
+ bool is_laid_out_;
+ size_t offset_in_bits_;
+ var_decl* anonymous_data_member_;
+
+ priv(bool is_static = false)
+ : is_laid_out_(!is_static),
+ offset_in_bits_(0),
+ anonymous_data_member_()
+ {}
+
+ priv(bool is_laid_out, size_t offset_in_bits)
+ : is_laid_out_(is_laid_out),
+ offset_in_bits_(offset_in_bits),
+ anonymous_data_member_()
+ {}
+}; //end struct dm_context_rel::priv
+
+dm_context_rel::dm_context_rel()
+ : context_rel(),
+ priv_(new priv)
+{}
+
+dm_context_rel::dm_context_rel(scope_decl* s,
+ bool is_laid_out,
+ size_t offset_in_bits,
+ access_specifier a,
+ bool is_static)
+ : context_rel(s, a, is_static),
+ priv_(new priv(is_laid_out, offset_in_bits))
+{}
+
+dm_context_rel::dm_context_rel(scope_decl* s)
+ : context_rel(s),
+ priv_(new priv())
+{}
+
+bool
+dm_context_rel::get_is_laid_out() const
+{return priv_->is_laid_out_;}
+
+void
+dm_context_rel::set_is_laid_out(bool f)
+{priv_->is_laid_out_ = f;}
+
+size_t
+dm_context_rel::get_offset_in_bits() const
+{return priv_->offset_in_bits_;}
+
+void
+dm_context_rel::set_offset_in_bits(size_t o)
+{priv_->offset_in_bits_ = o;}
+
+bool
+dm_context_rel::operator==(const dm_context_rel& o) const
+{
+ if (!context_rel::operator==(o))
+ return false;
+
+ return (priv_->is_laid_out_ == o.priv_->is_laid_out_
+ && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
+}
+
+bool
+dm_context_rel::operator!=(const dm_context_rel& o) const
+{return !operator==(o);}
+
+/// Return a non-nil value if this data member context relationship
+/// has an anonymous data member. That means, if the data member this
+/// relation belongs to is part of an anonymous data member.
+///
+/// @return the containing anonymous data member of this data member
+/// relationship. Nil if there is none.
+const var_decl*
+dm_context_rel::get_anonymous_data_member() const
+{return priv_->anonymous_data_member_;}
+
+/// Set the containing anonymous data member of this data member
+/// context relationship. That means that the data member this
+/// relation belongs to is part of an anonymous data member.
+///
+/// @param anon_dm the containing anonymous data member of this data
+/// member relationship. Nil if there is none.
+void
+dm_context_rel::set_anonymous_data_member(var_decl* anon_dm)
+{priv_->anonymous_data_member_ = anon_dm;}
+
dm_context_rel::~dm_context_rel()
{}
+// </class dm_context_rel stuff>
// <environment stuff>
@@ -4423,6 +4513,71 @@ is_data_member(const decl_base *d)
return 0;
}
+/// Get the first non-anonymous data member of a given anonymous data
+/// member.
+///
+/// E.g:
+///
+/// struct S
+/// {
+/// union // <-- for this anonymous data member, the function
+/// // returns a.
+/// {
+/// int a;
+/// charb;
+/// };
+/// };
+///
+/// @return anon_dm the anonymous data member to consider.
+///
+/// @return the first non-anonymous data member of @p anon_dm. If no
+/// data member was found then this function returns @p anon_dm.
+const var_decl_sptr
+get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
+{
+ if (!anon_dm || !is_anonymous_data_member(anon_dm))
+ return anon_dm;
+
+ class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
+ var_decl_sptr first = *klass->get_non_static_data_members().begin();
+
+ if (is_anonymous_data_member(first))
+ return get_first_non_anonymous_data_member(first);
+
+ return first;
+}
+
+/// In the context of a given class or union, this function returns
+/// the data member that is located after a given data member.
+///
+/// @param klass the class or union to consider.
+///
+/// @param the data member to consider.
+///
+/// @return the data member that is located right after @p
+/// data_member.
+const var_decl_sptr
+get_next_data_member(const class_or_union_sptr &klass,
+ const var_decl_sptr &data_member)
+{
+ if (!klass ||!data_member)
+ return var_decl_sptr();
+
+ for (class_or_union::data_members::const_iterator it =
+ klass->get_non_static_data_members().begin();
+ it != klass->get_non_static_data_members().end();
+ ++it)
+ if (**it == *data_member)
+ {
+ ++it;
+ if (it != klass->get_non_static_data_members().end())
+ return get_first_non_anonymous_data_member(*it);
+ break;
+ }
+
+ return var_decl_sptr();
+}
+
/// Test if a decl is an anonymous data member.
///
/// @param d the decl to consider.
@@ -4544,7 +4699,7 @@ is_anonymous_data_member(const var_decl& d)
///
/// @return the @ref class_or_union type of the anonymous data member
/// @p d.
-const class_or_union*
+class_or_union*
anonymous_data_member_to_class_or_union(const var_decl* d)
{
if ((d = is_anonymous_data_member(d)))
@@ -4657,6 +4812,53 @@ uint64_t
get_data_member_offset(const decl_base_sptr d)
{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
+/// Get the absolute offset of a data member.
+///
+/// If the data member is part of an anonymous data member then this
+/// returns the absolute offset -- relative to the beginning of the
+/// containing class of the anonymous data member.
+///
+/// @param m the data member to consider.
+///
+/// @return the aboslute offset of the data member @p m.
+uint64_t
+get_absolute_data_member_offset(const var_decl& m)
+{
+ ABG_ASSERT(is_data_member(m));
+ const dm_context_rel* ctxt_rel =
+ dynamic_cast<const dm_context_rel*>(m.get_context_rel());
+ ABG_ASSERT(ctxt_rel);
+
+ const var_decl *containing_anonymous_data_member =
+ ctxt_rel->get_anonymous_data_member();
+
+ uint64_t containing_anonymous_data_member_offset = 0;
+ if (containing_anonymous_data_member)
+ containing_anonymous_data_member_offset =
+ get_absolute_data_member_offset(*containing_anonymous_data_member);
+
+ return (ctxt_rel->get_offset_in_bits()
+ +
+ containing_anonymous_data_member_offset);
+}
+
+/// Get the absolute offset of a data member.
+///
+/// If the data member is part of an anonymous data member then this
+/// returns the absolute offset -- relative to the beginning of the
+/// containing class of the anonymous data member.
+///
+/// @param m the data member to consider.
+///
+/// @return the aboslute offset of the data member @p m.
+uint64_t
+get_absolute_data_member_offset(const var_decl_sptr& m)
+{
+ if (!m)
+ return 0;
+ return get_absolute_data_member_offset(*m);
+}
+
/// Get the size of a given variable.
///
/// @param v the variable to consider.
@@ -5621,7 +5823,7 @@ canonical_type_hash::operator()(const type_base_sptr& l) const
///
/// @param l the canonical type to hash.
///
-/// @return the the pointer value of the canonical type of @p l.
+/// @return the pointer value of the canonical type of @p l.
size_t
canonical_type_hash::operator()(const type_base *l) const
{return reinterpret_cast<size_t>(l);}
@@ -7405,6 +7607,29 @@ is_at_class_scope(const decl_base& decl)
return 0;
}
+/// Find a data member inside an anonymous data member.
+///
+/// An anonymous data member has a type which is a class or union.
+/// This function looks for a data member inside the type of that
+/// anonymous data member.
+///
+/// @param anon_dm the anonymous data member to consider.
+///
+/// @param name the name of the data member to look for.
+var_decl_sptr
+find_data_member_from_anonymous_data_member(const var_decl_sptr& anon_dm,
+ const string& name)
+{
+ const class_or_union* containing_class_or_union =
+ anonymous_data_member_to_class_or_union(anon_dm.get());
+
+ if (!containing_class_or_union)
+ return var_decl_sptr();
+
+ var_decl_sptr result = containing_class_or_union->find_data_member(name);
+ return result;
+}
+
/// Tests whether a given decl is at template scope.
///
/// Note that only template parameters , types that are compositions,
@@ -18119,6 +18344,39 @@ class_or_union::remove_member_decl(decl_base_sptr decl)
remove_member_type(t);
}
+/// Fixup the members of the type of an anonymous data member.
+///
+/// Walk all data members of (the type of) a given anonymous data
+/// member and set a particular property of the relationship between
+/// each data member and its containing type.
+///
+/// That property records the fact that the data member belongs to the
+/// anonymous data member we consider.
+///
+/// In the future, if there are other properties of this relationship
+/// to set in this manner, they ought to be added here.
+///
+/// @param anon_dm the anonymous data member to consider.
+void
+class_or_union::maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm)
+{
+ class_or_union * anon_dm_type =
+ anonymous_data_member_to_class_or_union(anon_dm.get());
+ if (!anon_dm_type)
+ return;
+
+ for (class_or_union::data_members::const_iterator it =
+ anon_dm_type->get_non_static_data_members().begin();
+ it != anon_dm_type->get_non_static_data_members().end();
+ ++it)
+ {
+ dm_context_rel *rel =
+ dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
+ ABG_ASSERT(rel);
+ rel->set_anonymous_data_member(anon_dm.get());
+ }
+}
+
/// Insert a member type.
///
/// @param t the type to insert in the @ref class_or_union type.
@@ -18479,7 +18737,6 @@ class_or_union::add_data_member(var_decl_sptr v, access_specifier access,
set_member_access_specifier(v, access);
set_member_is_static(v, is_static);
-
if (!is_static)
{
// If this is a non-static variable, add it to the set of
@@ -18497,6 +18754,13 @@ class_or_union::add_data_member(var_decl_sptr v, access_specifier access,
if (!is_already_in)
priv_->non_static_data_members_.push_back(v);
}
+
+ // If v is an anonymous data member, then fixup its data members.
+ // For now, the only thing the fixup does is to make the data
+ // members of the anonymous data member be aware of their containing
+ // anonymous data member. That is helpful to compute the absolute
+ // bit offset of each of the members of the anonymous data member.
+ maybe_fixup_members_of_anon_data_member(v);
}
/// Get the data members of this @ref class_or_union.
@@ -631,6 +631,10 @@ leaf_reporter::report(const class_or_union_diff& d,
if (diff_to_be_reported((*it).get()))
represent(*it, ctxt, out, indent + " ", /*local_only=*/true);
}
+
+ // Report about data members replaced by an anonymous union data
+ // member.
+ maybe_report_data_members_replaced_by_anon_dm(d, out, indent);
}
}
@@ -1415,5 +1415,88 @@ bool
reporter_base::diff_to_be_reported(const diff *d) const
{return d && d->to_be_reported();}
-} // namespace comparison
+/// Report about data members replaced by an anonymous data member
+/// without changing the overall bit-layout of the class or union in
+/// an ABI-meaningful way.
+///
+/// @param d the diff to consider.
+///
+/// @param out the output stream to emit the change report to.
+///
+/// @param indent the indentation string to use.
+void
+maybe_report_data_members_replaced_by_anon_dm(const class_or_union_diff &d,
+ ostream &out,
+ const string indent)
+{
+ const diff_context_sptr& ctxt = d.context();
+
+ if ((ctxt->get_allowed_category() & HARMLESS_DATA_MEMBER_CHANGE_CATEGORY)
+ && !d.data_members_replaced_by_adms().empty())
+ {
+ // Let's detect all the data members that are replaced by
+ // members of the same anonymous data member and report them
+ // in one go.
+ changed_var_sptrs_type::const_iterator i, j;
+ i = d.ordered_data_members_replaced_by_adms().begin();
+ // This contains the data members replaced by the same
+ // anonymous data member.
+ vector<var_decl_sptr> dms_replaced_by_same_anon_dm;
+ // This contains the anonymous data member that replaced the
+ // data members in the variable above.
+ var_decl_sptr anonymous_data_member;
+
+ while (i != d.ordered_data_members_replaced_by_adms().end())
+ {
+ anonymous_data_member = i->second;
+ // Let's look forward to see if the subsequent data
+ // members were replaced by members of
+ // anonymous_data_member.
+ for (j = i;
+ j != d.ordered_data_members_replaced_by_adms().end();
+ ++j)
+ {
+ if (*i->second == *j->second)
+ dms_replaced_by_same_anon_dm.push_back(j->first);
+ else
+ break;
+ }
+
+ bool several_data_members_replaced =
+ dms_replaced_by_same_anon_dm.size() > 1;
+
+ out << indent << "data member";
+ if (several_data_members_replaced)
+ out << "s";
+
+ bool first_data_member = true;
+ for (vector<var_decl_sptr>::const_iterator it =
+ dms_replaced_by_same_anon_dm.begin();
+ it != dms_replaced_by_same_anon_dm.end();
+ ++it)
+ {
+ string name = (*it)->get_qualified_name();
+ if (!first_data_member)
+ out << ",";
+ out << " '" << name << "'";
+ first_data_member = false;
+ }
+
+ if (several_data_members_replaced)
+ out << " were ";
+ else
+ out << " was ";
+
+ out << "replaced by anonymous data member:\n"
+ << indent + " "
+ << "'"
+ << i->second->get_pretty_representation()
+ << "'\n";
+
+ i = j;
+ }
+ }
+}
+
+} // Namespace comparison
} // end namespace abigail
@@ -250,6 +250,12 @@ maybe_report_interfaces_impacted_by_diff(const diff_sptr &d,
ostream &out,
const string &indent);
+void
+maybe_report_data_members_replaced_by_anon_dm(const class_or_union_diff &d,
+ ostream &out,
+ const string indent);
+
+
} // end namespace comparison
} // end namespace abigail
@@ -778,6 +778,54 @@ test-diff-filter/PR24787-libtwo.so \
test-diff-filter/PR24787-one.c \
test-diff-filter/PR24787-two.c \
test-diff-filter/PR24787-report-0.txt \
+test-diff-filter/test-PR25661-1-report-1.txt \
+test-diff-filter/test-PR25661-1-report-2.txt \
+test-diff-filter/test-PR25661-1-report-3.txt \
+test-diff-filter/test-PR25661-1-report-4.txt \
+test-diff-filter/test-PR25661-1-v0.o \
+test-diff-filter/test-PR25661-1-v1.o \
+test-diff-filter/test-PR25661-1-v0.c \
+test-diff-filter/test-PR25661-1-v1.c \
+test-diff-filter/test-PR25661-2-report-1.txt \
+test-diff-filter/test-PR25661-2-report-2.txt \
+test-diff-filter/test-PR25661-2-report-3.txt \
+test-diff-filter/test-PR25661-2-report-4.txt \
+test-diff-filter/test-PR25661-2-v0.o \
+test-diff-filter/test-PR25661-2-v1.o \
+test-diff-filter/test-PR25661-2-v0.c \
+test-diff-filter/test-PR25661-2-v1.c \
+test-diff-filter/test-PR25661-3-report-1.txt \
+test-diff-filter/test-PR25661-3-report-2.txt \
+test-diff-filter/test-PR25661-3-report-3.txt \
+test-diff-filter/test-PR25661-3-report-4.txt \
+test-diff-filter/test-PR25661-3-v0.o \
+test-diff-filter/test-PR25661-3-v1.o \
+test-diff-filter/test-PR25661-3-v0.c \
+test-diff-filter/test-PR25661-3-v1.c \
+test-diff-filter/test-PR25661-4-report-1.txt \
+test-diff-filter/test-PR25661-4-report-2.txt \
+test-diff-filter/test-PR25661-4-report-3.txt \
+test-diff-filter/test-PR25661-4-report-4.txt \
+test-diff-filter/test-PR25661-4-v0.o \
+test-diff-filter/test-PR25661-4-v1.o \
+test-diff-filter/test-PR25661-4-v0.c \
+test-diff-filter/test-PR25661-4-v1.c \
+test-diff-filter/test-PR25661-5-v0.o \
+test-diff-filter/test-PR25661-5-v1.o \
+test-diff-filter/test-PR25661-5-v0.c \
+test-diff-filter/test-PR25661-5-v1.c \
+test-diff-filter/test-PR25661-5-report-1.txt \
+test-diff-filter/test-PR25661-5-report-2.txt \
+test-diff-filter/test-PR25661-5-report-3.txt \
+test-diff-filter/test-PR25661-5-report-4.txt \
+test-diff-filter/test-PR25661-6-v0.c \
+test-diff-filter/test-PR25661-6-v1.c \
+test-diff-filter/test-PR25661-6-v0.o \
+test-diff-filter/test-PR25661-6-v1.o \
+test-diff-filter/test-PR25661-6-report-1.txt \
+test-diff-filter/test-PR25661-6-report-2.txt \
+test-diff-filter/test-PR25661-6-report-3.txt \
+test-diff-filter/test-PR25661-6-report-4.txt \
\
test-diff-suppr/test0-type-suppr-v0.cc \
test-diff-suppr/test0-type-suppr-v1.cc \
@@ -18,6 +18,6 @@ Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
parameter 1 of type 'S0&' has sub-type changes:
in referenced type 'struct S0':
type size hasn't changed
- 1 data member change:
- data member int S0::m0 at offset 0 (in bits) became anonymous data member 'union {int m0; char m01;}'
+ data member 'S0::m0' was replaced by anonymous data member:
+ 'union {int m0; char m01;}'
new file mode 100644
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
new file mode 100644
@@ -0,0 +1,12 @@
+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-PR25661-1-v1.c: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-PR25661-1-v1.c: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;};}'
+
new file mode 100644
@@ -0,0 +1,5 @@
+Leaf changes summary: 0 artifact changed (1 filtered out)
+Changed leaf types summary: 0 (1 filtered out) 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
+
new file mode 100644
@@ -0,0 +1,9 @@
+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-PR25661-1-v0.c: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;};}'
new file mode 100644
@@ -0,0 +1,12 @@
+struct S
+{
+ int a;
+ int b;
+ int c;
+ int d;
+};
+
+void
+foo(struct S* s __attribute__((unused)))
+{
+}
new file mode 100644
GIT binary patch
literal 2760
zcmbtVTW=dh6h7neWt&Z0CkD|dJS-BZO~tM+KyZsv3=wGx2t}zX^#z5sy|x#8LH4$U
zn|J^r^{thV0D*)MFFYas13!ajB*YtUNIbwfvvcCfWFrua<UQYf=Q?LD{^+GwcXL7j
z4*}O;F=H0MDK2nZ!8TN34Q}n-`(^Lmhkx9E{im;x&MTFpA}lLxd|U(PZbC%}Cqhbw
zAY_RU$PS3Sf_d2mQBcs4JrG3&mm!}o#FGRH{pl3M(s896T73NlhAGZbcb-u0!4OK0
zPqD?Sc%oc&WqG5#D%MJsM^IZ8(sA9Z?sM)HS5z_o3P>lN-l(=PX#R0<-D|FN01AP4
zex0=!*C|H(!sjoplV7o5_~kADl+L5y4b;GsR0ZV+jA0C}*q{{L#jk|R_!Z*M@(O;{
z?%+xVB+)$a_Ya!SY;86ChJUvnbd^s*z_~OBIWLKia}xcstZT#RII8ugy*K09AWmwd
zxD$5bK^Tu}I&O{J=Cxj!gbMn-xZn5t@hFLAaQ(Gg-cI9LuTc-`LBng-oAvrr&6aoR
zAnJL0VWJg2DjS=gKThsUqU}L6iDq#Zr{SzS+&*e;`CCtW{s7?m&dycu5(eG;cM)-Q
z52*!XGu}G@aa0i-%O&SNHs?{~=|@Ag_Jwlg)7;KVaTg6zI`c~>C=b8?m8HZcX3@Ak
z$IU*Wm#E1aQeO*OC&9Q>hEhVwm@S}$bBl?AWV&L5Nuh+5QydWz%4hJWt}Hx^mTN{I
zj*o5D>7q-i2d``i=Zs0k8HlIV+$0jmYAS$vJyrP$Gtc|Kt_^61%-z`3JlUK3o}6LN
zwUK>6+mNVeY{$QH2JdN}YBB49VE*nn2|Fm0St^H&lISRbfNmNDo%tMsSu_fRUeviW
zIE*L#De4psJDpi{_k=o}g_A*a(q$A+B6h(P5Ok;GafFX$FqtM%fY;2QCt>$39Vi+e
z_GjT(y}P>j{~<QemwLth<WOx5j?ayr+c)bm<cYIy&@0;B7PkLIG@$+dul^16wPR9F
z&i@TfjA7f-Gf#hhZNrA(?erfJzSlgRE28*p;(vu2+xWF(lHxa|1$akG7Pjp^Dr}By
zLrvD%QA^vF)|pj5Ukdi8`ssDD>+d0F$3zMqX!2#67{j(bL|s<?y1ta$C(2LnhMoUy
z<R~WBiBOH7b)s*X(311Bd>?tjw*LqEGB^Lh{}b(RnZXYy9)pFJ^D^_L_P5P{)I^I7
zwdD0P{TYI+{_SP-k6wTF=e|-sc5aIOt0wn#!Sqhkzl!Zodt%=`q@YDb;o$c=ot-`_
S6gSKN4PF0t?5L&PzrO*xO1jSg
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,20 @@
+struct S
+{
+ union
+ {
+ int tag[3];
+ struct
+ {
+ int a;
+ int b;
+ int c;
+ };
+ };
+
+ int d;
+};
+
+void
+foo(struct S* s __attribute__((unused)))
+{
+}
new file mode 100644
GIT binary patch
literal 2960
zcmbtWO^72!6n>S;PiH#m$t23|FdlkA*_ma#^P`TlE3-xiXJ=NCab&@RGIo+q(wcN6
z=~>4W@t_DR2)iJtAb9ZZMer<m@#tO!4;}=s-WEjG_qwZQDm5*NK1kK8@BP-RSJip%
z+2^-2jDaKuSKwqNQGg%wCwx0*+failT;I9%>&~rr@7;d&`=1fc#v&v3P>OkFFcm&i
zV)@+52yhRWVG;+t1FRUcS>6S<5VHnkv$-IQAXj3X-$b>1<PCu3io_QjGBn8iBm5O<
z$iRY8z!}V!pu(8(HL|4x0(cLYRUqXOl>3tju<G$%WpeC`pHObiP_{^1=FSinjXTHz
zTVjt`HIrK_))K20DrZnyW2Sl8eA2vRvKj^`12>Z8ZfyfyW*-LAykc?#Aa`a?HLt4T
zM#`{@4h+V2YvieT4%c<`upm5GxSty1h8nI!Mii#(vZt11<nzmvUHj~(&n%NCE2rd?
zISa73h&fR(xJdh>odM>jkgSCQ#q2hY94_F<*dJCI$GCH_h72Nq7CC$St;g5bn@-cY
z(R919O^!h^i9yCy_I`$=-DnaH?89&t3_`zW)A81ald)g#O?s~f^+6ETM?uHy1OqP^
z)rHqOg_zZQUgX8B(+m22ryq<We+pM$xNdJXpRk(^x8XMJR-@HuJlfi@SNGBXju#1m
zgTm&T?Tn+t(BB;Rp+60}xb&vo;pWlCy0iY6?F`a4b9HO$vb~Cd*8W|Tc>52;BNpi9
zKCq(-TPYQc+gPxN5T_qeT<)i>%7>Y)a(){X5;%3Fe$B$~_tS(}*fbcA?DzoY<Qyew
z#Kkq%WgL`8KoN3?ubYA-EQjJLi~yeO_>_!8`4pDuWAmpF$7`(9g9ucWIvlrhT7S|L
zAV}_P0oRfzk&Hk%?dC-Sk(QDPB>tsXQ+y(cSCb_yi<wSHJ&iSilfHWHA1k<8#cu_!
z`;j@5pPbO4sUmn?|I**!w!kSzHBWG7Z;vCdgL5=Z=Aq;w|0n{N?j^XL*$mvNKl0q3
z-#Hu{1Yv)IvY7WeovD9gPV7y+aNy6IjDpaYCKv+T?qodn@riK5N#whD0i9Xob>9$<
z{NX`=>WzJo`2U<%(4J}~>nYu}1#{d_Voka#ox=rT`ptSyRZ@7}{yfU45B{rt6K!>$
z6i&wfg%%3wy7Wn)k9b?rA=VI0^_{?}uSie!EPhvF+Qd=!NrH<4yc=ts47%<figb*$
z{}f>3#5Cq~UD{__{y&KPr9I_Oua=&F4>8>*Lg0wYaE%rU>ALhkBQ5?t5ntAc;?up>
z<G+a*`ILDg8`E1N{x=d3vy3n2cMwmrzaSc_^$+$R2zyNpUeOy;D9E@{|8rqK_jVxm
zny}xHiei@gm+&XZq}8t?E~HvN`YK3!iBmp$Z1Vk?h`%QiruUn^Ho85XN!nI_qok1J
XJD#jg_X_z<vtJeYe<cmYtk>@^Y+2C(
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
new file mode 100644
@@ -0,0 +1,12 @@
+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-PR25661-2-v1.c:20:1 has some indirect sub-type changes:
+ parameter 1 of type 'S*' has sub-type changes:
+ in pointed to type 'struct S' at test-PR25661-2-v1.c:1:1:
+ type size hasn't changed
+ data members 'S::b', 'S::c' were replaced by anonymous data member:
+ 'struct {int b; struct {union {char added_char; int c;};};}'
+
new file mode 100644
@@ -0,0 +1,5 @@
+Leaf changes summary: 0 artifact changed (1 filtered out)
+Changed leaf types summary: 0 (1 filtered out) 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
+
new file mode 100644
@@ -0,0 +1,9 @@
+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-PR25661-2-v0.c:1:1' changed:
+ type size hasn't changed
+ data members 'S::b', 'S::c' were replaced by anonymous data member:
+ 'struct {int b; struct {union {char added_char; int c;};};}'
new file mode 100644
@@ -0,0 +1,12 @@
+struct S
+{
+ int a;
+ int b;
+ int c;
+ int d;
+};
+
+void
+foo(struct S* s __attribute__((unused)))
+{
+}
new file mode 100644
GIT binary patch
literal 2760
zcmbtV&1)n@6n`}}AHC^hc9K!t5DzUVyAiwRLyfa5*&PjLv#UsmEO?RFGgC9uIv+CA
zyT&g(D8e3uT@X|hM7($s{|EmJ&w_aKCV0^Is_SJsl@5wNn0~K*@3UUjtNHMSmv(bP
z0F!{Luvjq);1m~fTZ?U|!W!J#yZg)D-4Fh__u5ZiA)MDLM@LxJa_Zxz<lHMz5yDXj
z$q<Arkp!{>BCo}~?1Ct0(UCn6MJ+BvK3|9?F%<gKDTt-xN;$On`U?zGoTKhMNxAz&
zC^<gG7OUd1a@CdPjq<8kD^(ssZB<Ceb+5S3x|dy1#r!KEon(2V+QOjuN5OTky3zqC
z1mfB{YcH--jP`}kpI;}xVj<<1y8uu+kA62$15Z#Dlpiogin!twq{UtQN_ZT<Li|}?
z!LL3Y+^K+A&0~N6p!xLHR>N=lcj`e``xFG6OLCC&lK3bm(XTd~j#aHU?Y$Az22ora
zMV+t{4Z>(tGcjrua9-<$ai~SV7xnvoKN`hq2G?J{<?S?{@f!7@9yGjWy;-k6*=%{2
z4ph(E3uB}3QQ6q^{BeAHqP7QWqGnMSm*K2C+&*e;`CCtU{vf;b>pMGFyi1s9^WSB`
z-94Z;jLmrW0K`#6Y%G_Yd)S<Z5vL!KZtZjB$|t#<mEtZMByi@JZcrY6|0_$0P0WJv
zc#fNWLN8I1MbeCgt&@-%s+3YfDYaUN63#6aDM=<fP9cdXVdWG?fQ0fH_^FYF2hnmZ
z)raG2n{^jyC=Kz>mT=87sW=1Sw3}-LBCRG282{9)DL)b8$qHcI2y{Z})7UgP*{9Dv
zKEs}CBm07}AyzT69slwfxMy&xC0!2$^LNH^*g+o85<X-pR!1=eG<^_s=5q*UY7_=N
z)ww-5j3)gl>a-koIx}_WggTsslYu(vGKwaOT`&a%-RXF&@UaXg(^v&KX8t@5yKkC6
zYIxY6g=78hn&STl+dyCH759@vwT*CmZ_L`BtVa+h%$}eZjlIom|BGlq=lx&(8|Z7t
zq@0}p8(O5uwxwsD{`}f08xmhl{t@AOgVVhti0>x;S7_SCuN{*VziBPN+lDi<ZTC@O
zV`Li|u+EN#+qSgNtonH<*q`dB*U7HGhnO7`A-HeAo3u!gZF`8ito(H|l-wuEPw$4E
z|1HEQCfA9grk_osZy7M0^D}=BaguHS_suXj|H1!b<8PV44<{ajg_iR&@}=>&&3`mN
ziwzCu{WJU-3R(Tz%jh4y{_M|vrF!h#6#G{L?wf+?ou+>k+n>(Fo;`%1MMWX;d!4LK
T-xZ3R<^Q^=|2uXx-0t7soGrUI
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,22 @@
+struct S
+{
+ int a;
+ struct
+ {
+ int b;
+ struct
+ {
+ union
+ {
+ char added_char;
+ int c;
+ };
+ };
+ };
+ int d;
+};
+
+void
+foo(struct S* s __attribute__((unused)))
+{
+}
new file mode 100644
GIT binary patch
literal 2968
zcmbtV&2Jk;6o2Dg+v}|DI&n}F1tB9qZBTdp0i<bBN+2Rl`BD_<2|={>uI;7%K=!r@
zAjAPw(OZ#_5E3`82#E{-00*udBP0$S_yZ7^N*v(5*?IALvJnVI+L`x$?{nVF+xh6l
zS9UW(01pAzV8$^DaGaab+mhUdDlEaxy?ejy-TUyt{kMMj1z}T)Ea{;r>BM9w=!_`}
z`BxDz2o$!Y%?^lS?hQh+LI%v4*>Ds=-W2)lErczHgpjv{Y1~Dk&<2q!NDJ#t<V{$3
z9V$Xt-;&S+VdP^W8Jh(kL`4Ecu)E_ih~<;La&qFUpHa0qMcFx`GN1LKWKk>-i{goL
z)i%m&<wdcSubfBed12dE?Pu*Pwy5G}N??>@_6D*hvet~vJ`T2h4ebGPinMSq)j1bd
z32sz3F`Gitn1F?<Fsx)W+ZE5Pa)1k~l+*Ug7cZ<*CdF(bbY=yhbPj`4QgDfOMf(Aa
zo)}z#1SH8_oDFyqXCeM9mvEN%1uG{Y3Z{{>f6#hnW25P`oI6doBW<z*3ULfFUKSr`
z47BrnKkyGbeQyHw{&*PF{jvW}Snq{VeGs<2cG&a6L0!44lkaKW_aaY{jvscrPB$Dx
z!6Y^A_1A9JcAA%K&4$}>o3&P>)o47`+N@nX2>jZf7b$^*!sdF-8Ai89!B#IA1(UFY
ztT*ZOw~jV9oQ<bzP7h?3aD8XzYV9I=UjKJ)VOee;OY{B#h@*;FE9R~HSgMB+r;mm#
z^z-G)-ONrYw~GofoI2C}G~xHZ(u7#jG#C%-r1W!gBW|`ij2J_;tu8P?_Mi@<e*P3j
zfB}Uw@bs%?K<Ny9?2wdUz^PvfJcN2ni8`D_O1qiV@@nwT7LaF}L>z%|+RfVp;#iCq
zVEiS;Q+yhXbNtm9mYF3_V_o5-pFH==2|QWFeGUIc@!zYJZa~sM?}hwll@2WxMeF)k
z&cJI5C*Mi`;7;EgMqV4&XcDh|rlQ~|0+$*V-1c+|?j#s^t{=2-_YT8RcZ@Pgd+qil
zxHBjACf=wQ%$p3tQNSh`0^H7cI1KPLa7W`PaIq<!Y2<ZoDMvy7usiXFflB;;E^BB{
zwc>iRyKP1AIWw+z;-e@aOg?X{gzL)*I!WsG7f?v|<G<QB(N_0K@i_jk#3Y8UOOFIS
z=GzG!A|J#rJRB>W?iE3Nm+_^MV+&{9CkZYo@JFdNn{-{e_c}(}e<-jqGnJICOZ!aA
z|0mTHY)|>q-%QWnM@;vL5Im-uf%~5@8oKTwVrlXDLUElaKJ~jE|6S#i^F&sTp^E<<
z18U{?yncW<(YpO3>O!^t!Tu9vuc^Vlej$|t$7TI5mHphm12MMWWJR^|{u%xpiM0By
zsD@0|k6sJ5XPolUW0UVsRsQ=bVfwGrE2P`gnWSy?n3BT5|M!?Xeg5P(&Ay@X|C$Ze
Hs@Lytw-L>m
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
new file mode 100644
@@ -0,0 +1,12 @@
+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-PR25661-3-v1.c:21:1 has some indirect sub-type changes:
+ parameter 1 of type 'S*' has sub-type changes:
+ in pointed to type 'struct S' at test-PR25661-3-v1.c:1:1:
+ type size hasn't changed
+ data member 'S::a' was replaced by anonymous data member:
+ 'union {struct {struct {int a;};}; int new_union_member;}'
+
new file mode 100644
@@ -0,0 +1,5 @@
+Leaf changes summary: 0 artifact changed (1 filtered out)
+Changed leaf types summary: 0 (1 filtered out) 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
+
new file mode 100644
@@ -0,0 +1,9 @@
+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-PR25661-3-v0.c:1:1' changed:
+ type size hasn't changed
+ data member 'S::a' was replaced by anonymous data member:
+ 'union {struct {struct {int a;};}; int new_union_member;}'
new file mode 100644
@@ -0,0 +1,12 @@
+ struct S
+{
+ int a;
+ int b;
+ int c;
+ int d;
+};
+
+void
+foo(struct S* s __attribute__((unused)))
+{
+}
new file mode 100644
GIT binary patch
literal 2760
zcmbtV&2Jk;6o2FKSF(xg#2^}l!y<v&RP6er5Zt1)hKMu;grZcHdO_*h9@`84K=!tT
zFL3}N_0~#AfIvcs3n#??z@Nbx3320w!~x!$ofmH=8&S1S^1e5}_c?FojX!<u&7F)8
zz$D-b%vX#86!UYrrNtIhU=?oe-ur#`-Y0+GfBV;O5zcB=QAb$Pa^mA8<jf5y3$dUO
zk^u-=APHm}L{^Jg*#VK$Vo`QM<h8g2*=#NxN094HCLk7%D&^4PyRR`!eula;BxN29
zpiuNEwpbC*l`4)bt(R8BYN7lTYAZq(9p|$1vUAB170ka3vKTL~SDF|!`z$!l6-O2U
za=y5_#@cgh6r*+at5?^^FP}^JWzGT=&Y<6Q)WGvp1?2~fksz)(0cmjuzY;FsSBQT~
z%lOr&gF6)vsafRh?KfWB+^l;Sy}LEPqkVD$7UCS_yeK})Nc5`?CL>ktPP*@e)qWUN
zhhaNthy5TNR!xj51)Np8K@@1w>xR9a*9(V{nx-bZ_SQ{zyZ(|}ulY5<?lx+TTJ2(^
z>7L(LU3WK#jKV`@eZ%!e(Vel{>Z`Guh8<i6)6QV)u(|1NzTkR&fNR^^m)-LibmQS7
z;_jZ%8^&gQxDVp6EY_C_#rxQtrxB+gk#6lPrScb<?dALq8pLqwmu^rN{`xmfiA_v{
z@pz7!eM~P=lSa~vg{_m27^;L)LLsr5ixL**i-aWO9Vd`jl(2jPBS1pw6#T@<!jovZ
zn&`vPwN1N=G?a#TXN$OInN*yCaN5lc0+Ci?28>@dYsyc=c)S8wGXkAZ@-#LKPWH)j
zk4~}Y+Q>d<Y>1VOY{$QJ3ho-5YDv}u{_KNM6ts~?)0hufiqv5QK20C^?b!_csTu};
zSGDi-55jS8f;ue+?e<jNJ*Ez(!MLxEy9~pzVi!ySerGZoDSRyb@g!0{j+r-$g3h}p
zkQyBHrol+RyQcWZVC(2hz2bgysFo3q?u}X7ll2VZgxM4HhOxJq?SBpp=)51*zmC3k
zOv=gmzo$ilY+HKf>Cdl~up#kQ{ErAf8JzAFL3}syze3X%e(ji~_)}{E-Zz|?ZM%mG
z8zbAmfHihB+_t5Crq$0w!TwY~y-s%hUBv8|2*CpbzD|n-*|rC$OUqv~L&<%j{Pb?v
z`QJl~Vsf1*YWmG2`hfw%IY0A{5GUF8|JV$3<A3}=H~y9x{Cw;&m}@yNBi|T*+x!;;
zG}+K_-ao@%qL9|V-IV^(>(Bn&SE|R(O|kzl;GQX%-f8+*vHj^x?Ab#Inp6}Lzt{2V
U<Xxe-Y5uoO{Xep!;dcN218X(A0RR91
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,23 @@
+struct S
+{
+ union
+ {
+ struct
+ {
+ struct
+ {
+ int a;
+ };
+ };
+ int new_union_member;
+ };
+
+ int b;
+ int c;
+ int d;
+};
+
+void
+foo(struct S* s __attribute__((unused)))
+{
+}
new file mode 100644
GIT binary patch
literal 2920
zcmbtV&5I*N6n~Y<=X8?EOdNKH@esjfcf{^|tj=avW;gEO?CdHs%&-R!5;{pIX-zsy
z(zA|=cu<7BtssctLGhqBLHq+2{09U<(32Ozt2e=ezE@q9RBC%sv>;XQ{oeb%_v)pp
z`rQ{^+D|YBYB0D83r(Q_U!@mvONcEf!#dnPxcBS9y?6e&|LS)?BAgVatcZ{ovNl<o
zoJg`v<~jo01(r*bgzRL>4?;j&D)kELDO<qlB;!0pF>@2AEMY946O`OBlo-o?iI89b
z?*LmBfs?!otR%!N?*UsAVjfodlL@em`6g9W?9(4GiZw&qDoKeChmg-wTI8~G#j?eV
zTg5fDo++I{YnfTr73(?cvc<}{ivsX$q~0tyF=X;du&k>V$7)jrh_LjTB~FHL+z(QV
ziVBb`GoIB$uQ=@5rV4(3lL}~^{rLJOrL|I8+QeCa{3@oUsPHsxfr^hBCM25FcISW;
z_HpI#6wZwOSuEfzP6f7!LFmmw`|zmo?9NWzzG&aAJ6*v_F~~(Zh`hnxOK{{>hm)~a
z?M-^G`PG3RR!4rv?f3)NA5~?HDg~TXdv53o(eC;EzTNjnp*M|9cH`ySmA(3<O1<XP
zoO-2EYt(8N8_mjvBd=FEa6@UZ(OBQE*yHdd@OB4Y;7$E5s_wKq+&yjX*gMZu>;VMc
z8|{<8p9Jl(H|}6cxUsi)rE&qYZ2!9y0FQ|VU~}F&0(M$rTlq}(J~r!d#OX&vwEFpC
z>4U^xA-#_d5ga?yaZJMRf5jQGsc|s=UGwHI**RL`2A9{<v~kcbw`Sy!(X@rgA-7O8
zi9h0SaVThB3z0){p=c6^hn^1DK>NDZhxsv%JDYUF<xo3YL0!pYQW*%R-5e8$V=Y=h
z;n$>2`DrLT(f~H4K>v{bZ){7P{Pq8RsNt0NbE$tVS2K>Pnc}3R4=p7roBo#{fmb9>
zHR^SOGkbF!x*c4@X|xWN6ndv2ICM+F>C9%}Oudoo^t{f=pzR0!3EG70b~;n<?vmM^
zy1~F(ri}c+Qxr@APIodMd-&cv!6ft?ynXg8bi1$1K;E$3pSojD7XCk%E#y<LR6kX?
zmK5gaN$TXQk0($e%)D7I>Q0($^3S7<&cT1>*O6<+q;x9(&!lL>^rg=MeVkjG4~f4-
zUu<|FaXME7sWXe;6ft&jHe-_EoCLoWUW>`}Jw%g<k@rs$tSzWQGJR>EarJ*DFNNY$
z{q$;?_4g1nV<I&Fe%&HP8>Vj?ZE^X(m-$tnC_mk6GyfgLD5k0tMKO-$W&B0~a#i`&
z`ZnTm{FFRUjep?3FZqTWTrv-&bWnMf|0j~a^mZWDl>DZ0l&jjmf<Hnbu7AJ9^pCy@
zim&=g^_aOS_8po3P!>$@H+^kPKK&<gTYW%9;ZW~*q&<9AC~h2IJt$u&qFl}X{SB%O
B%isV2
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
new file mode 100644
@@ -0,0 +1,12 @@
+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 func(S*)' at test-PR25661-4-v1.c: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-PR25661-4-v1.c:3:1:
+ type size hasn't changed
+ data members 'S::a', 'S::marker', 'S::b' were replaced by anonymous data member:
+ 'union {uint64_t marker[]; struct {uint64_t a; uint64_t b;};}'
+
new file mode 100644
@@ -0,0 +1,5 @@
+Leaf changes summary: 0 artifact changed (1 filtered out)
+Changed leaf types summary: 0 (1 filtered out) 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
+
new file mode 100644
@@ -0,0 +1,9 @@
+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-PR25661-4-v0.c:3:1' changed:
+ type size hasn't changed
+ data members 'S::a', 'S::marker', 'S::b' were replaced by anonymous data member:
+ 'union {uint64_t marker[]; struct {uint64_t a; uint64_t b;};}'
new file mode 100644
@@ -0,0 +1,15 @@
+#include <inttypes.h>
+
+struct S
+{
+ uint64_t marker[0];
+ uint64_t a;
+ uint64_t b;
+ uint64_t c;
+};
+
+void
+func(struct S *s)
+{
+ s->a = 1;
+}
new file mode 100644
GIT binary patch
literal 3400
zcmb_e&2Jl35TCbe$D6KWoVb*v;jopc+DPo$4j~DxQbMCpM^q@JDu@HJ*7n+7YOjlT
zT_r_)NK~j5LJAV%L*fKyBo3&83l|Rb1UHU|3x5E&3WQ+h?R)O#Wg{WPNPaW(o6q;T
zerxmcvl?R{iNOVUph*<qw(&q-=i)k)U<R(%?)+A}^Tz$!dz<%bKk(4~SHAxXJu=+O
z;K}k_P7Eg!vc`CBP0JCeWnyN;j7@M*%M#NwSwDzCGq}bJX!iU?ii-U>q|YDs5XxSG
zS*9D`p~!QvY@TGuxxgm!yIgDl%W=`jHGvsiEP_GCAMrOysR54B!1Ci|k<GKu{y>8n
zqOC}h_CXiqW%}y6ere2sYOtYC>@e#B>2BvudA)JR0ao(8|pcl@W=gp_gtr9j}
z!j?@l1{eYpQwjU3iR~j`$N&Ni#<oi2I(Z7VN-KyQbJ){!GV7T+YG8f#<BN0TWM&iL
z+AKi+A#96E!{amsY911MjhdV;HzkIfDC_Vtj*R_Tn8J~tBU~m{9)-iQA2fTTmRD~0
zQ3w!uVPtRbEIzrsT(y_%8x^NXxuU)6Ug&h`;Dk{Nch?@_5X1;%8BE44QLQ}78t-J;
zmzs{X!tP)gS)(BIJAv1-=v*97%H2WVE4K!%SN(FwkIFs2;Wqq^>-Wl{i!!womRoM*
za?x)2?Y7<adyzMU-XQ2G*|Eg(Qaw?o*>#7&2kuQRh;BHTHsedrU$r)>D^|7QRGg}{
zSXr!8o>*M9&hFqGYHlP9HX5r7mfep=fw$K20&nOyQFVvS?%M9^vc0@y*&RUr8ur>A
z1x<+8gL<gfX$g6&aA{-XoOKqfF8sTaaGW*;iQU`*wp(QL`JAzjoAW4Q^dsU2;+aD6
zU2S7(;stbw;na~XO$L7dJI#pOm<Hpa8t?f5yN;GL(#2b&+VuG1t1xEaZ%Yb3c?csw
z2fS1%q{CDSO8$7qQ%HwH?;t#kelv-67+<!u)5AA9PRyS)6zOe}GFfB=!f7^l2}GKX
z8TTjrbD>jxBI$2&4PZ`i+M(obEC`(Zllxvt;FO;p2cngjjq?i?zcMk&y7T}MZN_Zu
zUl;mi1^-CsR}{P`j+Cq5?+d-H;3tKDq~N!OzNg@?34LF|Ga}DV3T_JgXMvNNTu-@o
zv=02MCj5#=_;-)MErC<+WPWhMy?*32kVnIqccm10yAe3_{(;j7LvV&(&vjZ}W7Mhp
zL3@BUF1wA!(7SQK><-<a;~fm?`GF@xumm{GLBH?egX9E*$aC-!vct%2UK5GDZoNHp
z`}C>)A7~zP(AvuNlquJRFuqqp7uzD;;1o)PsV~fnV~>M^8h-}ObRYg}d=+EWoK#WP
zPy9tA_>eDsyy@T1I{uRMjW|^IL~=S;<R|Yg{sZ8&hGSa&mjw8=@RLmS-994T6o;`Q
z0|i&(pF=#Y|F^|cE#s+wg4F(7h^aXdg7c#Oo1`R2^`&<vt^QY{zFa4&Pw$&r|2krn
zQ}&4>r*B35(@H_9O8z=}r^Wvw4%DK^Cz*_s{FaE9cFBu0sT7iN()1|`go$<~3^IOo
zjKqSRzl1+TA#MHcrK}%)9c8>+*R<M{yC(YI77f#PjJ~>RJne~k_Yi_l#Q8r-N`ln+
SQ{J@rUq%04Bw|Ta<NpEtS`j<|
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,21 @@
+#include <inttypes.h>
+
+struct S
+{
+ union
+ {
+ uint64_t marker[0];
+ struct
+ {
+ uint64_t a;
+ uint64_t b;
+ };
+ };
+ uint64_t c;
+};
+
+void
+func(struct S *s)
+{
+ s->a = 1;
+}
new file mode 100644
GIT binary patch
literal 3480
zcmb_ePiP}m82{c((@Z-}nl|fhyAjNS%eLT5l3Lrk(lu_W+r>p{mkJ6JC&?rkH<_%N
z$<nT<2UlScWCcNmy@;L!_vqDw2fgXhqZh%09s~~y9`yU(yq8X1XF<dd^4|CTzQ6C^
zH+g&e%Cj0{Ac?^RIFcj^@RM=GS2<gSJj}!X&h1}zZohed=l$*bJKu5FJFk3Ozz`GM
z%HY9fj+`UzWDL+4kF9BG0=0=~GNOr1a!^arq)((gKLpL-5>KF6g^T1B*>OlOoNy6J
z<(QHB0+~q%*mUjyIhd>iGdXKOI>%D_Hwg0VES)8O>K2(zlkpGuGbuK}%vD%my73#b
z8Hxy#4Pe<BvdTf005(6`G`Tc(cLA~40ChRyv=2LwGbk#sId(RiH}z~GJIChJxl^cp
z6io91Lbyu7VqFs_LC>BypE92`FXwSdd1jiC$WWZjfNn_bh6#{9HKsREAM>8d00o(5
z>~fym%`+&kquWd#7Z(qlAxjFFwb|2)GRC<@Dz>`t@x?`QpH0QGYYVs)v$zDx0FU8M
zqlHF$%Q+h4){Fqb+{9UjmvCh4uWSZKej{<ySZNpxN}k{74x4VN?u7wB=mw#+ySMVh
z+FHe0wQf}G2E_>vue*WWp(_}KO}r=85C=a(AjM!RDv5H<vy|~pihZT&m@DY?2VrsO
z2VUEEn?<@|V?wFZ@42OBzxkS1YI|X+>(!mQ*LJ*aNmNmyl7dpx2_4Q_O|R9mT3$DF
z2hi>NZ6!LUSX-@yi7OeUZgiXh@PS95vP6X(y!8BjajUXktd#AtT`8`VSIXtbS2l`E
zd$@)jClm?`m6he9)eDEdyV-Vqci=TpbOw#i=E26AwYFNc+JN#kthF`t8xZXW<*U_b
z3wfz<X>03zaS5|7|GSiQBuFQs3E0g&U<Wx?m`NLV@Q5BpoPI?7T0E1@y{BzuCSO2<
z2u>W)6+6oxe<vyNFq2@sTBDO6)9a{7B3<+@Ri^`QMk<U^c&|#pr;cF+=zvcvfpo|u
zpk&W`%rTt~$NDNfgjVyheHcBtq*ud_I|?gTHjSd>Nh325POJHvK%}{70*TWTCZhaA
z5-)NIU{TC;Lh;jB7C70*&%GSODenhDURQ7-;#VsonU~rS(RMVA>Zu9&ih_SB<f{sv
z6IaSn@Xv(YQt;ElK2-3#LOxXR*M)pf!6!tV-xb^x_@4qNF}|Pj>}VhOS5nyJ9$?>j
z0A3V0#g4}ZJ2>oxP95iP5X~LQh3-KJHg!R;>p=ka!0kGA)2$ENHP3JLQO9|wULUwO
z#?;Qh@!RgWOV{&V>4GW1ZuEOS7u%BU_e0mlR%8XC)3_!Axt&^T;PmLz|36RxW6<8p
z{gffAf*HLlA&X;?W^e{M!qg7);>cp0QT@-Mn%={I^{=3>8j~{0{EsL~MdY7w`ZrZ2
zrx+PxL%tUdbg#%xzFqtuz-bdlH6|&B0{oeT7^$|qs8caA-xrrr_6He4wS5j1N%j9I
zTDA12`Uz6&Zz86~L<rs$`QIWTMyf6KnWX$Ok=!TBPyJ2Je;qN3DeFX*lP)gAStX$q
z<@^R(C;2Z?QAjJ%G#aI!oNu8<@*^W;UKajwjCj@dQ-O{34#Zv+{u|^JBe{MFeS{2|
zRwW?j1z{N9Kl(aKe~D8)YHkYgiO9bz3a0NEeRWlTIurHnAq2mQrh1x$7^&;0xJmwH
Mk?8Z7FR`lsKLqa-nE(I)
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
new file mode 100644
@@ -0,0 +1,12 @@
+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 func(S*)' at test-PR25661-5-v1.c:22:1 has some indirect sub-type changes:
+ parameter 1 of type 'S*' has sub-type changes:
+ in pointed to type 'struct S' at test-PR25661-5-v1.c:3:1:
+ type size hasn't changed
+ data members 'S::a', 'S::b' were replaced by anonymous data member:
+ 'struct {union {int a; char a_1;}; union {int b; char b_1;};}'
+
new file mode 100644
@@ -0,0 +1,5 @@
+Leaf changes summary: 0 artifact changed (1 filtered out)
+Changed leaf types summary: 0 (1 filtered out) 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
+
new file mode 100644
@@ -0,0 +1,9 @@
+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-PR25661-5-v0.c:3:1' changed:
+ type size hasn't changed
+ data members 'S::a', 'S::b' were replaced by anonymous data member:
+ 'struct {union {int a; char a_1;}; union {int b; char b_1;};}'
new file mode 100644
@@ -0,0 +1,14 @@
+#include <inttypes.h>
+
+struct S
+{
+ int a;
+ int b;
+ int c;
+};// end struct S
+
+void
+func(struct S *s)
+{
+ s->a = 1;
+}
new file mode 100644
GIT binary patch
literal 3152
zcmbtW&2Jl35TCc}jkn#zI5CKZaM&VH8x*fUplMo^5{N=mQ9+a{;sjxBuk8hU4eL!6
zKnTQ_sJH}yL_tUh_1rsmgy6sdiN67fE4NBLz|7lu&ib)P2%h9OGr#$K^FG$^Y+ZfE
z5CYT?a0!kjg#sKEkNFMBZa@VVU~l`zZ`(KCzO((w)}0@v=h2Jb|AYnwX=KY-vy#tD
z_hooP*d!T-%wQB!Vy8sRq&ka;S+K$=0mGJ(k?IQ9U{;v+m#DXV5LWR8GPPPDW+Yp%
z+8~OOwLwM`&SZhA4)OI5=u{koaLU9PpZ3AF2NX%ni$_Wo$1E+C=EXv>d_QU*2FJOC
z5SGL&E}>AtG92fk^MrH35f!Xq4oo{0uT<6?fEiCbxoDPB=*%L8+c@>b(~D$Wv@*uV
zDFFK(OmYP^utEh<DIgmqIhs`Q6M&g#k(%%*&O+QR&EYKf7Z)uc3C2lvXSaE7b+u7F
zSG`{M+S1Dsa3ak?&W^C`_bu^_VWRW6KZ+CgAR33gDCoGf15-k+KN<$L&ZzTBSnGvJ
zZ4kEnR@n2yL5&mDDC@Y^@e^ON)lS&$R=eRK31S$GqTY1$yc#DN+kHO<IY~#Vh6|J6
z<>&U?&Bl4RQTOUz!)?}^_4;GYHTUc;mcH#Ltf->0vFuid$w3sX_kt*h!#0Y3-0rU*
zuB}#AA9t%g=pICENY_t^;PU3?MfWV`SpIhju$TAB_G0Vb+y!x17E7~5`v|w<LB#1t
zLvG|#rSeC{=G@E<8l-UUOh>l>fBc!J#NEn+@i0ubc1mxeCU2O0d3Bwc-X9&tD4EA0
zqc!0~MmlCqz{`*`Oqk0-=`iC>%NZv8?O~C<T*&lca!K+|mE7MnuzVSiJ&8ZXlSXAA
zoK|z2KpgWak@keY&a%p<>|MqenbHnrcVn4xvd`{&J%dyH4_Q91;Vj~-oeq_k9u68?
zDVfx{&+=6b|CZ%z8m?ODYxqr;`x^ck%U@~uU6xfIy$`DARKLZxM9R$T_80yEcNwQ1
zXZsA^_>E!Ww~!`rO8bgSg2MzndY-^*jmO}{!NB)ALF=HmA4c5~>Ll;CT5)iFO6|vf
z)C;Cv24NH^7fb<Odo&yd_<nfNC<#1#KC0uyZ@<ccg8qIt_J;u%{y)hQ`ctn|KUKI5
zX4LsqIN4^$X%q<4UxvM`QHIz3&!CRZ@qhJipsya2(y9DElaLv@?F#DXug6BlhS>B!
z1HilNK<A3=)SbgGt{m$)>oG}jn!)#^)$yd;?x0G?$odw8>Rzh|x-EUY^XmVYH&ppk
z{q*YU^>+}{V<H5<GWa|RnW5X#`;eFaJI=5AMEU7m((}KD7{yd|A}hy3d>Kz_36-em
zTWFo<zrqKq$?+6Xeu{p;{z|XtOZtIih4NE&^goiYskZ~=m)U<!88TJtSMcY^<n`~D
zoc_^QP5G<7=H;f?H#z?f7fjzD`daG#v?qB>{hf-!@jyx@v%Y?co9oZ@-<o))jPCyz
DJ2>rX
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,25 @@
+#include <inttypes.h>
+
+struct S
+{
+ struct
+ {
+ union
+ {
+ int a;
+ char a_1;
+ };
+ union
+ {
+ int b;
+ char b_1;
+ };
+ };
+ int c;
+}; // end struct S
+
+void
+func(struct S *s)
+{
+ s->a = 1;
+}
new file mode 100644
GIT binary patch
literal 3280
zcmbtW-HRJl6hC(+vzhE<)9gmuT~}}frCo6*AKGnN*&1EeZn4;~W${UtNis=BlZj+z
z%c_WqQY;Eq5JV6~eDOiw`>YTC55CwJ@!7XRAM~6%_hu)zQxH9nx##@O=RNl;@9kW9
zNn;EoF}MiFl0*T@<}u&mYzr!|0{go+|Jc3x?%mx_cJBVlJ#W4CO9><7xRJ?Y6_0%r
z?%@=mF&<je@&szRWH6I~EpSjXXwY*;5XPXHT+$L<F30l5r>HeNU<K<{&K=Z&Ef#%p
zLVeNrk<bpXQljsW{zRf*FqxtMjQaeD%<~i~2j(>>GTr>05ORh>7uZUkqMNWt06RHr
zlbj9v+Ct2VP*)~S`+NvRlVSr~W>1zXmR?#fEn}SWDbzjzmUR&!oS0y-5xG;$vMyN9
zS?4WQ!J?NyHxuzPiVKxFZGH(ZSDF^qRKa4?eucCjSuDEj`8B<iggU)OMYLAGd~uDE
zSVk&|whB-@fu&JCcp85iO#r8zCOPFaM*Pe8)8Q%nGIp=DgkQe5uo(<uKZ>39UgPZM
zX5BgKT(7%bash)uA<2P)ev%pHhX(sr)6qE^PNuPa7)HS$^m{g~{+v)9PR4$<H|f0|
zR0ly^9R(e)6AZjyR27M;lr^gMyx8Nc(+m22ryq=Bf0|j*EPi+BO@V(#lW@Rub7p2h
z)ri8l*`-(Z?d|$GyIyl^ZryIw8nxOpji!BO4@=+mVxe$QS>LdoaeNs1TLVAzr$HA*
zZ`vJh9W^(d&1Y?A0R6+T3(5Q`5nS5dzF?oh92@^G0dFn9Lt<oa?*Th1v-M)$yoJm0
zDB|=Z;*0r0seD7*URr3QK>}xf(G`!!Uw>yQamBJ=+z_+nozv^6$s%1`9;!|UejBJT
zM&Xx5241)iBR~f{5E-PyQU*%)ct$fwhvI!G^>QWEhuJ~N+WmZulMr%dbhk*JG%^F>
zG@G9YL|RS;eispbAY_?O+S>wO6C<rqdNno#PWI__ucdH`9|`%Kf(sE}jf7-gx;%(>
zl3`ZoXF|TB;NJ=Pnu5z#dJ29+$U_DHK*)C#{GO2i6r<V)*>kF&KQF?r`~ds&55R4K
zQ;*Yq1~+<Z9D5xc<7qMuB^UcgF}QR^f!m29aHsyrb9;X0aBvWW{R!$g?{zv;|N5NT
zn|k5EpLZDrp)Xx91-RYGc<kdH;)avhckv2wqS))cAp-fsgZ|VT^T$#Y|38Lx^rha)
ze#%fS!N~n7ak5R*<0ufO-VFO`qZF_DpGF<+<NxYkM_)B2rIYzr6s02a2b2E#w8$w%
zAB#=(zHp#@MRxMc;j7DO3%_biQVaxmn_C@!RNFSHRE(@26Pr<<YZ*bcr3XB#{^b7{
zfb^&O>DE>2?;)nfL<p{m{8vdxk!nl#SXTa~xZ-7>C_mjxYW_D7qnNTzWI25!@-He0
zr6|XD&^pWi2eF|VBAy(ipBz6D{!%Z;-_#8$6w*)HeT58RqFf2X9pT@cAqgYrFX1nc
z$?9J_qkr_ONq^bbtlSiPm4YI*MZxs`&}*ss)0$*Wbtv}#BdAZ4I)93r=`ZU4KJARW
G>i-W$y!Chh
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
new file mode 100644
@@ -0,0 +1,5 @@
+Leaf changes summary: 0 artifact changed (1 filtered out)
+Changed leaf types summary: 0 (1 filtered out) 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
+
new file mode 100644
@@ -0,0 +1,12 @@
+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.c:11: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.c:1:1:
+ type size hasn't changed
+ data member 'S::a' was replaced by anonymous data member:
+ 'union {int a; char added;}'
+
new file mode 100644
@@ -0,0 +1,9 @@
+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.c:1:1' changed:
+ type size hasn't changed
+ data member 'S::a' was replaced by anonymous data member:
+ 'union {int a; char added;}'
new file mode 100644
@@ -0,0 +1,10 @@
+struct S
+{
+ int a;
+};
+
+void
+foo(struct S *s)
+{
+ s->a = 1;
+}
new file mode 100644
GIT binary patch
literal 2656
zcmbtV&ubGw6n>L!n$)#1Z4?dlu!7PS%%(p>Td78i+M;Nw7Q9H=B->=QNlLOURS^%0
zP`p$SR1g%ri2sHMJ^45E;$3eA5BlEhOgfovDd>aDy!XBLz4vBzX7c3n^(zs^KnjEN
zuxm*a;6rp*&vP{oDd>g8+07rbn~!&9UtHe#%9(e+tfRk!$HaN6J^7AuXD~!=K?h@(
z&@dce1}Vtyh<Y_2qRaI<uo#DMkTmwLiB@M5U8F=_Rv;G7P!#K7XA&vXNc1IoSZ^$O
z9K9)K#7%R`JZG{L7U>2fPR3kn!o)(S!8FgCMjRk&vkU3K*PkYK{>1A`Y2tK7Tb#%V
zfY=e_%pneEsXEmK<SQZ@RUocT;urx7N5+09x^d(?kNd;Gcbk4@eaJ5INazakqLF_3
zJ`%yu-GFSRUUjpjdg-2*Eqi`;#Va@kuk3g$+4+T$@my{=yV{`eCS1L-Xw6t-_Jlod
zjSLNs59LNit$_u%WX(E$fM-T02dzxiU#q#(Ww+)wyds)Tqga{Vn8;;vV^*dNaCK&8
z${N6Qg9m4$704}M4;O%KBw63#SbPf?dJ=u~BjGU@6Upb1neNV;7!bgrBb}iR`1L2u
zX@s6w{MO>*=o|w*VPc3=tNRS-)FEyg&^nrJegnGNY-t#PCoV(`=ng@t|HMA{;XOEI
z?p5|d?!R)b=rXldatPzqRmqHmQ}^TeBk2hykhn16n1+*|Bppn=lhzSNY*647r+(-8
zed1+r6t6rzklZJpUw`z`IZ^9cBAzf62fO*8>N^FT{YEfXq~^ODKG-G4cfc+*n_xHG
z6~`{Qg|+gMS6i;5kLymM&~Vq=+)l%(mECsAidS<b1xtWktXHcpK5urd?z=YLsZ7&%
ziuXk#x3aX{aH_6o{6D8Y<kOzW{gmnQLTQ~7VN<Lsr_dlwzcIJfAVt^t{ph3b{jdCC
z<mx%8oUH$l3`O)<dZOvSD6hnj`cpLYN#Jy@C{CVDeCN4L<EZB($9L`pz$?`zdMur9
z9V5cD0EgPxdt<MmKdk>Z!5=J0KJ`zpk=}m^v9S780n++Z(PNj;8CL(Bs4w@4>eIWS
z*Iz}9a>_nY<?>k+dMp7k%ldMDgm@UgUtDJU0RA(<*TP`2?J?N(%DNJHEBJc&9RW<p
zKrzepOZXKkVf(iovVZj2OTOG!>PN3lxwiy3FB+zIn*K#}K7AAY?jZ!*0z5*7BKrC%
QZy0|^^#4)elB)Cn0^_%<SpWb4
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,14 @@
+struct S
+{
+ union
+ {
+ int a;
+ char added;
+ };
+};
+
+void
+foo(struct S *s)
+{
+ s->a = 1;
+}
new file mode 100644
GIT binary patch
literal 2792
zcmbtV&2Jk;6o2FOSF*L6#8hn*4vPe8BGv08Z7jD{T0>Oo0xD_RN?fXF?cLZ5u^p|q
zRRAF>wL(N(Kp+qw5(n;xD`yV;3;Y8}oRGLh;?TY~JI@|ZSE>Xf?Y#GX?{hxh?8n#M
zdOafq@DOkXCK96n%lQf4lx!0!umE>kM}M}CK00oFcJ26g>3Q$BuTh_sHboignRqWq
zWin;5!g>Q)%L9=kMtX|;EmG&Qxo{9eUdZf)+mIC^M7&rfEzIl<hahap<HTXb4_~4*
zJ3<vPnJ;=^7vCW(F)v;zS8S`iRGt?Lg}KwHJuPhel6~106)d6zR*{4oC}dG6vygik
zZ2O9B6#?>!EdvxP!YWSOizT>GX<$7wuDH6GL^``jnVM(5d2Nw0%;v@!GG_qnlNgqg
z!8xjwY6MK74PKN6N%k_%8E|kG;@@%!XL*Xa*8<{T6jvXtxgBW<Gf7+&EL%MKF_S@K
z&-Vi#uHU@tY&jR)hP&acudZ#Z*4NKF%R7PZw7fXMtLHDSIMsf9e-LbTgFz659TdH&
z)7w03)T{LiPPMBg?DV_{YQ14UsQE+x-LTdT<Jx}M_S#|B3-@c=JL?<u`daNEq9R8C
z*SEGVIm=kc%Jb{M74UY54|YHt&WWWHh2rP9=oe8(9}Q{qYI*LH%vLG?HX0;w>P&Yt
z3;#SxQ(CE=fV-#;%Ji{NlQt~X4W`Zlt*JDn1qDr-uolcr1dX#`+yWX(b(W@N7A(N4
zn=&jo@eE3l7qorg{nw71nsB_5S+v(z#Ssao>RC6BJPpQgCL)|tl<|8?UR0FMYkZxN
zUr{*O>*st`!}VReW8m^xK<q%_W_+%f;^&kNkvYYi_Q}IUO*mbrqwJ}6y?$^<@AqS`
zjWmuD+G8#b4r6eAFZRG~k4E4|!M^AELHmApHyrE@Q73t?-Hw6>Q)(~r2HjxVWj`DQ
z?1Cx4?F{?<0H0TPFpL8iTd+Ecz0P|oP|(}mi@biI3jd#E3H@nLct1H@Q!(RvrDU?z
z$4e*>W_B2#r*2EU>3<e6x*z}5e=Q{@LcsaIBS9NxetO>N&(_pzh;1c5O87(Jbgu~F
zyNv$`IW}=NW0K-;sRj66Q6{GCHY!YvY>yPU%8rVfwr?VyR==Z~g8iv}dcDm0eZ<U|
z2*Ixk<bEZLhH1NtSX%yVm7n*C@>9Q?`43b~t`kK$j#Z*h8Bmn-GyM>8;!XdDs+ryA
z_&-+uh8g@k^%zXFoR^VrmA`5Jivk*Ks3@<W;jfTM+rM7Q{?Xro{dr%h9y2$^{!4+|
qs$hE8>91q@)0vpPhY&QVC>$pfGM>%#Q`|KFhpPUc#-0gd`acEuEVPsW
literal 0
HcmV?d00001
@@ -570,6 +570,174 @@ InOutSpec in_out_specs[] =
"data/test-diff-filter/PR24787-report-0.txt",
"output/test-diff-filter/PR24787-report-0.txt",
},
+ {
+ "data/test-diff-filter/test-PR25661-1-v0.o",
+ "data/test-diff-filter/test-PR25661-1-v1.o",
+ "--no-default-suppression",
+ "data/test-diff-filter/test-PR25661-1-report-1.txt",
+ "output/test-diff-filter/test-PR25661-1-report-1.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-1-v0.o",
+ "data/test-diff-filter/test-PR25661-1-v1.o",
+ "--no-default-suppression --harmless",
+ "data/test-diff-filter/test-PR25661-1-report-2.txt",
+ "output/test-diff-filter/test-PR25661-1-report-2.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-1-v0.o",
+ "data/test-diff-filter/test-PR25661-1-v1.o",
+ "--no-default-suppression --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-1-report-3.txt",
+ "output/test-diff-filter/test-PR25661-1-report-3.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-1-v0.o",
+ "data/test-diff-filter/test-PR25661-1-v1.o",
+ "--no-default-suppression --harmless --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-1-report-4.txt",
+ "output/test-diff-filter/test-PR25661-1-report-4.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-2-v0.o",
+ "data/test-diff-filter/test-PR25661-2-v1.o",
+ "--no-default-suppression",
+ "data/test-diff-filter/test-PR25661-2-report-1.txt",
+ "output/test-diff-filter/test-PR25661-2-report-1.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-2-v0.o",
+ "data/test-diff-filter/test-PR25661-2-v1.o",
+ "--no-default-suppression --harmless",
+ "data/test-diff-filter/test-PR25661-2-report-2.txt",
+ "output/test-diff-filter/test-PR25661-2-report-2.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-2-v0.o",
+ "data/test-diff-filter/test-PR25661-2-v1.o",
+ "--no-default-suppression --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-2-report-3.txt",
+ "output/test-diff-filter/test-PR25661-2-report-3.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-2-v0.o",
+ "data/test-diff-filter/test-PR25661-2-v1.o",
+ "--no-default-suppression --harmless --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-2-report-4.txt",
+ "output/test-diff-filter/test-PR25661-2-report-4.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-3-v0.o",
+ "data/test-diff-filter/test-PR25661-3-v1.o",
+ "--no-default-suppression",
+ "data/test-diff-filter/test-PR25661-3-report-1.txt",
+ "output/test-diff-filter/test-PR25661-3-report-1.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-3-v0.o",
+ "data/test-diff-filter/test-PR25661-3-v1.o",
+ "--no-default-suppression --harmless",
+ "data/test-diff-filter/test-PR25661-3-report-2.txt",
+ "output/test-diff-filter/test-PR25661-3-report-2.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-3-v0.o",
+ "data/test-diff-filter/test-PR25661-3-v1.o",
+ "--no-default-suppression --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-3-report-3.txt",
+ "output/test-diff-filter/test-PR25661-3-report-3.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-3-v0.o",
+ "data/test-diff-filter/test-PR25661-3-v1.o",
+ "--no-default-suppression --harmless --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-3-report-4.txt",
+ "output/test-diff-filter/test-PR25661-3-report-4.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-4-v0.o",
+ "data/test-diff-filter/test-PR25661-4-v1.o",
+ "--no-default-suppression",
+ "data/test-diff-filter/test-PR25661-4-report-1.txt",
+ "output/test-diff-filter/test-PR25661-4-report-1.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-4-v0.o",
+ "data/test-diff-filter/test-PR25661-4-v1.o",
+ "--no-default-suppression --harmless",
+ "data/test-diff-filter/test-PR25661-4-report-2.txt",
+ "output/test-diff-filter/test-PR25661-4-report-2.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-4-v0.o",
+ "data/test-diff-filter/test-PR25661-4-v1.o",
+ "--no-default-suppression --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-4-report-3.txt",
+ "output/test-diff-filter/test-PR25661-4-report-3.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-4-v0.o",
+ "data/test-diff-filter/test-PR25661-4-v1.o",
+ "--no-default-suppression --harmless --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-4-report-4.txt",
+ "output/test-diff-filter/test-PR25661-4-report-4.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-5-v0.o",
+ "data/test-diff-filter/test-PR25661-5-v1.o",
+ "--no-default-suppression",
+ "data/test-diff-filter/test-PR25661-5-report-1.txt",
+ "output/test-diff-filter/test-PR25661-5-report-1.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-5-v0.o",
+ "data/test-diff-filter/test-PR25661-5-v1.o",
+ "--no-default-suppression --harmless",
+ "data/test-diff-filter/test-PR25661-5-report-2.txt",
+ "output/test-diff-filter/test-PR25661-5-report-2.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-5-v0.o",
+ "data/test-diff-filter/test-PR25661-5-v1.o",
+ "--no-default-suppression --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-5-report-3.txt",
+ "output/test-diff-filter/test-PR25661-5-report-3.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-5-v0.o",
+ "data/test-diff-filter/test-PR25661-5-v1.o",
+ "--no-default-suppression --harmless --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-5-report-4.txt",
+ "output/test-diff-filter/test-PR25661-5-report-4.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-6-v0.o",
+ "data/test-diff-filter/test-PR25661-6-v1.o",
+ "--no-default-suppression",
+ "data/test-diff-filter/test-PR25661-6-report-1.txt",
+ "output/test-diff-filter/test-PR25661-6-report-1.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-6-v0.o",
+ "data/test-diff-filter/test-PR25661-6-v1.o",
+ "--no-default-suppression --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-6-report-2.txt",
+ "output/test-diff-filter/test-PR25661-6-report-2.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-6-v0.o",
+ "data/test-diff-filter/test-PR25661-6-v1.o",
+ "--no-default-suppression --harmless",
+ "data/test-diff-filter/test-PR25661-6-report-3.txt",
+ "output/test-diff-filter/test-PR25661-6-report-3.txt",
+ },
+ {
+ "data/test-diff-filter/test-PR25661-6-v0.o",
+ "data/test-diff-filter/test-PR25661-6-v1.o",
+ "--no-default-suppression --harmless --leaf-changes-only",
+ "data/test-diff-filter/test-PR25661-6-report-4.txt",
+ "output/test-diff-filter/test-PR25661-6-report-4.txt",
+ },
// This should be the last entry
{NULL, NULL, NULL, NULL, NULL}
};