@@ -17,6 +17,7 @@
#include "abg-corpus.h"
#include "abg-diff-utils.h"
#include "abg-reporter.h"
+#include "abg-suppression.h"
namespace abigail
{
@@ -46,14 +47,6 @@ using diff_utils::insertion;
using diff_utils::deletion;
using diff_utils::edit_script;
-class diff;
-
-/// Convenience typedef for a shared_ptr for the @ref diff class
-typedef shared_ptr<diff> diff_sptr;
-
-/// Convenience typedef for a weak_ptr for the @ref diff class
-typedef weak_ptr<diff> diff_wptr;
-
/// Hasher for @ref diff_sptr.
struct diff_sptr_hasher
{
@@ -261,14 +254,6 @@ typedef unordered_map<string, elf_symbol_sptr> string_elf_symbol_map;
/// value is a @ref var_diff_sptr.
typedef unordered_map<string, var_diff_sptr> string_var_diff_ptr_map;
-class diff_context;
-
-/// Convenience typedef for a shared pointer of @ref diff_context.
-typedef shared_ptr<diff_context> diff_context_sptr;
-
-/// Convenience typedef for a weak pointer of @ref diff_context.
-typedef weak_ptr<diff_context> diff_context_wptr;
-
class diff_node_visitor;
class diff_traversable_base;
@@ -438,6 +423,25 @@ enum diff_category
/// variable didn't change.
BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY = 1 << 21,
+ /// A diff node in this category carries a change that must be
+ /// reported, even if the diff node is also in the
+ /// SUPPRESSED_CATEGORY or PRIVATE_TYPE_CATEGORY categories.
+ /// Typically, this node matches a suppression specification like
+ /// the [allow_type] directive.
+ HAS_ALLOWED_CHANGE_CATEGORY = 1 << 22,
+
+ /// A diff node in this category has a descendant node that is in
+ /// the HAS_ALLOWED_CHANGE_CATEGORY category. Nodes in this
+ /// category must be reported, even if they are also in the
+ /// SUPPRESSED_CATEGORY or PRIVATE_TYPE_CATEGORY categories.
+ HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY = 1 << 23,
+
+ /// A diff node in this category has a parent node that is in the
+ /// HAS_ALLOWED_CHANGE_CATEGORY category. Nodes in this category
+ /// must be reported, even if they are also in the
+ /// SUPPRESSED_CATEGORY or PRIVATE_TYPE_CATEGORY categories.
+ HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY = 1 << 24,
+
/// A special enumerator that is the logical 'or' all the
/// enumerators above.
///
@@ -466,6 +470,9 @@ enum diff_category
| VAR_TYPE_CV_CHANGE_CATEGORY
| VOID_PTR_TO_PTR_CHANGE_CATEGORY
| BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY
+ | HAS_ALLOWED_CHANGE_CATEGORY
+ | HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY
+ | HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY
}; // enum diff_category
diff_category
@@ -730,9 +737,18 @@ public:
void
maybe_apply_filters(corpus_diff_sptr diff);
- suppr::suppressions_type&
+ const suppr::suppressions_type&
suppressions() const;
+ suppr::suppressions_type&
+ suppressions();
+
+ const suppr::suppressions_type&
+ negated_suppressions() const;
+
+ const suppr::suppressions_type&
+ direct_suppressions() const;
+
void
add_suppression(const suppr::suppression_sptr suppr);
@@ -1037,6 +1053,9 @@ public:
bool
is_filtered_out_wrt_non_inherited_categories() const;
+ bool
+ is_filtered_out_without_looking_at_allowed_changes() const;
+
bool
is_suppressed() const;
@@ -1049,6 +1068,15 @@ public:
bool
has_local_changes_to_be_reported() const;
+ bool
+ is_allowed_by_specific_negated_suppression() const;
+
+ bool
+ has_descendant_allowed_by_specific_negated_suppression() const;
+
+ bool
+ has_parent_allowed_by_specific_negated_suppression() const;
+
virtual const string&
get_pretty_representation() const;
@@ -36,11 +36,17 @@ using std::vector;
using comparison::diff;
using comparison::diff_context_sptr;
-/// Base type of the suppression specifications types.
+/// Base type of a direct suppression specifications types.
///
/// This abstracts a suppression specification. It's a way to specify
/// how to drop reports about a particular diff node on the floor, if
/// it matches the supppression specification.
+///
+/// Note that a direct suppression specification suppresses (for
+/// reporting purposes) the diff node that it matches. A negated
+/// suppression specification, however, suppresses a diff node that it
+/// DOES NOT match. A Negated suppression specification is abstracted
+/// by the class @ref negated_suppression_base.
class suppression_base
{
public:
@@ -143,6 +149,36 @@ typedef shared_ptr<type_suppression> type_suppression_sptr;
/// Convenience typedef for vector of @ref type_suppression_sptr.
typedef vector<type_suppression_sptr> type_suppressions_type;
+/// The base class of suppression specifications that are defined by
+/// the negation of matching clauses.
+///
+/// A direct suppression specification suppresses (for reporting
+/// purposes) the diff node that it matches. A negated suppression
+/// specification suppresses a diff node that it DOES NOT match.
+class negated_suppression_base
+{
+public:
+ negated_suppression_base();
+
+ virtual ~negated_suppression_base();
+}; // end class negated_suppression_base.
+
+/// A convenience typedef for a shared pointer to @ref
+/// negated_suppression_base.
+typedef shared_ptr<negated_suppression_base> negated_suppression_sptr;
+
+/// Convenience typedef for a vector of @ref negated_suppression_sptr
+typedef vector<negated_suppression_sptr> negated_suppressions_type;
+
+bool
+is_negated_suppression(const suppression_base&);
+
+const negated_suppression_base*
+is_negated_suppression(const suppression_base*);
+
+negated_suppression_sptr
+is_negated_suppression(const suppression_sptr&);
+
/// Abstraction of a type suppression specification.
///
/// Specifies under which condition reports about a type diff node
@@ -416,6 +452,37 @@ public:
~fn_call_expr_boundary();
}; //end class type_suppression::insertion_range::fn_call_expr_boundary
+/// Abstraction of a negated type suppression specification.
+///
+/// A negated type suppression suppresses a type if the negation of
+/// the equivalent propositions for a @ref type_suppression are valid.
+class negated_type_suppression : virtual public type_suppression,
+ virtual public negated_suppression_base
+{
+
+public:
+
+ negated_type_suppression(const string& label,
+ const string& type_name_regexp,
+ const string& type_name);
+
+ virtual bool
+ suppresses_diff(const diff* diff) const;
+
+ bool
+ suppresses_type(const type_base_sptr& type,
+ const diff_context_sptr& ctxt) const;
+
+ bool
+ suppresses_type(const type_base_sptr& type) const;
+
+ bool
+ suppresses_type(const type_base_sptr& type,
+ const scope_decl* type_scope) const;
+
+ virtual ~negated_type_suppression();
+};// end class negated_type_suppression
+
class function_suppression;
/// Convenience typedef for a shared pointer to function_suppression.
@@ -174,7 +174,17 @@ struct diff_context::priv
unordered_diff_sptr_set live_diffs_;
vector<diff_sptr> canonical_diffs;
vector<filtering::filter_base_sptr> filters_;
+ // All the suppressions specifications are stored in this data
+ // member.
suppressions_type suppressions_;
+ // The negated suppressions specifications that are in
+ // suppressions_ are stored here. Each time suppressions_ is
+ // modified, this data member should be cleared.
+ suppressions_type negated_suppressions_;
+ // The non-negated suppressions specifications that are in
+ // suppressions_ are stored here. Each time suppressions_ is
+ // modified, this data member should be cleared.
+ suppressions_type direct_suppressions_;
pointer_map visited_diff_nodes_;
corpus_diff_sptr corpus_diff_;
ostream* default_output_stream_;
@@ -304,6 +314,13 @@ public:
if (ctxt->get_allowed_category() == EVERYTHING_CATEGORY)
return false;
+ // If this node is on the path of a node that *must* be reported,
+ // then do not filter it.
+ if (category & (HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY
+ | HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY
+ | HAS_ALLOWED_CHANGE_CATEGORY))
+ return false;
+
/// We don't want to display nodes suppressed by a user-provided
/// suppression specification or by a "private type" suppression
/// specification.
@@ -1399,10 +1399,72 @@ diff_context::maybe_apply_filters(corpus_diff_sptr diff)
/// reports should be dropped on the floor.
///
/// @return the set of suppressions.
-suppressions_type&
+const suppressions_type&
diff_context::suppressions() const
{return priv_->suppressions_;}
+/// Getter for the vector of suppressions that specify which diff node
+/// reports should be dropped on the floor.
+///
+/// @return the set of suppressions.
+suppr::suppressions_type&
+diff_context::suppressions()
+{
+ // Invalidate negated and direct suppressions caches that are built
+ // from priv_->suppressions_;
+ priv_->negated_suppressions_.clear();
+ priv_->direct_suppressions_.clear();
+ return priv_->suppressions_;
+}
+
+/// Getter of the negated suppression specifications that are
+/// comprised in the general vector of suppression specifications
+/// returned by diff_context::suppressions().
+///
+/// Note that the first invocation of this function scans the vector
+/// returned by diff_context::suppressions() and caches the negated
+/// suppressions from there.
+///
+/// Subsequent invocations of this function just return the cached
+/// negated suppressions.
+///
+/// @return the negated suppression specifications stored in this diff
+/// context.
+const suppr::suppressions_type&
+diff_context::negated_suppressions() const
+{
+ if (priv_->negated_suppressions_.empty())
+ for (auto s : suppressions())
+ if (is_negated_suppression(s))
+ priv_->negated_suppressions_.push_back(s);
+
+ return priv_->negated_suppressions_;
+}
+
+/// Getter of the direct suppression specification (those that are
+/// not negated) comprised in the general vector of suppression
+/// specifications returned by diff_context::suppression().
+///
+/// Note that the first invocation of this function scans the vector
+/// returned by diff_context::suppressions() and caches the direct
+/// suppressions from there.
+///
+/// Subsequent invocations of this function just return the cached
+/// direct suppressions.
+///
+/// @return the direct suppression specifications.
+const suppr::suppressions_type&
+diff_context::direct_suppressions() const
+{
+ if (priv_->direct_suppressions_.empty())
+ {
+ for (auto s : suppressions())
+ if (!is_negated_suppression(s))
+ priv_->direct_suppressions_.push_back(s);
+ }
+ return priv_->direct_suppressions_;
+}
+
/// Add a new suppression specification that specifies which diff node
/// reports should be dropped on the floor.
///
@@ -1410,7 +1472,13 @@ diff_context::suppressions() const
/// existing set of suppressions specifications of the diff context.
void
diff_context::add_suppression(const suppression_sptr suppr)
-{priv_->suppressions_.push_back(suppr);}
+{
+ priv_->suppressions_.push_back(suppr);
+ // Invalidate negated and direct suppressions caches that are built
+ // from priv_->suppressions_;
+ priv_->negated_suppressions_.clear();
+ priv_->direct_suppressions_.clear();
+}
/// Add new suppression specifications that specify which diff node
/// reports should be dropped on the floor.
@@ -2313,6 +2381,16 @@ diff::set_local_category(diff_category c)
/// Test if this diff tree node is to be filtered out for reporting
/// purposes.
///
+/// There is a difference between a diff node being filtered out and
+/// being suppressed. Being suppressed means that there is a
+/// suppression specification that suppresses the diff node
+/// specifically. Being filtered out mean the node is either
+/// suppressed, or it's filtered out because the suppression of a set
+/// of (children) nodes caused this node to be filtered out as well.
+/// For instance, if a function diff has all its children diff nodes
+/// suppressed and if the function diff node carries no local change,
+/// then the function diff node itself is going to be filtered out.
+///
/// The function tests if the categories of the diff tree node are
/// "forbidden" by the context or not.
///
@@ -2321,13 +2399,16 @@ bool
diff::is_filtered_out() const
{
if (diff * canonical = get_canonical_diff())
- if (canonical->get_category() & SUPPRESSED_CATEGORY
- || canonical->get_category() & PRIVATE_TYPE_CATEGORY)
+ if ((canonical->get_category() & SUPPRESSED_CATEGORY
+ || canonical->get_category() & PRIVATE_TYPE_CATEGORY)
+ && !canonical->is_allowed_by_specific_negated_suppression()
+ && !canonical->has_descendant_allowed_by_specific_negated_suppression()
+ && !canonical->has_parent_allowed_by_specific_negated_suppression())
// The canonical type was suppressed either by a user-provided
// suppression specification or by a "private-type" suppression
- // specification.. This means all the class of equivalence of
- // that canonical type was suppressed. So this node should be
- // suppressed too.
+ // specification.. This means all the classes of equivalence of
+ // that canonical type were suppressed. So this node should be
+ // filtered out.
return true;
return priv_->is_filtered_out(get_category());
}
@@ -2345,6 +2426,27 @@ bool
diff::is_filtered_out_wrt_non_inherited_categories() const
{return priv_->is_filtered_out(get_local_category());}
+/// Test if this diff tree node is to be filtered out for reporting
+/// purposes, but without considering the categories that can /force/
+/// the node to be unfiltered.
+///
+/// The function tests if the categories of the diff tree node are
+/// "forbidden" by the context or not.
+///
+/// @return true iff the current diff node should should NOT be
+/// reported, with respect to the categories that might filter it out
+/// only.
+bool
+diff::is_filtered_out_without_looking_at_allowed_changes() const
+{
+ diff_category c = get_category();
+ c &= ~(HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY
+ | HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY
+ | HAS_ALLOWED_CHANGE_CATEGORY);
+
+ return priv_->is_filtered_out(c);
+}
+
/// Test if the current diff node has been suppressed by a
/// user-provided suppression specification.
///
@@ -2364,6 +2466,13 @@ diff::is_suppressed() const
/// Note that private type suppressions are auto-generated from the
/// path to where public headers are, as given by the user.
///
+/// Here is the current algorithm:
+///
+/// First, suppress this diff node if it's not matched by any
+/// negated suppression specifications. If it's not
+/// suppressed, then suppress it if it's matched by direct
+/// suppression specifications.
+///
/// @param is_private_type out parameter if the current diff node was
/// suppressed because it's a private type then this parameter is set
/// to true.
@@ -2373,19 +2482,32 @@ diff::is_suppressed() const
bool
diff::is_suppressed(bool &is_private_type) const
{
- const suppressions_type& suppressions = context()->suppressions();
- for (suppressions_type::const_iterator i = suppressions.begin();
- i != suppressions.end();
- ++i)
- {
- if ((*i)->suppresses_diff(this))
- {
- if (is_private_type_suppr_spec(*i))
- is_private_type = true;
- return true;
- }
- }
- return false;
+ // If there is at least one negated suppression, then suppress the
+ // current diff node by default ...
+ bool do_suppress = !context()->negated_suppressions().empty();
+
+ // ... unless there is at least one negated suppression that
+ // specifically asks to keep this diff node around (un-suppressed).
+ for (auto n : context()->negated_suppressions())
+ if (!n->suppresses_diff(this))
+ {
+ do_suppress = false;
+ break;
+ }
+
+ // Then walk the set of non-negated, AKA direct, suppressions. If at
+ // least one suppression suppresses the current diff node then the
+ // diff node must be suppressed.
+ for (auto d : context()->direct_suppressions())
+ if (d->suppresses_diff(this))
+ {
+ do_suppress = true;
+ if (is_private_type_suppr_spec(d))
+ is_private_type = true;
+ break;
+ }
+
+ return do_suppress;
}
/// Test if this diff tree node should be reported.
@@ -2412,6 +2534,51 @@ diff::has_local_changes_to_be_reported() const
return false;
}
+/// Test if this diff node is allowed (prevented from being
+/// suppressed) by at least one negated suppression specification.
+///
+/// @return true if this diff node is meant to be allowed by at least
+/// one negated suppression specification.
+bool
+diff::is_allowed_by_specific_negated_suppression() const
+{
+ const suppressions_type& suppressions = context()->suppressions();
+ for (suppressions_type::const_iterator i = suppressions.begin();
+ i != suppressions.end();
+ ++i)
+ {
+ if (is_negated_suppression(*i)
+ && !(*i)->suppresses_diff(this))
+ return true;
+ }
+ return false;
+}
+
+/// Test if the current diff node has a descendant node which is
+/// specifically allowed by a negated suppression specification.
+///
+/// @return true iff the current diff node has a descendant node
+/// which is specifically allowed by a negated suppression
+/// specification.
+bool
+diff::has_descendant_allowed_by_specific_negated_suppression() const
+{
+ bool result = (get_category() & HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY);
+ return result;
+}
+
+/// Test if the current diff node has a parent node which is
+/// specifically allowed by a negated suppression specification.
+///
+/// @return true iff the current diff node has a parent node which is
+/// specifically allowed by a negated suppression specification.
+bool
+diff::has_parent_allowed_by_specific_negated_suppression() const
+{
+ bool result = (get_category() & HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY);
+ return result;
+}
+
/// Get a pretty representation of the current @ref diff node.
///
/// This is suitable for e.g. emitting debugging traces for the diff
@@ -3075,6 +3242,30 @@ operator<<(ostream& o, diff_category c)
emitted_a_category |= true;
}
+ if (c & HAS_ALLOWED_CHANGE_CATEGORY)
+ {
+ if (emitted_a_category)
+ o << "|";
+ o << "HAS_ALLOWED_CHANGE_CATEGORY";
+ emitted_a_category |= true;
+ }
+
+ if (c & HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY)
+ {
+ if (emitted_a_category)
+ o << "|";
+ o << "HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY";
+ emitted_a_category |= true;
+ }
+
+ if (c & HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY)
+ {
+ if (emitted_a_category)
+ o << "|";
+ o << "HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY";
+ emitted_a_category |= true;
+ }
+
return o;
}
@@ -11385,7 +11576,10 @@ struct category_propagation_visitor : public diff_node_visitor
// are propagated in a specific pass elsewhere.
c &= ~(REDUNDANT_CATEGORY
| SUPPRESSED_CATEGORY
- | PRIVATE_TYPE_CATEGORY);
+ | PRIVATE_TYPE_CATEGORY
+ | HAS_ALLOWED_CHANGE_CATEGORY
+ | HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY
+ | HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY);
// Also, if a (class) type has got a harmful name change, do not
// propagate harmless name changes coming from its sub-types
// (i.e, data members) to the class itself.
@@ -11481,6 +11675,40 @@ struct suppression_categorization_visitor : public diff_node_visitor
if (canonical_diff != d)
canonical_diff->add_to_category(c);
}
+ else if (d->is_allowed_by_specific_negated_suppression())
+ {
+ // This diff node is specifically allowed by a
+ // negated_suppression, then mark it as being in the
+ // HAS_ALLOWED_CHANGE_CATEGORY.
+ diff_category c = HAS_ALLOWED_CHANGE_CATEGORY;
+ d->add_to_local_category(c);
+ diff *canonical_diff = d->get_canonical_diff();
+ canonical_diff->add_to_category(c);
+
+ // Note that some complementary code later down below does
+ // categorize the descendants and parents nodes of this node
+ // as HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY and
+ // HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY, repectively.
+ }
+
+ // If a parent node has been allowed by a negated suppression
+ // specification, then categorize the current node as
+ // HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY.
+ if (d->parent_node())
+ {
+ diff_category c = d->parent_node()->get_local_category();
+ if (c & (HAS_ALLOWED_CHANGE_CATEGORY
+ | HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY))
+ d->add_to_category(HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY);
+ else
+ {
+ c = d->parent_node()->get_category();
+ if (c & (HAS_ALLOWED_CHANGE_CATEGORY
+ | HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY))
+ d->add_to_category(HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY);
+ }
+ }
+
}
/// After visiting the children nodes of a given diff node,
@@ -11505,6 +11733,7 @@ struct suppression_categorization_visitor : public diff_node_visitor
bool has_suppressed_child = false;
bool has_non_private_child = false;
bool has_private_child = false;
+ bool has_descendant_with_allowed_change = false;
if (// A node to which we can propagate the "SUPPRESSED_CATEGORY"
// (or the PRIVATE_TYPE_CATEGORY for the same matter)
@@ -11670,6 +11899,24 @@ struct suppression_categorization_visitor : public diff_node_visitor
}
}
}
+
+ // If any descendant node was selected by a negated suppression
+ // specification then categorize the current one as
+ // HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY.
+ for (auto child_node : d->children_nodes())
+ {
+ diff *canonical_diff = child_node->get_canonical_diff();
+ diff_category c = canonical_diff->get_category();
+ if (c & (HAS_ALLOWED_CHANGE_CATEGORY
+ | HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY))
+ has_descendant_with_allowed_change = true;
+ }
+ if (has_descendant_with_allowed_change)
+ {
+ diff_category c = HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY;
+ d->add_to_category(c);
+ d->get_canonical_diff()->add_to_category(c);
+ }
}
}; //end struct suppression_categorization_visitor
@@ -272,7 +272,8 @@ default_reporter::report(const typedef_diff& d,
typedef_decl_sptr f = d.first_typedef_decl(), s = d.second_typedef_decl();
- report_non_type_typedef_changes(d, out, indent);
+ if (!d.is_filtered_out_without_looking_at_allowed_changes())
+ report_non_type_typedef_changes(d, out, indent);
diff_sptr dif = d.underlying_type_diff();
if (dif && dif->has_changes())
@@ -364,11 +365,12 @@ default_reporter::report(const qualified_type_diff& d, ostream& out,
RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER(d.first_qualified_type(),
d.second_qualified_type());
- if (report_local_qualified_type_changes(d, out, indent))
- // The local change was emitted and it's a name change. If the
- // type name changed, the it means the type changed altogether.
- // It makes a little sense to detail the changes in extenso here.
- return;
+ if (!d.is_filtered_out_without_looking_at_allowed_changes())
+ if (report_local_qualified_type_changes(d, out, indent))
+ // The local change was emitted and it's a name change. If the
+ // type name changed, the it means the type changed altogether.
+ // It makes a little sense to detail the changes in extenso here.
+ return;
diff_sptr dif = d.leaf_underlying_type_diff();
ABG_ASSERT(dif);
@@ -474,8 +476,9 @@ default_reporter::report(const reference_diff& d, ostream& out,
enum change_kind k = ir::NO_CHANGE_KIND;
equals(*d.first_reference(), *d.second_reference(), &k);
- if ((k & ALL_LOCAL_CHANGES_MASK) && !(k & SUBTYPE_CHANGE_KIND))
- report_local_reference_type_changes(d, out, indent);
+ if (!d.is_filtered_out_without_looking_at_allowed_changes())
+ if ((k & ALL_LOCAL_CHANGES_MASK) && !(k & SUBTYPE_CHANGE_KIND))
+ report_local_reference_type_changes(d, out, indent);
if (k & SUBTYPE_CHANGE_KIND)
if (diff_sptr dif = d.underlying_type_diff())
@@ -503,6 +506,9 @@ void
default_reporter::report(const fn_parm_diff& d, ostream& out,
const string& indent) const
{
+ if (!d.to_be_reported())
+ return;
+
function_decl::parameter_sptr f = d.first_parameter(),
s = d.second_parameter();
@@ -514,26 +520,23 @@ default_reporter::report(const fn_parm_diff& d, ostream& out,
type_has_sub_type_changes(d.first_parameter()->get_type(),
d.second_parameter()->get_type());
- if (d.to_be_reported())
- {
- diff_sptr type_diff = d.type_diff();
- ABG_ASSERT(type_diff->has_changes());
+ diff_sptr type_diff = d.type_diff();
+ ABG_ASSERT(type_diff->has_changes());
- out << indent;
- if (f->get_is_artificial())
- out << "implicit ";
- out << "parameter " << f->get_index();
- report_loc_info(f, *d.context(), out);
- out << " of type '"
- << f->get_type_pretty_representation();
-
- if (has_sub_type_change)
- out << "' has sub-type changes:\n";
- else
- out << "' changed:\n";
+ out << indent;
+ if (f->get_is_artificial())
+ out << "implicit ";
+ out << "parameter " << f->get_index();
+ report_loc_info(f, *d.context(), out);
+ out << " of type '"
+ << f->get_type_pretty_representation();
- type_diff->report(out, indent + " ");
- }
+ if (has_sub_type_change)
+ out << "' has sub-type changes:\n";
+ else
+ out << "' changed:\n";
+
+ type_diff->report(out, indent + " ");
}
/// For a @ref function_type_diff node, report the local changes
@@ -645,8 +648,8 @@ default_reporter::report(const function_type_diff& d, ostream& out,
dif->report(out, indent);
}
- report_local_function_type_changes(d, out, indent);
-
+ if (!d.is_filtered_out_without_looking_at_allowed_changes())
+ report_local_function_type_changes(d, out, indent);
}
/// Report a @ref array_diff in a serialized form.
@@ -678,10 +681,11 @@ default_reporter::report(const array_diff& d, ostream& out,
dif->report(out, indent + " ");
}
- report_name_size_and_alignment_changes(d.first_array(),
- d.second_array(),
- d.context(),
- out, indent);
+ if (!d.is_filtered_out_without_looking_at_allowed_changes())
+ report_name_size_and_alignment_changes(d.first_array(),
+ d.second_array(),
+ d.context(),
+ out, indent);
}
/// Generates a report for an intance of @ref base_diff.
@@ -702,30 +706,32 @@ default_reporter::report(const base_diff& d, ostream& out,
string repr = f->get_base_class()->get_pretty_representation();
bool emitted = false;
- if (f->get_is_static() != s->get_is_static())
+ if (!d.is_filtered_out_without_looking_at_allowed_changes())
{
- if (f->get_is_static())
- out << indent << "is no more static";
- else
- out << indent << "now becomes static";
- emitted = true;
- }
+ if (f->get_is_static() != s->get_is_static())
+ {
+ if (f->get_is_static())
+ out << indent << "is no more static";
+ else
+ out << indent << "now becomes static";
+ emitted = true;
+ }
- if ((d.context()->get_allowed_category() & ACCESS_CHANGE_CATEGORY)
- && (f->get_access_specifier() != s->get_access_specifier()))
- {
- if (emitted)
- out << ", ";
+ if ((d.context()->get_allowed_category() & ACCESS_CHANGE_CATEGORY)
+ && (f->get_access_specifier() != s->get_access_specifier()))
+ {
+ if (emitted)
+ out << ", ";
- out << "has access changed from '"
- << f->get_access_specifier()
- << "' to '"
- << s->get_access_specifier()
- << "'";
+ out << "has access changed from '"
+ << f->get_access_specifier()
+ << "' to '"
+ << s->get_access_specifier()
+ << "'";
- emitted = true;
+ emitted = true;
+ }
}
-
if (class_diff_sptr dif = d.get_underlying_class_diff())
{
if (dif->to_be_reported())
@@ -1493,135 +1499,138 @@ default_reporter::report(const function_decl_diff& d, ostream& out,
linkage_names2 =
s2->get_aliases_id_string(sc->get_fun_symbol_map());
- /// If the set of linkage names of the function have changed, report
- /// it.
- if (linkage_names1 != linkage_names2)
+ if (!d.is_filtered_out_without_looking_at_allowed_changes())
{
- if (linkage_names1.empty())
+ /// If the set of linkage names of the function have changed, report
+ /// it.
+ if (linkage_names1 != linkage_names2)
{
- out << indent << ff->get_pretty_representation()
- << " didn't have any linkage name, and it now has: '"
- << linkage_names2 << "'\n";
+ if (linkage_names1.empty())
+ {
+ out << indent << ff->get_pretty_representation()
+ << " didn't have any linkage name, and it now has: '"
+ << linkage_names2 << "'\n";
+ }
+ else if (linkage_names2.empty())
+ {
+ out << indent << ff->get_pretty_representation()
+ << " did have linkage names '" << linkage_names1
+ << "'\n"
+ << indent << "but it doesn't have any linkage name anymore\n";
+ }
+ else
+ out << indent << "linkage names of "
+ << ff->get_pretty_representation()
+ << "\n" << indent << "changed from '"
+ << linkage_names1 << "' to '" << linkage_names2 << "'\n";
}
- else if (linkage_names2.empty())
+
+ if (qn1 != qn2
+ && d.type_diff()
+ && d.type_diff()->to_be_reported())
{
- out << indent << ff->get_pretty_representation()
- << " did have linkage names '" << linkage_names1
- << "'\n"
- << indent << "but it doesn't have any linkage name anymore\n";
+ // So the function has sub-type changes that are to be
+ // reported. Let's see if the function name changed too; if it
+ // did, then we'd report that change right before reporting the
+ // sub-type changes.
+ string frep1 = d.first_function_decl()->get_pretty_representation(),
+ frep2 = d.second_function_decl()->get_pretty_representation();
+ out << indent << "'" << frep1 << " {" << linkage_names1<< "}"
+ << "' now becomes '"
+ << frep2 << " {" << linkage_names2 << "}" << "'\n";
}
- else
- out << indent << "linkage names of "
- << ff->get_pretty_representation()
- << "\n" << indent << "changed from '"
- << linkage_names1 << "' to '" << linkage_names2 << "'\n";
- }
- if (qn1 != qn2
- && d.type_diff()
- && d.type_diff()->to_be_reported())
- {
- // So the function has sub-type changes that are to be
- // reported. Let's see if the function name changed too; if it
- // did, then we'd report that change right before reporting the
- // sub-type changes.
- string frep1 = d.first_function_decl()->get_pretty_representation(),
- frep2 = d.second_function_decl()->get_pretty_representation();
- out << indent << "'" << frep1 << " {" << linkage_names1<< "}"
- << "' now becomes '"
- << frep2 << " {" << linkage_names2 << "}" << "'\n";
- }
-
- maybe_report_diff_for_symbol(ff->get_symbol(),
- sf->get_symbol(),
- d.context(), out, indent);
-
- // Now report about inline-ness changes
- if (ff->is_declared_inline() != sf->is_declared_inline())
- {
- out << indent;
- if (ff->is_declared_inline())
- out << sf->get_pretty_representation()
- << " is not declared inline anymore\n";
- else
- out << sf->get_pretty_representation()
- << " is now declared inline\n";
- }
+ maybe_report_diff_for_symbol(ff->get_symbol(),
+ sf->get_symbol(),
+ d.context(), out, indent);
- // Report about vtable offset changes.
- if (is_member_function(ff) && is_member_function(sf))
- {
- bool ff_is_virtual = get_member_function_is_virtual(ff),
- sf_is_virtual = get_member_function_is_virtual(sf);
- if (ff_is_virtual != sf_is_virtual)
+ // Now report about inline-ness changes
+ if (ff->is_declared_inline() != sf->is_declared_inline())
{
out << indent;
- if (ff_is_virtual)
- out << ff->get_pretty_representation()
- << " is no more declared virtual\n";
+ if (ff->is_declared_inline())
+ out << sf->get_pretty_representation()
+ << " is not declared inline anymore\n";
else
- out << ff->get_pretty_representation()
- << " is now declared virtual\n";
+ out << sf->get_pretty_representation()
+ << " is now declared inline\n";
}
- size_t ff_vtable_offset = get_member_function_vtable_offset(ff),
- sf_vtable_offset = get_member_function_vtable_offset(sf);
- if (ff_is_virtual && sf_is_virtual
- && (ff_vtable_offset != sf_vtable_offset))
+ // Report about vtable offset changes.
+ if (is_member_function(ff) && is_member_function(sf))
{
- out << indent
- << "the vtable offset of " << ff->get_pretty_representation()
- << " changed from " << ff_vtable_offset
- << " to " << sf_vtable_offset << "\n";
- }
+ bool ff_is_virtual = get_member_function_is_virtual(ff),
+ sf_is_virtual = get_member_function_is_virtual(sf);
+ if (ff_is_virtual != sf_is_virtual)
+ {
+ out << indent;
+ if (ff_is_virtual)
+ out << ff->get_pretty_representation()
+ << " is no more declared virtual\n";
+ else
+ out << ff->get_pretty_representation()
+ << " is now declared virtual\n";
+ }
- // the parent types (classe or union) of the two member
- // functions.
- class_or_union_sptr f =
- is_class_or_union_type(is_method_type(ff->get_type())->get_class_type());
- class_or_union_sptr s =
- is_class_or_union_type(is_method_type(sf->get_type())->get_class_type());
+ size_t ff_vtable_offset = get_member_function_vtable_offset(ff),
+ sf_vtable_offset = get_member_function_vtable_offset(sf);
+ if (ff_is_virtual && sf_is_virtual
+ && (ff_vtable_offset != sf_vtable_offset))
+ {
+ out << indent
+ << "the vtable offset of " << ff->get_pretty_representation()
+ << " changed from " << ff_vtable_offset
+ << " to " << sf_vtable_offset << "\n";
+ }
- class_decl_sptr fc = is_class_type(f);
- class_decl_sptr sc = is_class_type(s);
+ // the parent types (classe or union) of the two member
+ // functions.
+ class_or_union_sptr f =
+ is_class_or_union_type(is_method_type(ff->get_type())->get_class_type());
+ class_or_union_sptr s =
+ is_class_or_union_type(is_method_type(sf->get_type())->get_class_type());
- // Detect if the virtual member function changes above
- // introduced a vtable change or not.
- bool vtable_added = false, vtable_removed = false;
- if (!f->get_is_declaration_only() && !s->get_is_declaration_only())
- {
- if (fc && sc)
+ class_decl_sptr fc = is_class_type(f);
+ class_decl_sptr sc = is_class_type(s);
+
+ // Detect if the virtual member function changes above
+ // introduced a vtable change or not.
+ bool vtable_added = false, vtable_removed = false;
+ if (!f->get_is_declaration_only() && !s->get_is_declaration_only())
{
- vtable_added = !fc->has_vtable() && sc->has_vtable();
- vtable_removed = fc->has_vtable() && !sc->has_vtable();
+ if (fc && sc)
+ {
+ vtable_added = !fc->has_vtable() && sc->has_vtable();
+ vtable_removed = fc->has_vtable() && !sc->has_vtable();
+ }
+ }
+ bool vtable_changed = ((ff_is_virtual != sf_is_virtual)
+ || (ff_vtable_offset != sf_vtable_offset));
+ bool incompatible_change = (ff_vtable_offset != sf_vtable_offset);
+
+ if (vtable_added)
+ out << indent
+ << " note that a vtable was added to "
+ << fc->get_pretty_representation()
+ << "\n";
+ else if (vtable_removed)
+ out << indent
+ << " note that the vtable was removed from "
+ << fc->get_pretty_representation()
+ << "\n";
+ else if (vtable_changed)
+ {
+ out << indent;
+ if (incompatible_change)
+ out << " note that this is an ABI incompatible "
+ "change to the vtable of ";
+ else
+ out << " note that this induces a change to the vtable of ";
+ out << fc->get_pretty_representation()
+ << "\n";
}
- }
- bool vtable_changed = ((ff_is_virtual != sf_is_virtual)
- || (ff_vtable_offset != sf_vtable_offset));
- bool incompatible_change = (ff_vtable_offset != sf_vtable_offset);
- if (vtable_added)
- out << indent
- << " note that a vtable was added to "
- << fc->get_pretty_representation()
- << "\n";
- else if (vtable_removed)
- out << indent
- << " note that the vtable was removed from "
- << fc->get_pretty_representation()
- << "\n";
- else if (vtable_changed)
- {
- out << indent;
- if (incompatible_change)
- out << " note that this is an ABI incompatible "
- "change to the vtable of ";
- else
- out << " note that this induces a change to the vtable of ";
- out << fc->get_pretty_representation()
- << "\n";
}
-
}
// Report about function type differences.
@@ -1648,17 +1657,20 @@ default_reporter::report(const var_diff& d, ostream& out,
decl_base_sptr first = d.first_var(), second = d.second_var();
string n = first->get_pretty_representation();
- report_name_size_and_alignment_changes(first, second,
- d.context(),
- out, indent);
+ if (!d.is_filtered_out_without_looking_at_allowed_changes())
+ {
+ report_name_size_and_alignment_changes(first, second,
+ d.context(),
+ out, indent);
- maybe_report_diff_for_symbol(d.first_var()->get_symbol(),
- d.second_var()->get_symbol(),
- d.context(), out, indent);
+ maybe_report_diff_for_symbol(d.first_var()->get_symbol(),
+ d.second_var()->get_symbol(),
+ d.context(), out, indent);
- maybe_report_diff_for_member(first, second, d.context(), out, indent);
+ maybe_report_diff_for_member(first, second, d.context(), out, indent);
- maybe_report_diff_for_variable(first, second, d.context(), out, indent);
+ maybe_report_diff_for_variable(first, second, d.context(), out, indent);
+ }
if (diff_sptr dif = d.type_diff())
{
@@ -274,6 +274,67 @@ suppression_base::has_soname_related_property() const
&& get_soname_not_regex_str().empty()));
}
+/// Constructor of the @ref negated_suppression_base.
+negated_suppression_base::negated_suppression_base()
+{
+}
+
+/// Destructor of the @ref negated_suppression_base.
+negated_suppression_base::~negated_suppression_base()
+{
+}
+
+/// Test if a suppression specification is a negated suppression.
+///
+/// @param s the suppression to consider.
+///
+/// @return true iff @p s is an instance of @ref
+/// negated_suppression_base.
+bool
+is_negated_suppression(const suppression_base& s)
+{
+ bool result = true;
+ try
+ {
+ dynamic_cast<const negated_suppression_base&>(s);
+ }
+ catch (...)
+ {
+ result = false;
+ }
+ return result;
+}
+
+/// Test if a suppression specification is a negated suppression.
+///
+/// @param s the suppression to consider.
+///
+/// @return true a pointer to the @ref negated_suppression_base which
+/// @p s, or nil if it's not a negated suppression.
+/// negated_suppression_base.
+const negated_suppression_base*
+is_negated_suppression(const suppression_base* s)
+{
+ const negated_suppression_base* result = nullptr;
+ result = dynamic_cast<const negated_suppression_base*>(s);
+ return result;
+}
+
+/// Test if a suppression specification is a negated suppression.
+///
+/// @param s the suppression to consider.
+///
+/// @return true a pointer to the @ref negated_suppression_base which
+/// @p s, or nil if it's not a negated suppression.
+/// negated_suppression_base.
+negated_suppression_sptr
+is_negated_suppression(const suppression_sptr& s)
+{
+ negated_suppression_sptr result;
+ result = dynamic_pointer_cast<negated_suppression_base>(s);
+ return result;
+}
+
/// Check if the SONAMEs of the two binaries being compared match the
/// content of the properties "soname_regexp" and "soname_not_regexp"
/// of the current suppression specification.
@@ -1619,6 +1680,52 @@ is_type_suppression(suppression_sptr suppr)
// </type_suppression stuff>
+// <negated_type_suppression stuff>
+
+/// Constructor for @ref negated_type_suppression.
+///
+/// @param label the label of the suppression. This is just a free
+/// form comment explaining what the suppression is about.
+///
+/// @param type_name_regexp the regular expression describing the
+/// types about which diff reports should be suppressed. If it's an
+/// empty string, the parameter is ignored.
+///
+/// @param type_name the name of the type about which diff reports
+/// should be suppressed. If it's an empty string, the parameter is
+/// ignored.
+///
+/// Note that parameter @p type_name_regexp and @p type_name_regexp
+/// should not necessarily be populated. It usually is either one or
+/// the other that the user wants.
+negated_type_suppression::negated_type_suppression(const string& label,
+ const string& type_name_regexp,
+ const string& type_name)
+ : type_suppression(label, type_name_regexp, type_name),
+ negated_suppression_base()
+{
+}
+
+/// Evaluate this suppression specification on a given diff node and
+/// say if the diff node should be suppressed or not.
+///
+/// @param diff the diff node to evaluate this suppression
+/// specification against.
+///
+/// @return true if @p diff should be suppressed.
+bool
+negated_type_suppression::suppresses_diff(const diff* diff) const
+{
+ return !type_suppression::suppresses_diff(diff);
+}
+
+/// Destructor of the @ref negated_type_suppression type.
+negated_type_suppression::~negated_type_suppression()
+{
+}
+
+// </negated_type_suppression stuff>
+
/// Parse the value of the "type_kind" property in the "suppress_type"
/// section.
///
@@ -1681,7 +1788,8 @@ read_type_suppression(const ini::config::section& section)
{
type_suppression_sptr result;
- if (section.get_name() != "suppress_type")
+ if (section.get_name() != "suppress_type"
+ && section.get_name() != "allow_type")
return result;
static const char *const sufficient_props[] = {
@@ -2046,7 +2154,11 @@ read_type_suppression(const ini::config::section& section)
changed_enumerator_names.push_back(p->get_value()->as_string());
}
- result.reset(new type_suppression(label_str, name_regex_str, name_str));
+ if (section.get_name() == "suppress_type")
+ result.reset(new type_suppression(label_str, name_regex_str, name_str));
+ else if (section.get_name() == "allow_type")
+ result.reset(new negated_type_suppression(label_str, name_regex_str,
+ name_str));
if (consider_type_kind)
{
@@ -258,6 +258,46 @@ test-abidiff-exit/PR30048-test-2-v0.cc \
test-abidiff-exit/PR30048-test-2-v0.o \
test-abidiff-exit/PR30048-test-2-v1.cc \
test-abidiff-exit/PR30048-test-2-v1.o \
+test-abidiff-exit/test-allow-type-array-suppr.txt \
+test-abidiff-exit/test-allow-type-array-v0--v1-report-1.txt \
+test-abidiff-exit/test-allow-type-array-v0--v1-report-2.txt \
+test-abidiff-exit/test-allow-type-array-v0--v2-report-1.txt \
+test-abidiff-exit/test-allow-type-array-v0--v2-report-2.txt \
+test-abidiff-exit/test-allow-type-array-v0--v3-report-1.txt \
+test-abidiff-exit/test-allow-type-array-v0--v3-report-2.txt \
+test-abidiff-exit/test-allow-type-array-v0.c \
+test-abidiff-exit/test-allow-type-array-v0.o \
+test-abidiff-exit/test-allow-type-array-v1.c \
+test-abidiff-exit/test-allow-type-array-v1.o \
+test-abidiff-exit/test-allow-type-array-v2.c \
+test-abidiff-exit/test-allow-type-array-v2.o \
+test-abidiff-exit/test-allow-type-array-v3.c \
+test-abidiff-exit/test-allow-type-array-v3.o \
+test-abidiff-exit/test-allow-type-region-suppr.txt \
+test-abidiff-exit/test-allow-type-region-v0--v1-report-1.txt \
+test-abidiff-exit/test-allow-type-region-v0--v1-report-2.txt \
+test-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt \
+test-abidiff-exit/test-allow-type-region-v0--v2-report-2.txt \
+test-abidiff-exit/test-allow-type-region-v0--v3-report-1.txt \
+test-abidiff-exit/test-allow-type-region-v0--v3-report-2.txt \
+test-abidiff-exit/test-allow-type-region-v0--v4-report-1.txt \
+test-abidiff-exit/test-allow-type-region-v0--v4-report-2.txt \
+test-abidiff-exit/test-allow-type-region-v0--v5-report-1.txt \
+test-abidiff-exit/test-allow-type-region-v0--v5-report-2.txt \
+test-abidiff-exit/test-allow-type-region-v0.c \
+test-abidiff-exit/test-allow-type-region-v0.o \
+test-abidiff-exit/test-allow-type-region-v1.c \
+test-abidiff-exit/test-allow-type-region-v1.o \
+test-abidiff-exit/test-allow-type-region-v2.c \
+test-abidiff-exit/test-allow-type-region-v2.o \
+test-abidiff-exit/test-allow-type-region-v3.c \
+test-abidiff-exit/test-allow-type-region-v3.o \
+test-abidiff-exit/test-allow-type-region-v4.c \
+test-abidiff-exit/test-allow-type-region-v4.o \
+test-abidiff-exit/test-allow-type-region-v5.c \
+test-abidiff-exit/test-allow-type-region-v5.o \
+test-abidiff-exit/test-allow-type-suppr2.txt \
+test-abidiff-exit/test-allow-type-suppr1.txt \
\
test-diff-dwarf/test0-v0.cc \
test-diff-dwarf/test0-v0.o \
new file mode 100644
@@ -0,0 +1,7 @@
+[allow_type]
+ type_kind = struct
+ has_data_member_regexp = rh_kabi_reserved
+
+[suppress_type]
+ type_kind = struct
+ has_data_member_inserted_between = {offset_of(rh_kabi_reserved1), end}
new file mode 100644
@@ -0,0 +1,23 @@
+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 int foo(C0*, C1*)' at test-allow-type-array-v0.c:15:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-array-v1.c:1:1:
+ type size hasn't changed
+ 1 data member insertion:
+ 'int inserted', at offset 64 (in bits) at test-allow-type-array-v1.c:5:1
+ 1 data member change:
+ type of 'char rh_kabi_reserved1[50]' changed:
+ type name changed from 'char[50]' to 'char[46]'
+ array type size changed from 400 to 368
+ array type subrange 1 changed length from 50 to 46
+ and offset changed from 64 to 96 (in bits) (by +32 bits)
+ parameter 2 of type 'C1*' has sub-type changes:
+ in pointed to type 'struct C1' at test-allow-type-array-v1.c:9:1:
+ type size changed from 64 to 96 (in bits)
+ 1 data member insertion:
+ 'int m2', at offset 64 (in bits) at test-allow-type-array-v1.c:13:1
+
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,20 @@
+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 int foo(C0*, C1*)' at test-allow-type-array-v0.c:15:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-array-v2.c:1:1:
+ type size changed from 480 to 512 (in bits)
+ 1 data member insertion:
+ 'int wrongly_inserted', at offset 32 (in bits) at test-allow-type-array-v2.c:4:1
+ 2 data member changes:
+ 'int m1' offset changed from 32 to 64 (in bits) (by +32 bits)
+ 'char rh_kabi_reserved1[50]' offset changed from 64 to 96 (in bits) (by +32 bits)
+ parameter 2 of type 'C1*' has sub-type changes:
+ in pointed to type 'struct C1' at test-allow-type-array-v2.c:9:1:
+ type size changed from 64 to 96 (in bits)
+ 1 data member insertion:
+ 'int m2', at offset 64 (in bits) at test-allow-type-array-v2.c:13:1
+
new file mode 100644
@@ -0,0 +1,15 @@
+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 int foo(C0*, C1*)' at test-allow-type-array-v0.c:15:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-array-v2.c:1:1:
+ type size changed from 480 to 512 (in bits)
+ 1 data member insertion:
+ 'int wrongly_inserted', at offset 32 (in bits) at test-allow-type-array-v2.c:4:1
+ 2 data member changes:
+ 'int m1' offset changed from 32 to 64 (in bits) (by +32 bits)
+ 'char rh_kabi_reserved1[50]' offset changed from 64 to 96 (in bits) (by +32 bits)
+
new file mode 100644
@@ -0,0 +1,23 @@
+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 int foo(C0*, C1*)' at test-allow-type-array-v0.c:15:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-array-v3.c:1:1:
+ type size hasn't changed
+ 1 data member insertion:
+ 'int correctly_inserted', at offset 64 (in bits) at test-allow-type-array-v3.c:5:1
+ 1 data member change:
+ type of 'char rh_kabi_reserved1[50]' changed:
+ type name changed from 'char[50]' to 'char[46]'
+ array type size changed from 400 to 368
+ array type subrange 1 changed length from 50 to 46
+ and offset changed from 64 to 96 (in bits) (by +32 bits)
+ parameter 2 of type 'C1*' has sub-type changes:
+ in pointed to type 'struct C1' at test-allow-type-array-v3.c:9:1:
+ type size changed from 64 to 96 (in bits)
+ 1 data member insertion:
+ 'int m2', at offset 64 (in bits) at test-allow-type-array-v3.c:13:1
+
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,18 @@
+struct C0
+{
+ int m0;
+ int m1;
+ char rh_kabi_reserved1[50];
+};
+
+struct C1
+{
+ int m0;
+ char m1;
+};
+
+int
+foo(struct C0 *c0, struct C1 *c1)
+{
+ return c0->m0 + c1->m0;
+}
new file mode 100644
GIT binary patch
literal 3392
zcmc&$&2Jl35TEDuCYx*$J24*(0cDLqZ6kK=4OIy#DM6t$5vZV|s+WSZwx8`K{)pC_
zPgEf;h$t73IC4T<kPsJ+9Qg-&<Aj6|NSsjMRH+A;S<g$hn{9>Qz(~6@^PBn2ynSEx
z2Up&BEh7Xd5pWq!JcR-*8!<aFm*Ej8z>U>|Usn%q-(5Y}I$Axva`!Ng@1sKyci#E_
z7tGT^M9d-LJQWdRuP0-6W~B@-iCc(>P8qaeve0xP8=2YR$k&Y;Y6Fa{?sr2N*+;LB
z&nUfI(2OWe6H&j+iVKGE1xBdk=t)V_AYK;CMz04V7j;D-5;Z3A`H$#lYh}ojk@>Wh
zt+_D!b7ZfB?x3N6h%XT1*mtogE}1WyYlQ_9lM6yKOml!04N(Blo&nRmY-$r&Q|J6*
zjtH4ESSSZ((OAR0p-J)VM8VW%XJ#kG)NuZBfMKjZv1p!@H@Ftg?1&I+1*$(<gtbBm
zdz+4Uc^bzP<)58iD^Qu`GyBt&1<&D=p+Vyu#zlQ~93%T}e00p6LoI~3H!)6%b_hOb
z%to6fBW5$XL0OC-L%_(ftL20~_MQG{L!WHuqLj%X@9MQ1){6Ur<+{%Ej%&@A=jUB_
z-nGtMmvw8^3prq4IB(gVaH}hqnzAbczlN?C)LKis3m5H+7wqkM%Wguu*KJx`-M-)K
zBAxa{(5h^BRlgF*z6`cy-Gy4q3!v2Mb!4gDtH0-$ntoVn`&G<pdVaeUv_c!1GU$5k
zQoS!XWGD%>sgBKcN}=qB{Zicvy~wmNR`(kXTkiTHP|)_;?cR<Z?rloj3j%M?-Yz?}
z|F7{w#spVaRu-*uxD@CA!8%0i3V7xRBKEI?*v*TXv0>vA+yk_K)E<iTD--#TGArXl
zH!*=ZX^OT_7XJ7vEvBX3M0k{V2PZiiM$$yX4r!u6bW5BHX%Jl^Dfq}Ki~tSr*rkXD
zV<{-*<0X(H8st(?${#<4(;QF5=10x_!!{vZc4{p~kstqh)q(K%S59$f!s&UJ{l^kG
zyYK`Xw64cD0NQhmQw=o+g5Heb)OVfz?F4>}{o4sVVE-G|$-e3vsjtpCr1ESh^Pgs%
z^6A-QpYBZ(h5s;c@h4{>3jdS+ORSUiEyihX;`0Mef3FjIRn%cH&@E+!ayJBrE*)^H
z{XRH>Y<o^!R=1iJzuV|xEV8|7HIUo)g}uP*Hs$@4w%?VCf-RIua3%6<y-r8sCF*p0
zp>*(mu=}A`+u*{oRcQoXNAidKM>T_dnj^JNs@yUg$NQRn%8g4A9m0|)|5iLHW+(Y)
zF-H6G-|}hwlQpTG>i-)#F-hjqzM|V{IhI4_5pUKb#wSrzo;o}DpCOVZd?#yC;8g~{
zj<QZ($=tUvl*B0eh{5s+HL{YquOpf^{-1b36`#gWw`y|yb;Oc25dw=3$4zo#lFY4O
zEUkZ@ukdx|Qh&N%lKnRkqnc`*XhyQb{dW|=TJ=}@eZ<rFzcYVaB|d<E_yGPr-jF5c
zDW%FO{TcIBT<JNQloU}s75WMd!g#m}hBEUPj*)?(=1;+2qLDWLn>_z&pVIu(ubbj4
xJgqm?ZgKw>514+3=vOnzr!`HUU4-BcpC5~ym?XcS#+AnZn8*KZj7w&c|2JnMH)a3;
literal 0
HcmV?d00001
@@ -0,0 +1,20 @@
+struct C0
+{
+ int m0;
+ int m1;
+ int inserted;
+ char rh_kabi_reserved1[46];
+};
+
+struct C1
+{
+ int m0;
+ char m1;
+ int m2;
+};
+
+int
+foo(struct C0 *c0, struct C1 *c1)
+{
+ return c0->m0 + c1->m0;
+}
new file mode 100644
GIT binary patch
literal 3448
zcmcImOK&4Z5U%!kl1U~HJLZuPP#gr>hZs8(R=Z)BEJ4w-37}=QXtfd#C1bm753$Fq
z@gyXRcpX3+1tE|)a^wI9PF#?<Ai)pd#xLL=;1YoZRE?{hNoR-<h>~Wi>g#%ScTL%E
zUwQtSj1Ztmz-2hp6bi6y9m-3wxCHk=0dB7B{<O0D=E2JD=Kjjwm4m$;zW4V){P5~`
zzoDH8BK904pNC?{#OuL?oLQcOCq)Ah(VhcikR%jc$i`yUAl-~*E0zbW0Fe=}vZfzI
zF!Ua3Z{agcF9)(#oHHv1P=(C03nN2cqeRi|!{{Rx`DI0W9!7h?!LD~YAo6i7<V&O~
z6`%f!npvHL90{3^n`YI8nS)qfhk+6b10UcE#3&fn#aVI5e!^ZYEZAsV5Qb&jJ#5wz
z1pot$#*P?e9|7CGY#U>k#pDRHc?yx4#L(kl&swYKIhYrZjumWUW_l(sCI)l&16b^e
z2R<akYJn0A&%$b<jLGeicxnm@vZ<a^Q>z8?TAI8wMON?_J{hVS68DUn+IGB@c)f_S
ziMD5v3n6|V8zn}KgAWQbaSvt0OlG_nHug0I4E0qbFU*l|%zNu*zHW+gCWC%guiY#z
zyBCVCTY9|Y7U$>Y=UsQ+EuOw1YsD2W;sxj2nWEE<HUqiXkbw;SDym*sZ7yyvoOjNj
zbGGJ-P6Jw<pi$fmx_%=-cj^&8=*lpXH3*w)8(zg<3nc<uvgSgy>4gx<Zsd5aR_Apm
z+PN(qFATjMXUi>Bq1^1WWx3X=z2=u2epGJx6%5eu{8l+^Mh-@oVc@mOwXWQdktEci
z6b`2-Q|xZJ=0#pCI=EKz>vczN`_ca#{e*3uumo3^moFAi<DH!O2Nx1wFyKt+k+^dM
z#CA?hj|^HLVKY!8sb-4#(_^{!Gs~j`x6pun(irto7JmLSZOurXRQOSGE9*W6uB4HH
z8Pdprcyt_FG9aETDfrMai~s}h`%57MhgTXIfFFMf88DuLQvA_lIGyoC;(XNEpVZ<s
z_S9VrqknSuDg)ukT~2Uj!s$_T9}5bfX8i%?bg%tUfbv<!$zIh!&<hEi@~*S~vWEMt
zzpLTbSih^`Z?OJ7bG;t5cdEx^8)7+@b^C`ISNq*zodzqB!hh_k;4)YEFRWi;uE#Gj
zPG^=pHz;*?+L2d59)&&LR8l0jBPh|tfl{U0g;FS6Ua2N4n~gO;sCRHJmc2?Plv_uZ
zz0eC9@~BJ852SLz6iOs`E!L}@c3a|<Ed`xOmT+!3-N>tMaA4V7tA}1&@<#q6qkf_@
zQun07EwRw=ch<=^NwcUBrcZ=dl12$x_dkVe)TjT}pYC6eN$FJnKS)WCZcBYdQ)?+<
zLt>5(#A1g$Vq~YjDf|x+(;~k0n6&T`gI~s0hcDgsIxguLSr2k^&K<hOl5YDPqG|O{
z@@Q55R6jv_{WZk&m<YiI&VP%P1nIVGxR#cGh4ZhoFXgAXqvyYk7{yd|q8QVMoc|rx
z6;t^Yr}>lSKgJC;sth@RQWf9(8~<tA6jHgz`fuf@_$Roc<h~IK&$53KBU!iof-&B1
z-~2lJFZ7X~pw3UhpP@jeOA28AIiJ7kQ#yb8)l>cor+W0<6yh%DZ*sx(`$WH{x<B2i
e{_P?J`#kK6q$Eh+Kh>4y|1H=5Rl=7<-TyDlemc<r
literal 0
HcmV?d00001
@@ -0,0 +1,20 @@
+struct C0
+{
+ int m0;
+ int wrongly_inserted;
+ int m1;
+ char rh_kabi_reserved1[50];
+};
+
+struct C1
+{
+ int m0;
+ char m1;
+ int m2;
+};
+
+int
+foo(struct C0 *c0, struct C1 *c1)
+{
+ return c0->m0 + c1->m0;
+}
new file mode 100644
GIT binary patch
literal 3456
zcmc&$&2Jl35TEDu#+z)M*fErZfU@R8{Sdp(nyL-0QjAP#B2ZNYRYiQcYx~(=Vz0}3
zlO{!c34s~~p(1hYkqZYTBrZrC;lPm_e*yObmk1<aX8oSC*=#EW2S)OHGru>#nRy=`
z``z;|JeOh&q%b%K`<6rj-qZH=N~l)gJ}AKDm7SkgcHZ7w+1a?WvU`4SH;3b$U0^@H
z_TBI3rveL^8R9$~5+lPy5j|C1gbHgT!g`CKWJm*rhIFW>S<ePFRJ9Nu(>z?91TC$)
zUI61CqV*1bCTOrBt%W($Yz$3ERc)9Y{{}URt`DPA#7T{K7`zPGVQ|n}{XVdKSPOAU
zWTou(Z)mBFMaYqo`n01qY*^R}^{X&up)&R{4#2XYXlIJ-tp1d~T3FK2xxf@n*N0e9
zV+GtFI!zsLN<Rj=eoj}WFpDZ86!R1!HH)FAK`&~n$js!~<5LA)S(snQvzbip0RT-<
z@xaF!TP;w6i6X2PN|;=?*wb@ZkWTd+om(vst1^3Ij=bOr{G_OAh}<(;a@*ljWOxyE
z6@5?O%ozJ)DoYbR9Q>fN5Wb-lTS!e0!-iay!T88j@=TrlR=vNa=36Q&rBcYdaPhKH
zwND$iZ9Qq(MtQMZw(YWQ99!c}W5o%?f_d_|VfKOzk1w~m$9=bfrsFp{%UesQ%u^@L
z&9Y&(q1*S`#)da=+aA*Cja>H;>TcIuZ@~S4H^J}J)}6Xr^Em>WylF$D<M>eO^n1M2
z>^I+VOKmqOb=^98wH>!x@;iZvp}6lk-BNSF*LlDRH7SlM;*<hD2nMC56F8x2;#$*f
zwM@R{20)9Z)9v=Jo5A)qZaTj2Y-7z<<Nr&1kDA~@wR*-lhIe!PA6!g$(SW^SDD1`>
zu&o@MpUh~t@KMl%l8-8!pP9;il&WUOuAqb9Bu(_5((ub)Noz`C$D-yjdTa-1%CM~*
zz{pTALy{;Ewva<h3WOad0Utkv5ugBm4--VeCYB@$U=v6X1*Q{Fil04%(;3f1&PSg8
zy&fU8KY14u$dB$`W*|Je%NdcGaQeJ1>?1K;nDC%b=w73@bRyy}Yar;^2u^vg3j389
z{-&_skKq@EeKUrCAnfnO9Ir?2o%W;(ADVJPkNZC&aCr{f!lnjGBJrPwCjL$hMdH5-
z`>dGb@eP5~nMKbHtig6KaOyY*{&4O{E#O-LSk#Qbst*QW`Mm2`O<vz<V<&9&aV^xH
zdfn%n2bLY*@!I?#rR#cJQZR*739f~9qu=Xs?6#KI54eSW!yE)oV_gL1om$IxdR%Pe
zKTh+=r!$iGB*RsNGJ5aACf}$O(I71RM-f?gHKIq=IR7Xv(mVaPe7gU5Ov)$o|4Bwf
z;=c5*sB2XsKBUfy1JMK_j~MyM?-c%*2xS?^cuZP&S%6=LUi(Ab_Yy9}G4jrc$GNyq
z4Yj!M^N1$ZZ-~|^`BXna@%o#H#bY7_r$zoNWJDzHTf?=a{Fg-jtAb1Usqe(|Uqg&y
z$~sXE<r9(rrUb++^UL`y#FO|(#DmI8$Gh-%@4|nSHic3ePNPwVlk;b|BK46IDr<rt
z#Ym6)ejzZi-I4oCg1<CEhKf8t34e|XxmF|~=C8#0%XdoWPrrJSFLA0To|{7468Sr#
oVETQcU(-0B?lk`0MF{ppvp2|yNPPcPR}%jRQUBKwE~#<;-*v`5{r~^~
literal 0
HcmV?d00001
@@ -0,0 +1,20 @@
+struct C0
+{
+ int m0;
+ int m1;
+ int correctly_inserted;
+ char rh_kabi_reserved1[46];
+};
+
+struct C1
+{
+ int m0;
+ char m1;
+ int m2;
+};
+
+int
+foo(struct C0 *c0, struct C1 *c1)
+{
+ return c0->m0 + c1->m0;
+}
new file mode 100644
GIT binary patch
literal 3456
zcmc&$&2Jk;6o2FO#+z)M*l~e`fMO%6eu!PiZq<gC6eFuN5vWv!s)#RVZI3^QKdSX6
zBt?83K!hMvB#u3D;edq11&JdZICA4J;9lSofdsrao^dvlZH3^#NIUc1Z{F{{w=-{_
z{m#W_pN=sGYB0C}`<g-l-nI7Sk`PO91Tt`KW#{LWowxQ@b~f&;>|Wg4P2qfJ7ub)l
ze)l`tnZN`yL7ayLF*H3Cl4IpXc!D(%VckVA5+tEmfVdFj2I;1dEg_FtJwztKikt0T
z0ORkY_BK8fG&vBrM9erFLlt7>0!)s7gA#eS_q|VA#EY|T5t2jaU^n`GU}=#HacQVb
z+3nv@Gi!^GA|du^%d8b(VNb|wFy^8#_AyStl3-Zpa_qeQxV@TLve7uh49m8MSk7V@
z00WJt4j9EB1>3%08&ep?lpb<vauJ(F*VAC<tW{(t((LF|#x@q_7t(Adk$M2Yl2knK
zamH3N6ks9;tC>6ow_Wz+942H_KF8)(GsG&*-kc*VcnqHyWeuTwMoqo8*a}V0qimw>
zNn9CYe@rE5p~Arjg#}SVF}4t!9=a7=lfn2%HPXzS{MNj$VWt}<%g18KyL9<lwp=)y
zEfm~SZXsJ-EEWreVj+9{Dz9f(yg+U^r%z;^Zm`kg%T3<ne!GUM=hs@xTT5r0GpC)+
zV%BLwr{8O4H+qA1vxju55x-Sg_p0rR&j;M!<n;p7`o7O=L1(+t?jaWNI@DU85BXNV
z%k%Yq{q=Uf*$(oZb`^<DuieS}t-wKN-0yjve0{*zdB6#E$h9L~=L0?n2Kl-dctUh=
zuikDn9KO{KfHobk)9JtA1lu>b<N3a~?QEWMYyV&1d*lR{%H?y}<9ItK{=wCVt3D!T
ztc9Cbfo-MO{A9wqg+)OHrHV?dPfevhh?SFL*U><7q86&BIQ;Tg)SeO9vGC)PC9QJ|
z+=&_nMu-{)h!%2a%K*_~BJlA;7y$<0cNj4YY+_Nv0Biyg!+_}sl>8?T;dI6`q4QB^
zf3Fgx_NVS*0{P*$R}lygzvYaKOgKHSN&S8emnu9c1-jQ!OF;Rg#L0)sfuQF?IK}m)
z{<4OzN&P(yzby3+HJqA1jqitxIH_<x>fI?HQ`*pylCqxvBN8WjdbXub4VH$&e;TS#
zkgLLfmHK(P>i)A5ryRq1f;-sm23{4{z#pzHB?Wvd0GC=3xYfY`T%UJ5x6Z2@P3(G&
zKJE$Gt5$u!d0^Y~y<U?aq;%Rnt|%Bni3C@KUh8+e9J{UC>j&J$uHg&<ueL57^H!zd
zdtEMH<UcO+$fq+>_oUpFq%f*?sgrGZ<WM0@?+CAijY6`{KZbi$r~j5u_pke;a4P<v
zq=bfUOLawEs}!;!aaJCPB?)Q7$WDDz_+LVdWt?@NwDFPzzZ6#clWuzjw{(oG6S6oL
z_o+hCZJ$9jD*vo(t%^_i6Qt)~M@;vL5S*3quagoQx@`sbqT*kX@z*4m;#1$z<KIAx
ze5yQA6yp;a|04y+RmE59n}|p8XJtVpmEm3ZyLaIqrI*5yA1<R=xl`+BxTEBe5ehFz
zei$QJxBWt5@^we%FG~K>2pJ0M{1p5-3S?SRfLy<l=dbFN&Yynu6kp+#j~<&`+>-HI
pGGY3CqF+;;Pj{++y9mLaZ1!1FLPLLl$}5WhgUtWy5SK)q|2NDSKh*#L
literal 0
HcmV?d00001
@@ -0,0 +1,11 @@
+[allow_type]
+ type_kind = struct
+ has_data_member_regexp = rh_kabi_reserved
+
+[suppress_type]
+ type_kind = struct
+ has_data_member_inserted_between =
+ {
+ offset_of_first_data_member_regexp(rh_kabi_reserved),
+ offset_of_last_data_member_regexp(rh_kabi_reserved)
+ }
new file mode 100644
@@ -0,0 +1,20 @@
+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 int foo(C0*, C1*)' at test-allow-type-region-v0.c:19:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-region-v1.c:1:1:
+ type size hasn't changed
+ 1 data member change:
+ type of 'unsigned int rh_kabi_reserved1' changed:
+ type name changed from 'unsigned int' to 'int'
+ type size hasn't changed
+ and name of 'C0::rh_kabi_reserved1' changed to 'C0::correctly_inserted' at test-allow-type-region-v1.c:5:1
+ parameter 2 of type 'C1*' has sub-type changes:
+ in pointed to type 'struct C1' at test-allow-type-region-v1.c:12:1:
+ type size hasn't changed
+ 1 data member insertion:
+ 'char wrongly_inserted', at offset 40 (in bits) at test-allow-type-region-v1.c:16:1
+
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,21 @@
+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 int foo(C0*, C1*)' at test-allow-type-region-v0.c:19:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-region-v2.c:1:1:
+ type size hasn't changed
+ 1 data member deletion:
+ 'unsigned int rh_kabi_reserved1', at offset 64 (in bits) at test-allow-type-region-v0.c:5:1
+ 1 data member insertion:
+ 'int incorrectly_inserted', at offset 32 (in bits) at test-allow-type-region-v2.c:4:1
+ 1 data member change:
+ 'int m1' offset changed from 32 to 64 (in bits) (by +32 bits)
+ parameter 2 of type 'C1*' has sub-type changes:
+ in pointed to type 'struct C1' at test-allow-type-region-v2.c:12:1:
+ type size hasn't changed
+ 1 data member insertion:
+ 'char wrongly_inserted', at offset 40 (in bits) at test-allow-type-region-v2.c:16:1
+
new file mode 100644
@@ -0,0 +1,16 @@
+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 int foo(C0*, C1*)' at test-allow-type-region-v0.c:19:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-region-v2.c:1:1:
+ type size hasn't changed
+ 1 data member deletion:
+ 'unsigned int rh_kabi_reserved1', at offset 64 (in bits) at test-allow-type-region-v0.c:5:1
+ 1 data member insertion:
+ 'int incorrectly_inserted', at offset 32 (in bits) at test-allow-type-region-v2.c:4:1
+ 1 data member change:
+ 'int m1' offset changed from 32 to 64 (in bits) (by +32 bits)
+
new file mode 100644
@@ -0,0 +1,23 @@
+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 int foo(C0*, C1*)' at test-allow-type-region-v0.c:19:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-region-v3.c:1:1:
+ type size changed from 224 to 256 (in bits)
+ 1 data member insertion:
+ 'int incorrectly_inserted', at offset 64 (in bits) at test-allow-type-region-v3.c:5:1
+ 5 data member changes:
+ 'unsigned int rh_kabi_reserved1' offset changed from 64 to 96 (in bits) (by +32 bits)
+ 'unsigned int rh_kabi_reserved2' offset changed from 96 to 128 (in bits) (by +32 bits)
+ 'unsigned int rh_kabi_reserved3' offset changed from 128 to 160 (in bits) (by +32 bits)
+ 'unsigned int rh_kabi_reserved4' offset changed from 160 to 192 (in bits) (by +32 bits)
+ 'unsigned int rh_kabi_reserved5' offset changed from 192 to 224 (in bits) (by +32 bits)
+ parameter 2 of type 'C1*' has sub-type changes:
+ in pointed to type 'struct C1' at test-allow-type-region-v3.c:13:1:
+ type size hasn't changed
+ 1 data member insertion:
+ 'char wrongly_inserted', at offset 40 (in bits) at test-allow-type-region-v3.c:17:1
+
new file mode 100644
@@ -0,0 +1,18 @@
+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 int foo(C0*, C1*)' at test-allow-type-region-v0.c:19:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-region-v3.c:1:1:
+ type size changed from 224 to 256 (in bits)
+ 1 data member insertion:
+ 'int incorrectly_inserted', at offset 64 (in bits) at test-allow-type-region-v3.c:5:1
+ 5 data member changes:
+ 'unsigned int rh_kabi_reserved1' offset changed from 64 to 96 (in bits) (by +32 bits)
+ 'unsigned int rh_kabi_reserved2' offset changed from 96 to 128 (in bits) (by +32 bits)
+ 'unsigned int rh_kabi_reserved3' offset changed from 128 to 160 (in bits) (by +32 bits)
+ 'unsigned int rh_kabi_reserved4' offset changed from 160 to 192 (in bits) (by +32 bits)
+ 'unsigned int rh_kabi_reserved5' offset changed from 192 to 224 (in bits) (by +32 bits)
+
new file mode 100644
@@ -0,0 +1,28 @@
+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 int foo(C0*, C1*)' at test-allow-type-region-v0.c:19:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-region-v4.c:1:1:
+ type size hasn't changed
+ 3 data member changes:
+ type of 'unsigned int rh_kabi_reserved1' changed:
+ type name changed from 'unsigned int' to 'int'
+ type size hasn't changed
+ and name of 'C0::rh_kabi_reserved1' changed to 'C0::correctly_inserted1' at test-allow-type-region-v4.c:5:1
+ type of 'unsigned int rh_kabi_reserved3' changed:
+ type name changed from 'unsigned int' to 'int'
+ type size hasn't changed
+ and name of 'C0::rh_kabi_reserved3' changed to 'C0::correctly_inserted2' at test-allow-type-region-v4.c:7:1
+ type of 'unsigned int rh_kabi_reserved4' changed:
+ type name changed from 'unsigned int' to 'int'
+ type size hasn't changed
+ and name of 'C0::rh_kabi_reserved4' changed to 'C0::correctly_inserted3' at test-allow-type-region-v4.c:8:1
+ parameter 2 of type 'C1*' has sub-type changes:
+ in pointed to type 'struct C1' at test-allow-type-region-v4.c:12:1:
+ type size hasn't changed
+ 1 data member insertion:
+ 'char wrongly_inserted', at offset 40 (in bits) at test-allow-type-region-v4.c:16:1
+
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,30 @@
+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 int foo(C0*, C1*)' at test-allow-type-region-v0.c:19:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-region-v5.c:1:1:
+ type size changed from 224 to 256 (in bits)
+ 1 data member insertion:
+ 'int incorrectly_inserted', at offset 224 (in bits) at test-allow-type-region-v5.c:10:1
+ 3 data member changes:
+ type of 'unsigned int rh_kabi_reserved1' changed:
+ type name changed from 'unsigned int' to 'int'
+ type size hasn't changed
+ and name of 'C0::rh_kabi_reserved1' changed to 'C0::correctly_inserted1' at test-allow-type-region-v5.c:5:1
+ type of 'unsigned int rh_kabi_reserved3' changed:
+ type name changed from 'unsigned int' to 'int'
+ type size hasn't changed
+ and name of 'C0::rh_kabi_reserved3' changed to 'C0::correctly_inserted2' at test-allow-type-region-v5.c:7:1
+ type of 'unsigned int rh_kabi_reserved4' changed:
+ type name changed from 'unsigned int' to 'int'
+ type size hasn't changed
+ and name of 'C0::rh_kabi_reserved4' changed to 'C0::correctly_inserted3' at test-allow-type-region-v5.c:8:1
+ parameter 2 of type 'C1*' has sub-type changes:
+ in pointed to type 'struct C1' at test-allow-type-region-v5.c:13:1:
+ type size hasn't changed
+ 1 data member insertion:
+ 'char wrongly_inserted', at offset 40 (in bits) at test-allow-type-region-v5.c:17:1
+
new file mode 100644
@@ -0,0 +1,25 @@
+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 int foo(C0*, C1*)' at test-allow-type-region-v0.c:19:1 has some indirect sub-type changes:
+ parameter 1 of type 'C0*' has sub-type changes:
+ in pointed to type 'struct C0' at test-allow-type-region-v5.c:1:1:
+ type size changed from 224 to 256 (in bits)
+ 1 data member insertion:
+ 'int incorrectly_inserted', at offset 224 (in bits) at test-allow-type-region-v5.c:10:1
+ 3 data member changes:
+ type of 'unsigned int rh_kabi_reserved1' changed:
+ type name changed from 'unsigned int' to 'int'
+ type size hasn't changed
+ and name of 'C0::rh_kabi_reserved1' changed to 'C0::correctly_inserted1' at test-allow-type-region-v5.c:5:1
+ type of 'unsigned int rh_kabi_reserved3' changed:
+ type name changed from 'unsigned int' to 'int'
+ type size hasn't changed
+ and name of 'C0::rh_kabi_reserved3' changed to 'C0::correctly_inserted2' at test-allow-type-region-v5.c:7:1
+ type of 'unsigned int rh_kabi_reserved4' changed:
+ type name changed from 'unsigned int' to 'int'
+ type size hasn't changed
+ and name of 'C0::rh_kabi_reserved4' changed to 'C0::correctly_inserted3' at test-allow-type-region-v5.c:8:1
+
new file mode 100644
@@ -0,0 +1,22 @@
+struct C0
+{
+ int m0;
+ int m1;
+ unsigned rh_kabi_reserved1;
+ unsigned rh_kabi_reserved2;
+ unsigned rh_kabi_reserved3;
+ unsigned rh_kabi_reserved4;
+ unsigned rh_kabi_reserved5;
+};
+
+struct C1
+{
+ int m0;
+ char m1;
+};
+
+int
+foo(struct C0 *c0, struct C1 *c1)
+{
+ return c0->m0 + c1->m0;
+}
new file mode 100644
GIT binary patch
literal 3576
zcmc&$&2Jl35TEDu#tzPh6BkHGQEUWiTCsMVhLSc)F^WnP6+u;0RpO)R+J3f|_#;|x
zLK=h$mr7BD)JhyU^adBs2&pPZE<JMOAK+djBqBh-%=5ft^So537e?~VZ+>s)&AgAD
z^{oqUz7Z1wv<Ns4hn8jm_LGOWq+kh-K?bg_?Ebv6`^o;w?&hPFy$kz$X?#A~1M%Yr
zKm3J$HV74&pqS@XVCZo?gstUSI4*7@6Kl<al^}$$2yq4Dsw(?)B$Emb5FAo4K`^ag
zlHf4~2MJC<GH!eA0OD~~g0)<P<j{9GLRm%*vy3K*j6+-upoYO(rvoCR>LHs%S1a!Q
zhL&BKg*1WK-G*H$!t|dC-++NUf`Kpa0b&@ek#jk*m^zyqTFoq^&>N{_k4p6zD<iCA
zD#dO|k-;)vgjDK$${N8mHv8u?XE7i)fpd>SDwkYEzr>h$X(W@frl+RI#CRh8EN%{m
z;;s+o#cPw8EQRS)Cni@j<Wrj1nWPl(GX7#zB!rF@Exk%L6neaa*hb$|sD%)Jj0}^a
zoyH%6X|?GwF&!K2O{-#U0fPr7uGAj--hR4fkJW5Zh{Z5&v)%RTZCTCIAzggyYIeE!
zYPML+pUxMvbF*`E#o}BsJ97mcR@{IGocWVkrxk3r<x*X?rSDbHbp1+WX?x*}b7tPz
zn#($M@EdFEZrNM&Wmo!JvRdq8=K7e^eaw6x^9ocNt`CJqrzH#3PW3~tQ1^mD(<@`P
zy6ZIyej{*jJ<@Nx%|f*+*JU7yb*LVP>nQ}X8*~d*H*ghnaIEUpYL49Y0-!<1Z8kd}
zIl;{hi9vO*({{FI^OgTG^W&<5i_6RBvNL#wC;!6%s@s9DDr>QG1;ln*ObsQHckm|B
zEz~zr>DNcnw`0r01J}@jW1<vY!Z`f$chr~_+1UUreh<tT3rC{F!VFPjfodInLl&sk
z6TuJmaYR^veIi0E7>Z!YANxdvSTGvFlK*fYPpx@8v_E?9AA1j}N3!TMc?#|DF6d0e
z(`vOn&T+)k?>gJh7(AQs90NMvgMNbe6!SEPu7RkxLp<eukL`C2zQwjQ_*-mm82nwf
zKQ{QU*uG=%Y{Gqmr;iQE!=6$*A6}Q<Lt2;3KBUr&&3$-*dGe><4%^h_Ni_dc&x9gt
z&Hu{wB5QO0Eb~-jxK7A-Z?*!rj5_dpx}i}Zw*$yie}jCv+l9O@n{K`;%bWEzuU+fl
zn8I$k?8~hq!>;eP>+)zw(`!o|f+;j4dQI7tPOByHE0S+_0-47?<a7hKvd$CB##+sH
zTl%1RJx{8pFp&00pOc=a#NgolVViuzl0$<yv%|a}b_!uL{sfNEeSgw;I)8IcN~iP3
zj6uUx{~o9dmMADBE4(3>IbaOO$WOnU`1eK05<bm2Y2Z4O_mtP+!}Pt3LncSwzcV>|
z7^;xzdkNX7`oH8>t>dYFqRjfM$eD8@1*iDsxJE`uOy4yei^~6y^WWfD%1`~v%)fyg
z&8h1|sN^%w|3DM0b$+d>e?`SF@`dXCn?9UG$7#LyFY%XXQ7DC;I(X_ht?BQv#s^La
zb~rxF5jK6lVeUvTLhe(JU!b6n=>5~w*9ge9qzTqD?5OW4?LU1*b-d=O9y2#hai8-y
oxM2Fu(bw6Gr!zI*U8Eq(?@x}5keKVIx}xGsoaoz7EI~8=A2fhgBme*a
literal 0
HcmV?d00001
@@ -0,0 +1,23 @@
+struct C0
+{
+ int m0;
+ int m1;
+ int correctly_inserted;
+ unsigned rh_kabi_reserved2;
+ unsigned rh_kabi_reserved3;
+ unsigned rh_kabi_reserved4;
+ unsigned rh_kabi_reserved5;
+};
+
+struct C1
+{
+ int m0;
+ char m1;
+ char wrongly_inserted;
+};
+
+int
+foo(struct C0 *c0, struct C1 *c1)
+{
+ return c0->m0 + c1->m0;
+}
new file mode 100644
GIT binary patch
literal 3632
zcmc&$&2Jl35TEsC6Q@obCpM6fB0C7w53zPO4JD*XF|tY%fdCa%JwQp;_Ordj_Ezgn
zngl^_NKq~=f&-!lgt%~q6C9C1NE~`Be*pI)aj3)rW}fFco0nCE;J`@x<~P5YdGo&Z
z?cTcd+A9ge03`-oghNZQ0P~}VxGZ5Aa*&0qtNXvL?tk!bb${!@>cORl2N`T19Ds4}
z`VSM>kp)JQ!bhliikhgLj2LER9!?qu$Rs-RV2%(%=)jPKLvmD>#7T*V$3Di0F^NYc
z&Pbe;I4AL_#M6)*vb=5xLql>LX2pTz*pFN)eOPKDNo2oNMq&%CVdP-6;rn3Z<N(Pg
zQNuUx(ul0uJY)zY?zF6$1Nm`@H(<DkvBRHHhA|FidU?*cka{t-mR(9=Ffz#_jF~me
zWGdC?=8{GhNAwJ&QWsNZ8mm|wKbNB}64TiA1f=GYYZx~&X*`?Grp)|oe$tp4$vgp&
z<W$^+(W3Fv3>HgK^;0uzS&Au7@6AvNcn+TgjS=LANkomB<bYuC7HSJ)&!RRA<InUs
zDOz=W5abC$!pJ8k`rVQVmI0#!)65yx*!R|B4QsMt8Kp!5^Mcm;rd##a1JM(~wx~Z3
zTiu@5?23AUcJT7+R|^&Ag@WT0&lR1*!u-O5<19FZ(^oKH)eYHUFP<sbop7rwR+^$K
z0<VUq8`N4WJ4@&7^NaTOLcwmr&A{(A+q>&t7mJ0W4tn*4W6Zf@%p%nMAP}`M+EK0L
z22g7G9Z{<L_4m9|(+f*&uZmM^x?Z~!v_c!_BZ98mF4cQtQ-p$8n<j7b<V&IGg}qYU
z4P6Os^wqsa!xlSU2;{WgcH6&chr2ffCN(|3Yi~Qn+W%PjQKN#(mCADAH16S<f3Sh_
zyyRqy2WsyM7&{qbc5Ebh8&4LUN_8@&emR}_C{Y<7zJ>vu6Q}4<4#Dq##re$Gn-9R`
z_d?Gx(Gw>oR)`Z5<V|wSW%h5!7(R08M!Y8Ay%8fOjK#1te!Mqg#Ds|$mg2{c@pN@h
zMb<~H{Uc8yU70LuPfnm6T?JK%c$#gV<EK~?PtUt-Kd$j?!jlYWe+Tyq;<L<CA8HIl
zy%FK5?ze2et??hS-PHKoZ1*(&OSW%mJe%;T#;bXLr|})Of7bY)*#4EZK3}!AG+&Ej
zNM#u7@lP{P@$~GmO<w~N#ozCn;ILNwA8cP>t@mGGp7tcVFHr35c0#v`It=={rBEn#
zLMYO$2gPcy2gN|N-C|u-x0-lUH+=L->{hFR*goQR1Gn20M^oBfSEv*$p&-%g(ysZP
zj=*nAvFnGTh_{p73*Fi#cPv`#jlk^)p2&YxvzSk7r1nX5S7tDHuh^#8sLY{3oPP7X
z6Ag-BJ^vK?=sozi`LzFfpHxoO&uUK1lz$m?JC-RaA}wB!7AH)ikK)uji@!NiR<PCk
zB!|!B=Q8TB(PQ64m(Ef22|k?jhp7_jv9BT<H~xF_#}faOIiJQ)ls^7Ca(bVXvds0b
zkr5F+b{&0j^;Mw_&ZYWvuj%z~AV+<waUzs*hwJ~M2-d2;((fZ5mw%lPRR0(JuoIQ1
zH2u}b<#%XOD5bs{v?@>OPtc?AAPB)-&X010_1LeO<LM5<zu^3(0n-O+{S^Hb0tziF
zg7pRms&h)~PhVG+uXq}dUYokO&-K;$r|$xNwe@`3Q~ljV3d;Qc%#jfhef~7AxcnV1
L^i3p}pq~FXvNv33
literal 0
HcmV?d00001
@@ -0,0 +1,23 @@
+struct C0
+{
+ int m0;
+ int incorrectly_inserted;
+ int m1;
+ unsigned rh_kabi_reserved2;
+ unsigned rh_kabi_reserved3;
+ unsigned rh_kabi_reserved4;
+ unsigned rh_kabi_reserved5;
+};
+
+struct C1
+{
+ int m0;
+ char m1;
+ char wrongly_inserted;
+};
+
+int
+foo(struct C0 *c0, struct C1 *c1)
+{
+ return c0->m0 + c1->m0;
+}
new file mode 100644
GIT binary patch
literal 3632
zcmcIm&2Jl35TEsW6Q_0(Ck~L1qBscD53zQfh7wYx7@5*UAcTsl9soIO``KP%?^f$g
zngl^_NKr17j{^cB4shVy0}>pOkhq{8%OAkKNE|A0fSKoc&gNwmArK>Z=QqDMU+-g|
z_x6=nUrrbXC^6tN99oJ6SQt6PWeLkL1v$9Bw*TAO{(BGC_O~9a9b9>Mkj3YN12FEr
z{o^<$vcO1@`!GG8phr|rM+~#F0H=)uWD?y4Foy~CTS-csOms_NNtluy4rM+<kBr2_
z5@#h&NjxR-h{V&7N?NWLLNY1)Fe@cUWq#sPWBpQ;emq5FQif(Fw$K_v4n~^355|;i
zkZcmwzVQWhWYrfSOCWKlZPiOKH!AT43>DCK=rf8iM!_6gnKv$_pHHvnmec5rOzH?@
z<_t5HPWQR_l##=Zo`Q7xa@rijDi-_CPf?1*G^QSh^n7X^{e~xur^j+>b8dES!k8S+
zJ_eBDP~3%)g7Lx(7E4q0Gc)Ts@+nX6%}@z=27d|a5#)wRL=QE|0m0x6)E4@lM{O9!
zpJSt>XzB2WV2&UpjJd>kKP{PH889+1%_+mm{9rxOv?iLCQA{K-E@)Rbotj$>L{9|U
zqVX(jc|Et~iAJ7w@ak*V^Oe$b`BJHHp-{>%E-WsVN{glZ*=y*q=7c<8FP+QV-Ehkj
zt1aP)z^$X{1oign&hkb3;*!0+n73PSEAYKmXSeElSS%C`aJ{-81fm{BNxh{-(3z!U
z%mt{ood8173vH*<@o(AT?oD9_qUHJ?Rxi|{*!H`k*zg<gxW$$m7CUYYC*E@0PBCbQ
zHqKTAp3^BddSX+Af>@iD29wC8DN^!YvEhV{gf@;f+-B1jJ8t+tXFq9PCyl|?N@XQ~
z7I*R7KiEP%FH`c=;DOq^2F6a-n9U5QKE#tnr&66vsb3t+evqh)4&6Wpj)_xrD3kE}
zUvXn*?9B&Y@_V7jm^czACRT_O6XZ>DY{=~2jxl`X(v6IofcHj>n2?EKseimTV#I{;
z7?%7;kMVSMPe#^9t^J87oUTk3wI`?0j;?~LL_E!Qj{PTD6Hh-Sk1|la>f>?dX@3Xz
z3*z$;f7Js~FGYB&`##%mYW&A+w>17cwtE`?4coUho=x~v<JCOB*Z3~mKWn_Qe`Q{u
zuUcDLAB%lRWf|-KPcpC8bB}HMHy}~`{k{n$){6gw?Mtln{CVbSPonz*h2CyAbZV%>
zps(8sg<>a!0^Ms+sP%eK2t>yzG(>Hyg*SE6$1#bWS}hRUM~0oi@mk_&NXPYr3c(Tz
z5?z&c-S2h<{<jo7KNJPLo9tfb)HgY?Xjhwo(-l0C|EOj$p4Le1lS)@+pw6@6$u}zV
zXb`90Ja0vvB3O?<gJbj_{M&fie?2FaQ}uJ&pk~Ui47wf56cmv*FG!mMCUA`W)H{ox
zIZ{^fspq5tpUKaq*Wp9=eI18%j=WFt;aoTjl}Pt}1=+a%@5v8K{7&Y0>YpgR{|0h;
zP6}D!`Zvgki0)g(vAFuG&<4j+eY)55`ZtlIoT^WRQtoj5UlhSw)mQpm<m2M2e4zTD
z;D<?6oYM4F9~bY_q)>`|HF&Bxr9Z(Dg$GUuzU25QM_Bj$mN}m8!2K(ZUmh@hpw>^(
zUn3ybvLaY-u%kMswEpz(s^S$-{phtR#eJ@?&OiMx(7(1GPkXAryGTKq-=BFhBBIZq
R`ihI+;X-#Ku>|$_zX1}OT?haG
literal 0
HcmV?d00001
@@ -0,0 +1,24 @@
+struct C0
+{
+ int m0;
+ int m1;
+ int incorrectly_inserted;
+ unsigned rh_kabi_reserved1;
+ unsigned rh_kabi_reserved2;
+ unsigned rh_kabi_reserved3;
+ unsigned rh_kabi_reserved4;
+ unsigned rh_kabi_reserved5;
+};
+
+struct C1
+{
+ int m0;
+ char m1;
+ char wrongly_inserted;
+};
+
+int
+foo(struct C0 *c0, struct C1 *c1)
+{
+ return c0->m0 + c1->m0;
+}
new file mode 100644
GIT binary patch
literal 3688
zcmc&$O=u)l5U!q{PC7gJnPieRF)NvfvOm}}nIx`pm#mRtcM}wqm1Ph9Bt0{4X4=g3
zEIplUl4V^_;u3@v1O<OU(1SO@g9kkbg5XUALGa>b?<;r+c+jdh^(LK{CWsz<(67Gw
zs_NDI>*~IJ@!3lW!vNI`xB&Z_Vgc%X`*=yhB^ZSaTwT6%Z~4xxz2!R__m_7s?(L?r
zzrPE{kFR_;i33?+*yP?z-9ywx+lh!`7H1%9yoXGpIRj=dA%q1;N|=<hvLv=8?&<#+
zJ^Cf?l{hW2E%B(teG-pLd`#jKU?(ll4<VV9b25tsum^tPv_t!8(>9Tvw8IixsP!NR
zebrVAj4?S`(y6JX7#~t*t2_f~0*QC(R=EIE6B4gMPY!*1KBEX@0L;O2)5iJKlc|-=
zLJFOcu@5k2#xU(vs>4m&Mh0i}2&7UMQsy9LvDklljD|>z<IqEpnzmQauXosZbTE@L
zrzWR{jgj8;0{}LM;)(R-jHf0rS&FisoLI?_&(iqL1f_t-@JY}dK^~q&)Tu>w2?j5s
zw9xkqO2aVz92_7)yN(ZnDT0tNrV>M)VMztcfWEG3ju}?}*Vb6o8m?MKK9Rt<puW29
zmb}$Kv_-HfDv!g4-}Y+0sATB`FF$uRTP!@0EfjKdxk7e!W_Gqvm@Q;aT|tLsH)Mk|
ze>&?l!wp|7)`TwtuZ*f2l<SLI3um3P^UmgM)~Ugbpyk&Z+pC_B$wE;9J$nH>zuXD}
zQ4WuCn>`dbe~6iba@`FeUvD)<zS63^=H+W%m~VI`TyD+v8u_3eI=Ds=_--R#X^V9c
z3Su4F5QjG;ABuL^&R5*fmC!+3#j92wvE_w8M#pV5S~r|<`?|oOn%DB3&AD9pf6RQ;
ztl)C7crJSi&-L^_I8=FuMrDteZ08CXTWMpmzt_Htw~cP9x~)<^J(zwoQ5@*Gh7KGP
zC+MOk;rGAdY-Vg_1Tgts(PK=s#5EH$#5EISbva}*JJmCWj}+yI)dZ|1G0lYj7?$Rb
zwIrsQFcia*|G*)hO8ZD;f7IR|c?+qGa#Lq=4E5+Ps7%DuYNyzLgeCFxyvq7<jb{}e
zWI*TJtvQI#Fi&HsIS}=Hgr~fBS$|36UuV6h@v_1r*VgzSSii0DU$MTc@vOop8n4#>
zy~a0L|5@XIW&IvYeIL}G(>_@2Ln6&s_kWmq@~3Bqb^3BpQ~WO-6$&gB{|D>mS?c3w
znWwXgo)_fW+s)7|p$vnLtSc0Xtq^il4Ix)*w;>mZhMTL1(nbxddbNc%iQQ5u5Ss_g
zZs7VgaWJIe`9g(Y3I&N?m3q0=Yzq7i<@{DCa#*#TcIcMZd0<grtp;vW@IwBhn8bM6
zBXv${xFrVN_l<S(jkal2h|??5%TcEY*5gm2joy!c8&Bu2k4foN{>~o)F`cIS(!HXp
zxzsUt`?q*Q-r#^?w2+^Am+_ZKwngmqG0AX~$q%I0ey97sfF_+I@8f(qXZAxS(tV#n
zHg5hlPgKRz{OP|`pMM28eN3d_66e20N~Gz&t7wbMzrcysIF|BLz0>nwM~=o+^F%1y
zN1XpR)|F8CmAr|DxcFOqp*p|rDtdpdDxT_MT>RU#C~WzT==Lg3$#>DBaMuaJHyj`3
z2<yI|GsnyAx_`^@3tgrI)cz^@Qv~F?qzIPpv!lAFwEy(gRq=|a`RKW6h&|3<=Lyqy
mfxhN?Je{fj?ji+i{QgXn5^4JSX<l*hUvQ!?Be4Ya_`d<0OK8jh
literal 0
HcmV?d00001
@@ -0,0 +1,23 @@
+struct C0
+{
+ int m0;
+ int m1;
+ int correctly_inserted1;
+ unsigned rh_kabi_reserved2;
+ int correctly_inserted2;
+ int correctly_inserted3;
+ unsigned rh_kabi_reserved5;
+};
+
+struct C1
+{
+ int m0;
+ char m1;
+ char wrongly_inserted;
+};
+
+int
+foo(struct C0 *c0, struct C1 *c1)
+{
+ return c0->m0 + c1->m0;
+}
new file mode 100644
GIT binary patch
literal 3640
zcmc&$O>7%g5T57tCYw4xPHZ3{MRpLVKVt3J4JD*%35rS+fdCa%J@AvR?Pq(5f1>p!
zO@g4DkfK~#1P25cq#oeR1;G&s35f&T%8d*6B5|n10cM`(Ih)s2h2X$Q`{tW(X5PHN
zeY-a<zVt#u2+$(n0vuYJ1y~$8#LEgULl!b{Wp)3z)%|zxt?qB#T|KyX?;wrs-2)Im
zz4_e)c4UKaD14Zj$Eb<Q@rYrq%)@bUfJ~x257satge6ESm{g;(6?POJ8vPI>Mim}b
zd|F{g;jF?VDrOp-r0sV?NG8=dtd$Ztqu+C>aTTvhO*lmMOQjXI(HcSyM(W)zh^!hQ
z*(7@S;xihNU7d$CfyAw*T`fUwOyO%VRKVDwPbfo-fi=D~C(fmwO|4}XQy7elbA+)n
z!g5lnJ~!ux436jtNTn{MtZ}SjbNpPEx=2i8*AtMMbJj3!cv3t$o=I7`+1#X<8csg~
z;BYGL!bm|pH-p7eRQ<%vT83hlr}t*41U!XLg2o7H!xW-MPjWyocn!6Uv8PcBA^sd6
zBSou@4}u&)NQhiwqTel<U<()-m{wNUqu<&O)$Pf;EsBW*<^|354X@&_2eK!FZCQI7
zwmLn((UG-0?ck-CujE%s&*V#`!kI!TU!E_QOQmutfATU0ta>3k+=Wwlw;gVE<oSl|
z$iT0n=>^s1`JKhH?%4%*yPS6$a6RaD8m--Rzk|g>Sp&0r8LHhNkkv2}REpu^;?6*|
z=><@1cH6R8>(<`(iw!?4w)_gtui^QvV$cj-oRkbYUaMH^$qgAwVqIDRmsg+|%3jzj
z*1XVD&_!R(uh(6<<A*>_*K4)9*WGY;Q({uX?{?hng+ldzto)!+!KIazrTj_U$W#Ad
z7uBJ`Cd)wVT?Vm}7PF(n&P_aFbUO73Rr>ky^aqKRv7xINpp#=X9nK{D{#T3(tk@e6
zkRP1fBWV_T;>5xVabkhGQSNhD{aZ4Ik6gYHuLXF2#E1o>F)WQA?~fR<U?PU4__6zV
zy27U->!a8Hfd`SUP8Pi<$Iy<hg04h7%{IsJQ>=-n=PkA$Hh4DSQ3kZX(cL;7iPvKw
z>Xisjb#Jo$y1~E4cEjLrv)wcJui3s~@NB}z2CwJ&jls9s{=wjXWcwG^=6v<q(wf;E
zLn_VKjDMVYz0P}V(^r8+^LP3tlvr#254O*-Hv7*rPkR#G7bx_0+o4xM9R_{f)F_lY
zAr$E1gF>a(gF+x%UZEx{TMfLi>s|CI>{Tj(+&<#=0<Y7MM^jpUN9q(Tp&`-h%C2_X
zZHeEQLZ=(b0$xyVFZ8M#+_7w~*8{IDc_RN&&0;>Sk=`fW-7<s0d&M@zMr95S;>?@p
zjc8B=oB1cuNAJPE&8Pi0`=oNZe#USbruy5U+i{taBC^Q~(&U6m^iiCCXYqGO$$4ze
zKFQH#@>3Oc*qE`eqRZqc`WPS1`NLF&%-9!^jT`?R^@9nZ^J)A<nd7e^XZDE{EOGs-
zWJJV_T}NMBeTNHO<6Npw_nKLM6FKTrj}xJiTU`HVO|aJWwSEWrxcmwqsQ$0`VJA9I
zYx=v7%MWN$D8;@Sv^r1gkI<v>APB+doFC-~o3URq$I~5zf5G{S1Evr3`f2($0t#K$
z1nVXT>T^o#PhVG^uX!4eS)01}mFw&CPu~UlYMc4Ar{=qh6s+?5Ge<^5%=y!};_~0;
MLSIF437YwT1884f`v3p{
literal 0
HcmV?d00001
@@ -0,0 +1,24 @@
+struct C0
+{
+ int m0;
+ int m1;
+ int correctly_inserted1;
+ unsigned rh_kabi_reserved2;
+ int correctly_inserted2;
+ int correctly_inserted3;
+ unsigned rh_kabi_reserved5;
+ int incorrectly_inserted;
+};
+
+struct C1
+{
+ int m0;
+ char m1;
+ char wrongly_inserted;
+};
+
+int
+foo(struct C0 *c0, struct C1 *c1)
+{
+ return c0->m0 + c1->m0;
+}
new file mode 100644
GIT binary patch
literal 3696
zcmc&$O>7%g5T57F#!j6dCuvGUisB$pf5h5x`a@{dVidJa1Oil4^}tWMwx8`K_BvW`
z(liwm2??pnB?u%A{0OA>z?n-WZXh8J91s!`R}SS|Bo380z|7lu&gNxRAviG7zWL^R
zGjHDC&hE|gFI-3o0a^r{gB?q=0ILH#xU66q_QN<_Uc7a0@zz@p7H_THU)(zXU@M31
z{VfnbzW(hL4rGJKkb9b%$Eb<Rp_pMU%tBs#giNYE3s#yC!V>f;*r#S?E1XfdfABN(
z7*sf|_?*HSh4(8wpnMK0yif6mAk$}ieh7ViYEITd2{J=JaoQ2(qtfOwL`G>x6}Hjp
zM-B$+oeqczHCeJr^isqpl-aJ%LXJS{{ia<l!StlUSE0XvzWsM7LJWa5e0oNl$v%@^
z8lTUiGcuW7j5RK-Og0;FGZ`_CGkOBD*>hQI7_->yKQlo?qz>ZHBaofRETLa|R6IF6
zp0%c@rboqCI`;@bhC}g01`6WYNlccd?1v|p#>uCAaC4GUz*G37XpW!`Pa$gbB6|db
zS5VvNdknP@;?LnBQnc&%AebfyDKVWIiH0Q;Yyks3)0z<W;Mev<-5#ymqL@lyT+m!z
zaVy?(AiFYHm$j3y=6Ah@FKc-^!HX|m&M%an&X-Ds<AqXwZgy_2RGKU0k6c2BMK|OQ
z=fu&x(+<~sdA1>a8F*DR-Jse$yD@*tId#HWpUXQ9xE6H$M(g^r=VP)^*1*g@2h~mx
z$Z8mKDkX49e#gP{_eMjt=>|}2cG|L7>(t)#iVZI;w!8{1y5V}QV$cj7T&WCvw^gil
z<%$d?u?}sE!`o5}WjE{=Yi{T&=wM&XtJfX5;e|k*j@xQ=t~ufLRf$0juj4!GCkxg8
zG4sP_1s4|<PUnx{=^p(DN2_iUU@eM7Y+eGfkrPvc>C86XI=Zp?)++tnaPGa-!chMe
zbl{jIMHjXYe*Y_}&q}P202aS9W{ibBNn&A!B(XqMnLS-rR7Df`SaFW^T7WerK`a<d
zU}^qXQxe32kp!0fhxYJP;>Tk9qxb%y_mIjdi$0TmXvcR!XCj_fJI(%Mtcj=R4Ym&$
zJe%++13KSc?LmBuc^X5{fvA^aJmuYH`&EN~o9%|d-)6gO@ORn1Y4B{qmcjqP_7?`P
z*Z-Ztx7q&L;D2TN9&2+S^q$i`*z7|p$Jq3LoO$x6XOnIEf{<wbm&k+?Yt8?`_8HdZ
z_<82(tm5Ydh3@rs=vGjNL8O}+g>oZ=0@Xt(RJvU#1hVB8YO=D{!0KM_V4uQnr4q>X
zUEOZr`VF}|q~-ZihhPc~iC$KAwbO1({2mqjPACglx14V1R#$jn*<7v%Zd>v~{-c`0
zc-kX<PI|a9gWmhbHu=V71`XoOiu79CDTdAX!`Mgf$G?rI^Ebz&bUJ_Zr$9_3rZ3$q
zs+#4fyVq{>hP=Z8qu4`!`d!9fBPD0CHOHim8%%zzymlJX_hsxdIr2WhmveR}R3X#%
zd1RC3pW}(@c$z=`pPKWpA!m+>6kOo^SICHo>AQ@5N%_m1=qkrjeyVq7{#E2?Og&G8
zN<QWMziEQC&ad?i<dfpx<qH-4!tV^C<Fux_m=ym3EefR=sa~t&wEhr#H10Ve_=e--
z9AVS<OXhgFJ@@Z9e!j;<K<}TXZzCYrvL;x6&W`$?(*Dy|SI29f=40koLvXQf@`UNT
lKwon+p3c;KcPYNf@6QYwF)`Oq^Gb@p%Za{<#S%2*{|4n9YbO8z
literal 0
HcmV?d00001
@@ -0,0 +1,7 @@
+[allow_type]
+ kind = struct
+ has_data_member_inserted_between = {offsetof(rh_kabi_reserved1), end}
+
+[allow_type]
+ kind = union
+ has_data_member_inserted_between = {offsetof(rh_kabi_reserved1), end}
new file mode 100644
@@ -0,0 +1,7 @@
+[allow_type]
+ type_kind = struct
+ has_data_member_regexp = rh_kabi_reserved
+
+[suppress_type]
+ type_kind = struct
+ has_data_member_inserted_between = {offset_of(rh_kabi_reserved1), end}
@@ -493,6 +493,193 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/PR30048-test-2-report-1.txt",
"output/test-abidiff-exit/PR30048-test-2-report-1.txt"
},
+ {
+ "data/test-abidiff-exit/test-allow-type-array-v0.o",
+ "data/test-abidiff-exit/test-allow-type-array-v1.o",
+ "",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-array-v0--v1-report-1.txt",
+ "output/test-abidiff-exit/test-allow-type-array-v0--v1-report-1.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-array-v0.o",
+ "data/test-abidiff-exit/test-allow-type-array-v1.o",
+ "data/test-abidiff-exit/test-allow-type-array-suppr.txt",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_OK,
+ "data/test-abidiff-exit/test-allow-type-array-v0--v1-report-2.txt",
+ "output/test-abidiff-exit/test-allow-type-array-v0--v1-report-2.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-array-v0.o",
+ "data/test-abidiff-exit/test-allow-type-array-v2.o",
+ "",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-array-v0--v2-report-1.txt",
+ "output/test-abidiff-exit/test-allow-type-array-v0--v2-report-1.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-array-v0.o",
+ "data/test-abidiff-exit/test-allow-type-array-v2.o",
+ "data/test-abidiff-exit/test-allow-type-array-suppr.txt",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-array-v0--v2-report-2.txt",
+ "output/test-abidiff-exit/test-allow-type-array-v0--v2-report-2.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-array-v0.o",
+ "data/test-abidiff-exit/test-allow-type-array-v3.o",
+ "",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-array-v0--v3-report-1.txt",
+ "output/test-abidiff-exit/test-allow-type-array-v0--v3-report-1.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-array-v0.o",
+ "data/test-abidiff-exit/test-allow-type-array-v3.o",
+ "data/test-abidiff-exit/test-allow-type-array-suppr.txt",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_OK,
+ "data/test-abidiff-exit/test-allow-type-array-v0--v3-report-2.txt",
+ "output/test-abidiff-exit/test-allow-type-array-v0--v3-report-2.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v1.o",
+ "",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v1-report-1.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v1-report-1.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v1.o",
+ "data/test-abidiff-exit/test-allow-type-region-suppr.txt",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_OK,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v1-report-2.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v1-report-2.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v2.o",
+ "",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v2.o",
+ "",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v2.o",
+ "data/test-abidiff-exit/test-allow-type-region-suppr.txt",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v2-report-2.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v2-report-2.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v3.o",
+ "",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v3-report-1.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v3-report-1.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v3.o",
+ "data/test-abidiff-exit/test-allow-type-region-suppr.txt",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v3-report-2.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v3-report-2.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v4.o",
+ "",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v4-report-1.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v4-report-1.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v4.o",
+ "data/test-abidiff-exit/test-allow-type-region-suppr.txt",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_OK,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v4-report-2.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v4-report-2.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v5.o",
+ "",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v5-report-1.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v5-report-1.txt"
+ },
+ {
+ "data/test-abidiff-exit/test-allow-type-region-v0.o",
+ "data/test-abidiff-exit/test-allow-type-region-v5.o",
+ "data/test-abidiff-exit/test-allow-type-region-suppr.txt",
+ "",
+ "",
+ "--no-default-suppression",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abidiff-exit/test-allow-type-region-v0--v5-report-2.txt",
+ "output/test-abidiff-exit/test-allow-type-region-v0--v5-report-2.txt"
+ },
#ifdef WITH_BTF
{
"data/test-abidiff-exit/btf/test0-v0.o",