From: Dodji Seketeli <dodji@redhat.com>
To: Dodji Seketeli <dodji@redhat.com>
Cc: libabigail@sourceware.org, ckalina@redhat.com
Subject: [PATCH 03/13] suppression: Factorize out is_data_member_offset_in_range
Date: Thu, 02 Mar 2023 19:57:18 +0100 [thread overview]
Message-ID: <87pm9rq8vl.fsf_-_@redhat.com> (raw)
In-Reply-To: <87356nrnmq.fsf@redhat.com> (Dodji Seketeli's message of "Thu, 02 Mar 2023 19:53:17 +0100")
Hello,
In preparation of subsequent changes, this patch factorizes a function
is_data_member_offset_in_range() out of
type_suppression::suppression(). This is useful to determine if a
data member offset is within an "offset range" expressed by the
type_suppression::insertion_range type.
This function is useful to implement the
offset_of_first_data_member_regexp and
offset_of_last_data_member_regexp properties to come in subsequent
patches.
Please note that is_data_member_offset_in_range works on data members
of unions and classes, not just on classes like what the original code
of inside type_suppression::suppresses_diff was doing.
This patch should not have any functional impact on the code.
* include/abg-fwd.h (get_last_data_member)
(get_next_data_member_offset): Declare functions.
* src/abg-ir.cc (get_next_data_member): Add an overload for
class_or_union and write the overload for class_or_union_sptr in
term of the former.
(get_last_data_member): Add overloads form class_or_union& and
class_or_union*. Write the overload for class_or_union_sptr in
terms of the one for class_or_union*.
(get_next_data_member_offset): Add an overload for
class_or_union* and write the overload for class_or_union_sptr in
terms of the former.
* include/abg-suppression.h
(type_suppression::insertion_range::eval_boundary): Take a
class_or_union* for the context, as opposed to a class_decl_sptr.
This makes this static function work for unions as well.
(is_data_member_offset_in_range): Declare new function.
* src/abg-suppression.cc (type_suppression::suppression_diff):
Factorize ...
(is_data_member_offset_in_range): ... this function out.
(type_suppression::insertion_range::eval_boundary): Adjust this to
make it take a class_or_union* rather than a class_decl_sptr.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
include/abg-fwd.h | 11 ++++
include/abg-suppression.h | 12 +++-
src/abg-ir.cc | 57 +++++++++++++++++-
src/abg-suppression.cc | 122 ++++++++++++++++++++------------------
4 files changed, 138 insertions(+), 64 deletions(-)
diff --git a/include/abg-fwd.h b/include/abg-fwd.h
index 155642f0..4051fab5 100644
--- a/include/abg-fwd.h
+++ b/include/abg-fwd.h
@@ -655,6 +655,12 @@ is_data_member(const decl_base *);
const var_decl_sptr
get_next_data_member(const class_or_union_sptr&, const var_decl_sptr&);
+var_decl_sptr
+get_last_data_member(const class_or_union&);
+
+var_decl_sptr
+get_last_data_member(const class_or_union*);
+
var_decl_sptr
get_last_data_member(const class_or_union_sptr&);
@@ -740,6 +746,11 @@ get_data_member_offset(const decl_base_sptr);
uint64_t
get_absolute_data_member_offset(const var_decl&);
+bool
+get_next_data_member_offset(const class_or_union*,
+ const var_decl_sptr&,
+ uint64_t&);
+
bool
get_next_data_member_offset(const class_or_union_sptr&,
const var_decl_sptr&,
diff --git a/include/abg-suppression.h b/include/abg-suppression.h
index 27f52110..b13bb9fb 100644
--- a/include/abg-suppression.h
+++ b/include/abg-suppression.h
@@ -346,9 +346,9 @@ public:
create_fn_call_expr_boundary(const string&);
static bool
- eval_boundary(boundary_sptr boundary,
- class_decl_sptr context,
- uint64_t& value);
+ eval_boundary(const boundary_sptr boundary,
+ const class_or_union* context,
+ uint64_t& value);
static bool
boundary_value_is_end(uint64_t value);
@@ -899,6 +899,12 @@ is_type_suppressed(const fe_iface& fe,
const location& type_location,
bool& type_is_private,
bool require_drop_property = false);
+
+bool
+is_data_member_offset_in_range(const var_decl_sptr&,
+ const type_suppression::insertion_range_sptr&,
+ const class_or_union*);
+
} // end namespace suppr
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index 321adbf5..ef19eb41 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -5752,7 +5752,7 @@ get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
/// @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,
+get_next_data_member(const class_or_union *klass,
const var_decl_sptr &data_member)
{
if (!klass ||!data_member)
@@ -5773,12 +5773,40 @@ get_next_data_member(const class_or_union_sptr &klass,
return var_decl_sptr();
}
+/// 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)
+{return get_next_data_member(klass.get(), data_member);}
+
+/// Get the last data member of a class type.
+///
+/// @param klass the class type to consider.
+var_decl_sptr
+get_last_data_member(const class_or_union& klass)
+{return klass.get_non_static_data_members().back();}
+
+/// Get the last data member of a class type.
+///
+/// @param klass the class type to consider.
+var_decl_sptr
+get_last_data_member(const class_or_union* klass)
+{return get_last_data_member(*klass);}
+
/// Get the last data member of a class type.
///
/// @param klass the class type to consider.
var_decl_sptr
get_last_data_member(const class_or_union_sptr &klass)
-{return klass->get_non_static_data_members().back();}
+{return get_last_data_member(klass.get());}
/// Test if a decl is an anonymous data member.
///
@@ -6062,7 +6090,7 @@ get_data_member_offset(const decl_base_sptr d)
/// @return true iff the data member coming right after @p dm was
/// found.
bool
-get_next_data_member_offset(const class_or_union_sptr& klass,
+get_next_data_member_offset(const class_or_union* klass,
const var_decl_sptr& dm,
uint64_t& offset)
{
@@ -6073,6 +6101,29 @@ get_next_data_member_offset(const class_or_union_sptr& klass,
return true;
}
+/// Get the offset of the non-static data member that comes after a
+/// given one.
+///
+/// If there is no data member after after the one given to this
+/// function (maybe because the given one is the last data member of
+/// the class type) then the function return false.
+///
+/// @param klass the class to consider.
+///
+/// @param dm the data member before the one we want to retrieve.
+///
+/// @param offset out parameter. This parameter is set by the
+/// function to the offset of the data member that comes right after
+/// the data member @p dm, iff the function returns true.
+///
+/// @return true iff the data member coming right after @p dm was
+/// found.
+bool
+get_next_data_member_offset(const class_or_union_sptr& klass,
+ const var_decl_sptr& dm,
+ uint64_t& offset)
+{return get_next_data_member_offset(klass.get(), dm, offset);}
+
/// Get the absolute offset of a data member.
///
/// If the data member is part of an anonymous data member then this
diff --git a/src/abg-suppression.cc b/src/abg-suppression.cc
index 5fcdef97..b596e0d5 100644
--- a/src/abg-suppression.cc
+++ b/src/abg-suppression.cc
@@ -865,65 +865,19 @@ type_suppression::suppresses_diff(const diff* diff) const
const class_decl_sptr& first_type_decl =
klass_diff->first_class_decl();
- for (string_decl_base_sptr_map::const_iterator m =
- klass_diff->inserted_data_members().begin();
- m != klass_diff->inserted_data_members().end();
- ++m)
+ // All inserted data members must be in an allowed
+ // insertion range.
+ for (const auto& m : klass_diff->inserted_data_members())
{
- decl_base_sptr member = m->second;
- size_t dm_offset = get_data_member_offset(member);
+ decl_base_sptr member = m.second;
bool matched = false;
- for (insertion_ranges::const_iterator i =
- get_data_member_insertion_ranges().begin();
- i != get_data_member_insertion_ranges().end();
- ++i)
- {
- type_suppression::insertion_range_sptr range = *i;
- uint64_t range_begin_val = 0, range_end_val = 0;
- if (!type_suppression::insertion_range::eval_boundary
- (range->begin(), first_type_decl, range_begin_val))
- break;
- if (!type_suppression::insertion_range::eval_boundary
- (range->end(), first_type_decl, range_end_val))
- break;
-
- uint64_t range_begin = range_begin_val;
- uint64_t range_end = range_end_val;
-
- if (insertion_range::boundary_value_is_end(range_begin)
- && insertion_range::boundary_value_is_end(range_end))
- {
- // This idiom represents the predicate
- // "has_data_member_inserted_at = end"
- if (dm_offset >
- get_data_member_offset(get_last_data_member
- (first_type_decl)))
- {
- // So the data member was added after
- // last data member of the klass. That
- // matches the suppr spec
- // "has_data_member_inserted_at = end".
- matched = true;
- continue;
- }
- }
-
- if (range_begin > range_end)
- // Wrong suppr spec. Ignore it.
- continue;
-
- if (dm_offset < range_begin || dm_offset > range_end)
- // The offset of the added data member doesn't
- // match the insertion range specified. So
- // the diff object won't be suppressed.
- continue;
-
- // If we reached this point, then all the
- // insertion range constraints have been
- // satisfied. So
+ for (const auto& range : get_data_member_insertion_ranges())
+ if (is_data_member_offset_in_range(is_var_decl(member),
+ range,
+ first_type_decl.get()))
matched = true;
- }
+
if (!matched)
return false;
}
@@ -1404,9 +1358,9 @@ type_suppression::insertion_range::create_fn_call_expr_boundary(const string& s)
/// @return true iff the evaluation was successful and @p value
/// contains the resulting value.
bool
-type_suppression::insertion_range::eval_boundary(boundary_sptr boundary,
- class_decl_sptr context,
- uint64_t& value)
+type_suppression::insertion_range::eval_boundary(const boundary_sptr boundary,
+ const class_or_union* context,
+ uint64_t& value)
{
if (integer_boundary_sptr b = is_integer_boundary(boundary))
{
@@ -4962,5 +4916,57 @@ is_type_suppressed(const fe_iface& fe,
return false;
}
+/// Test if a data memer offset is in a given insertion range.
+///
+/// @param dm the data member to consider.
+///
+/// @param range the insertion range to consider.
+///
+/// @param the class (or union) type to consider as the context in
+/// which to evaluate the insertion range denoted by @p range.
+///
+/// @return true iff the offset of the data member @p dm is in the
+/// insertion range @p range in the context of the type denoted by @p
+/// context.
+bool
+is_data_member_offset_in_range(const var_decl_sptr& dm,
+ const type_suppression::insertion_range_sptr& range,
+ const class_or_union* context)
+{
+ ABG_ASSERT(dm && range && context);
+
+ uint64_t range_begin = 0, range_end = 0;
+ if (!type_suppression::insertion_range::eval_boundary (range->begin(),
+ context,
+ range_begin))
+ return false;
+
+ if (!type_suppression::insertion_range::eval_boundary (range->end(),
+ context,
+ range_end))
+ return false;
+
+ if (range_begin > range_end)
+ // wrong range, ignore it.
+ return false;
+
+ uint64_t dm_offset = get_data_member_offset(dm);
+ if (type_suppression::insertion_range::boundary_value_is_end(range_begin)
+ && type_suppression::insertion_range::boundary_value_is_end(range_end))
+ {
+ // This idiom represents the predicate
+ // "has_data_member_inserted_at = end"
+ if (dm_offset > get_data_member_offset(get_last_data_member(context)))
+ return true;
+ return false;
+ }
+
+ if (dm_offset < range_begin || dm_offset > range_end)
+ // The offset of the data member is outside the range.
+ return false;
+
+ return true;
+}
+
}// end namespace suppr
} // end namespace abigail
--
2.39.2
next prev parent reply other threads:[~2023-03-02 18:57 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <877cvzrnws.fsf@redhat.com>
2023-03-02 18:53 ` [PATCH 00/13] Support negative suppression specifications Dodji Seketeli
2023-03-02 18:55 ` [PATCH 01/13] ini: Fix parsing list property values Dodji Seketeli
2023-03-02 18:56 ` [PATCH 02/13] suppr: Support has_data_member and has_data_member_regexp properties Dodji Seketeli
2023-03-02 18:57 ` Dodji Seketeli [this message]
2023-03-02 18:58 ` [PATCH 04/13] suppression: Support the has_size_change property for suppress_type Dodji Seketeli
2023-03-02 18:59 ` [PATCH 05/13] suppression: Support offset_of_{first,last}_data_member_regexp offset selectors Dodji Seketeli
2023-03-02 18:59 ` [PATCH 06/13] comparison, suppression: Support [allow_type] directive Dodji Seketeli
2023-03-02 19:00 ` [PATCH 07/13] Misc white space fixes Dodji Seketeli
2023-03-02 19:01 ` [PATCH 08/13] abidiff: Add extensive logging Dodji Seketeli
2023-03-02 19:01 ` [PATCH 09/13] tools-utils: Support kernel stablelist Dodji Seketeli
2023-03-02 19:02 ` [PATCH 10/13] comp-filter: Don't re-visit node while applying filters to diff nodes Dodji Seketeli
2023-03-02 19:03 ` [PATCH 11/13] comparison: Add a mode to not apply filters on interface sub-graphs Dodji Seketeli
2023-03-02 19:04 ` [PATCH 12/13] comparison: When marking leaf nodes don't do unnecessary impact analysis Dodji Seketeli
2023-03-02 19:05 ` [PATCH 13/13] comp-filter: Speed up harmless/harmful categorization Dodji Seketeli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87pm9rq8vl.fsf_-_@redhat.com \
--to=dodji@redhat.com \
--cc=ckalina@redhat.com \
--cc=libabigail@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).