From patchwork Tue Dec 7 17:42:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 48590 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D373E3858434 for ; Tue, 7 Dec 2021 17:42:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D373E3858434 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1638898939; bh=GTDbzN3CbJZgowWdQ/H3pjmCtA1yUUTXE+uMdwQgR1k=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:From; b=vtWr7NX8hMu0MufqkP/efXk4UBREJS1grMEt9QTZPbBS+Jllrvh+PSmtIyBfbtIte H9lL8Ojh95tMxqZSYUfx6G83VgfS6QJNdIrf5wZLGhxgoaiJfVAC4/cCRvcQRe8gpJ SqmLy4Ep9HnyKOG5B+bIWuaqc6jiFmC7v9QeTi2w= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.153.124]) by sourceware.org (Postfix) with ESMTPS id 0E63E3858D3C for ; Tue, 7 Dec 2021 17:42:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0E63E3858D3C Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-4-_v-xXyLIMXCFQqDFvKnqeQ-1; Tue, 07 Dec 2021 12:42:07 -0500 X-MC-Unique: _v-xXyLIMXCFQqDFvKnqeQ-1 Received: by mail-qt1-f198.google.com with SMTP id h8-20020a05622a170800b002acc8656e05so18430725qtk.7 for ; Tue, 07 Dec 2021 09:42:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:organization:date:message-id :user-agent:mime-version; bh=GTDbzN3CbJZgowWdQ/H3pjmCtA1yUUTXE+uMdwQgR1k=; b=WcMLiFeQo7E02j92GgdR73yffA1WF5NbSs1Ua3Y8dMMDmkRMGLoUaNHg2yXd5SqOsi 7rd73Zh8JTXIgW6ErezRO3GyAKDDuFZS+VmdAimRU5OHAVHnbMHByWqT23Go9m3W6z3X gGM84IXYIjcN1AasBC0abjaLmJ7llH4hoXzCe5l1UhX/K2vndih7wsM9HxHnjkDRvV8G kWuFxpMQlvQXv4vnAA1jsCz8kOmu0ybmDJb7aBOKiHQEvBknp3v0fu7f8sHPLZbf0bQc z+5NJLfxdBZxTPTyrg3/oX7pSykD5KFem9+5lQoscH0W3+wcW75pMO7P6leJNRXlvmfy mgIQ== X-Gm-Message-State: AOAM532AWSpCeYYx/fbx9AlNCoiNCvmuq9O7ZQblw/+I7ifugqK4cSNL vV2LnsCCjN5sm02k280CcFnsFYSvTmdZSyeyqZxMv8/XkCJ9dUFcRuFwRdOPdNk3i1Zlw2pBDLQ 5qpoks8ie7PmuVfuCuxxBp2TKNArHYHh3OtpeG6XWge5/HISkk74CiuTdUd1UGJH4c66x X-Received: by 2002:ad4:5aa5:: with SMTP id u5mr703279qvg.99.1638898925753; Tue, 07 Dec 2021 09:42:05 -0800 (PST) X-Google-Smtp-Source: ABdhPJysUkuJGUBYp+6ufuI9vVL0RwpprxKXY5kOhET6fvn91A05K58ziWJT5h3Xrz/9Azgn6Gxt4w== X-Received: by 2002:ad4:5aa5:: with SMTP id u5mr703155qvg.99.1638898924806; Tue, 07 Dec 2021 09:42:04 -0800 (PST) Received: from localhost ([88.120.130.27]) by smtp.gmail.com with ESMTPSA id x13sm155878qkp.102.2021.12.07.09.42.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Dec 2021 09:42:04 -0800 (PST) Received: by localhost (Postfix, from userid 1000) id 50AE05802BD; Tue, 7 Dec 2021 18:42:02 +0100 (CET) To: libabigail@sourceware.org Subject: [PATCH, applied] suppression: Fix has_data_member_inserted_between = {offset_of(), offset_of()} Organization: Red Hat / France X-Operating-System: Fedora 36 X-URL: http://www.redhat.com Date: Tue, 07 Dec 2021 18:42:02 +0100 Message-ID: <875ys0s45x.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_LOTSOFHASH, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libabigail@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Dodji Seketeli via Libabigail From: Dodji Seketeli Reply-To: Dodji Seketeli Errors-To: libabigail-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libabigail" Hello, This should fix bug https://sourceware.org/bugzilla/show_bug.cgi?id=28073 There is at least a case where the evaluation of the suppression specification rule incarnated by the property has_data_member_inserted_between doesn't work. This is in the context of the following suppression specification: [suppress_type] name = struct_foo has_data_member_inserted_between = {offset_of(dm1), offset_of(dm2)} The evaluation of the rule incarnated by has_data_member_inserted_between fails in the context of a type change where the data member "dm1" is removed from the type struct_foo. In that case, the evaluation of the suppression should ALWAYS yield to the suppression specification NOT suppressing the change. But in some cases the change is suppressed nonetheless. This patch fixes that. The idea of the patch is that if the class has a removed data member or if its size shrinks then no type change on that class can be suppressed. This is because those two kinds of change are incompatible ABI (or at least API) changes. So they should be reported. The patch also fixes the evaluation of the boundaries of the insertion range expressed as an "offset_after" expression. * doc/manuals/libabigail-concepts.rst: Update the documentation to reflect that has_data_member* properties will never suppress any type change if the change carries a data member suppression or a type size reduction. * include/abg-fwd.h (get_last_data_member) (get_next_data_member_offset): Declare new functions. * include/abg-suppression.h (insertion_range::boundary_value_is_end): Declare new static member function. (type_supression::insertion_range::eval_boundary): Make this static function take an uint64_t rather than ssize_t. (type_suppression::insertion_range::integer_boundary::{integer_boundary, as_integer, operator int}): Make these member functions and operator take or return uint64_t rather than int. * src/abg-ir.cc (get_last_data_member) (get_next_data_member_offset): Define new functions. * src/abg-suppression.cc (type_suppression::suppresses_diff): Rework logic to better handle "has_data_member_inserted_*" properties in the context of class diffs. If the diff object carries data member removal or size reduction, the diff object is not suppressed by the current type suppression. Also, the property "has_data_member_inserted_at = end", is now represented by an insertion range where the beginning and the end of the range are both the max possible value of insertion range boundaries; the code is made to recognize that. (type_suppression::insertion_range::eval_boundary): Make this static function take an uint64_t rather than ssize_t. If the boundary is expressed as a "offset_after" expression, make sure the offset of the next data member is considered if it's present. (type_suppression::insertion_range::integer_boundary::{integer_boundary, as_integer, operator int}): Make these take or return uint64_t rather than int. (type_suppression::insertion_range::boundary_value_is_end): Define new member function. (type_suppression::insertion_range::integer_boundary::priv::value_): Turn the type of this into uint64_t, from int. (type_suppression::insertion_range::integer_boundary::priv::priv): The parameter of this is now uint64_t, from int. * tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.c: New test source code. * tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.o: New test binary. * tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.o.abi: New test input. * tests/data/test-diff-suppr/PR28073/PR28073-output-{1,2}.txt: New test reference output. * tests/data/test-diff-suppr/PR28073/PR28073.after.o: New test binary. * tests/data/test-diff-suppr/PR28073/PR28073.after.o.abi: New test input. * tests/data/test-diff-suppr/PR28073/PR28073.before.o: New test binary. * tests/data/test-diff-suppr/PR28073/PR28073.before.o.abi: New test input. * tests/data/test-diff-suppr/PR28073/PR28073.c: New test source code. * tests/data/test-diff-suppr/PR28073/bitfield.suppr: New test input. * tests/data/Makefile.am: Add the new test material to source distribution. * tests/test-diff-suppr.cc: Add the new test input to this test harness. Signed-off-by: Dodji Seketeli Applied to master. --- doc/manuals/libabigail-concepts.rst | 20 +- include/abg-fwd.h | 8 + include/abg-suppression.h | 11 +- src/abg-ir.cc | 36 ++++ src/abg-suppression.cc | 171 +++++++++++------- tests/data/Makefile.am | 11 ++ .../PR28073/PR28073-bitfield-removed.c | 14 ++ .../PR28073/PR28073-bitfield-removed.o | Bin 0 -> 3776 bytes .../PR28073/PR28073-bitfield-removed.o.abi | 29 +++ .../PR28073/PR28073-output-1.txt | 3 + .../PR28073/PR28073-output-2.txt | 14 ++ .../test-diff-suppr/PR28073/PR28073.after.o | Bin 0 -> 3848 bytes .../PR28073/PR28073.after.o.abi | 35 ++++ .../test-diff-suppr/PR28073/PR28073.before.o | Bin 0 -> 3768 bytes .../PR28073/PR28073.before.o.abi | 32 ++++ tests/data/test-diff-suppr/PR28073/PR28073.c | 24 +++ .../test-diff-suppr/PR28073/bitfield.suppr | 4 + tests/test-diff-suppr.cc | 20 ++ 18 files changed, 360 insertions(+), 72 deletions(-) create mode 100644 tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.c create mode 100644 tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.o create mode 100644 tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.o.abi create mode 100644 tests/data/test-diff-suppr/PR28073/PR28073-output-1.txt create mode 100644 tests/data/test-diff-suppr/PR28073/PR28073-output-2.txt create mode 100644 tests/data/test-diff-suppr/PR28073/PR28073.after.o create mode 100644 tests/data/test-diff-suppr/PR28073/PR28073.after.o.abi create mode 100644 tests/data/test-diff-suppr/PR28073/PR28073.before.o create mode 100644 tests/data/test-diff-suppr/PR28073/PR28073.before.o.abi create mode 100644 tests/data/test-diff-suppr/PR28073/PR28073.c create mode 100644 tests/data/test-diff-suppr/PR28073/bitfield.suppr diff --git a/doc/manuals/libabigail-concepts.rst b/doc/manuals/libabigail-concepts.rst index b11c2c87..c30e87e8 100644 --- a/doc/manuals/libabigail-concepts.rst +++ b/doc/manuals/libabigail-concepts.rst @@ -433,7 +433,11 @@ The potential properties of this sections are listed below: Suppresses change reports involving a type which has at least one data member inserted at an offset specified by the property value - ``offset-in-bit``. The value ``offset-in-bit`` is either: + ``offset-in-bit``. Please note that if a type has a change in which + at least one of its data members is removed or its size is reduced, + the type will *NOT* be suppressed by the evaluation of this property. + + The value ``offset-in-bit`` is either: - an integer value, expressed in bits, which denotes the offset of the insertion point of the data member, starting @@ -468,11 +472,14 @@ The potential properties of this sections are listed below: ``has_data_member_inserted_between`` ``=`` {<``range-begin``>, <``range-end``>} Suppresses change reports involving a type which has at least one - data mber inserted at an offset that is comprised in the range - between range-begin`` and ``range-end``. Please note that each of + data member inserted at an offset that is comprised in the range + between ``range-begin`` and ``range-end``. Please note that each of the values ``range-begin`` and ``range-end`` can be of the same form as the :ref:`has_data_member_inserted_at - ` property above. + ` property above. Please + also note that if a type has a change in which at least one of its + data members is removed or its size is reduced, the type will *NOT* be + suppressed by the evaluation of this property. Usage examples of this properties are: :: @@ -508,7 +515,10 @@ The potential properties of this sections are listed below: long as the system can cope with. The values of the boundaries of the ranges are of the same kind as for the :ref:`has_data_member_inserted_at - ` property above. + ` property above. Please + note that if a type has a change in which at least one of its data + members is removed or its size is reduced, the type will *NOT* be + suppressed by the evaluation of this property. Another usage example of this property is thus: :: diff --git a/include/abg-fwd.h b/include/abg-fwd.h index 63895314..36a99c3b 100644 --- a/include/abg-fwd.h +++ b/include/abg-fwd.h @@ -639,6 +639,9 @@ 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_sptr&); + bool is_anonymous_data_member(const decl_base&); @@ -721,6 +724,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_sptr&, + const var_decl_sptr&, + uint64_t&); + uint64_t get_var_size_in_bits(const var_decl_sptr&); diff --git a/include/abg-suppression.h b/include/abg-suppression.h index db0334e7..6c13e33d 100644 --- a/include/abg-suppression.h +++ b/include/abg-suppression.h @@ -328,7 +328,10 @@ public: static bool eval_boundary(boundary_sptr boundary, class_decl_sptr context, - ssize_t& value); + uint64_t& value); + + static bool + boundary_value_is_end(uint64_t value); }; // end class insertion_range type_suppression::insertion_range::integer_boundary_sptr @@ -360,9 +363,9 @@ class type_suppression::insertion_range::integer_boundary integer_boundary(); public: - integer_boundary(int value); - int as_integer() const; - operator int() const; + integer_boundary(uint64_t value); + uint64_t as_integer() const; + operator uint64_t () const; ~integer_boundary(); }; //end class type_suppression::insertion_range::integer_boundary diff --git a/src/abg-ir.cc b/src/abg-ir.cc index 17a62153..2cc4cf8c 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -5739,6 +5739,13 @@ get_next_data_member(const class_or_union_sptr &klass, return var_decl_sptr(); } +/// 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();} + /// Test if a decl is an anonymous data member. /// /// @param d the decl to consider. @@ -6003,6 +6010,35 @@ uint64_t get_data_member_offset(const decl_base_sptr d) {return get_data_member_offset(dynamic_pointer_cast(d));} +/// 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) +{ + var_decl_sptr next_dm = get_next_data_member(klass, dm); + if (!next_dm) + return false; + offset = get_data_member_offset(next_dm); + return true; +} + /// 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 d3343a81..48c73cf8 100644 --- a/src/abg-suppression.cc +++ b/src/abg-suppression.cc @@ -14,6 +14,7 @@ #include "abg-internal.h" #include +#include // ABG_BEGIN_EXPORT_DECLARATIONS @@ -773,67 +774,93 @@ type_suppression::suppresses_diff(const diff* diff) const d = is_type_diff(get_typedef_diff_underlying_type_diff(d)); } + // Now let's consider class diffs in the context of a suppr spec + // that contains properties like "has_data_member_inserted_*". + const class_diff* klass_diff = dynamic_cast(d); - if (// We are looking at a class diff ... - klass_diff - // ... that has inserted data members ... - && !get_data_member_insertion_ranges().empty() - // ... that has no deleted data members ... - && klass_diff->deleted_data_members().empty() - // ... and in which the class size hasn't shrunk (because, e.g, - // the base classes have changed). - && (klass_diff->first_class_decl()->get_size_in_bits() - <= klass_diff->second_class_decl()->get_size_in_bits())) + if (klass_diff) { - const class_decl_sptr& first_type_decl = klass_diff->first_class_decl(); - const class_decl_sptr& second_type_decl = klass_diff->second_class_decl(); - size_t first_type_size = first_type_decl->get_size_in_bits(); - size_t second_type_size = second_type_decl->get_size_in_bits(); - - for (string_decl_base_sptr_map::const_iterator m = - klass_diff->inserted_data_members().begin(); - m != klass_diff->inserted_data_members().end(); - ++m) + // We are looking at a class diff ... + if (!get_data_member_insertion_ranges().empty()) { - decl_base_sptr member = m->second; - size_t dm_offset = get_data_member_offset(member); - bool matched = false; - - for (insertion_ranges::const_iterator i = - get_data_member_insertion_ranges().begin(); - i != get_data_member_insertion_ranges().end(); - ++i) + // ... and the suppr spec contains a + // "has_data_member_inserted_*" clause ... + if (klass_diff->deleted_data_members().empty() + && (klass_diff->first_class_decl()->get_size_in_bits() + <= klass_diff->second_class_decl()->get_size_in_bits())) { - type_suppression::insertion_range_sptr range = *i; - ssize_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; - - unsigned range_begin = - (range_begin_val < 0) ? first_type_size : range_begin_val; - - unsigned range_end = - (range_end_val < 0) ? second_type_size : range_end_val; - - if (range_begin > range_end) - continue; - - if (range_begin_val < 0 || range_end_val < 0) + // That "has_data_member_inserted_*" clause doesn't hold + // if the class has deleted data members or shrunk. + + const class_decl_sptr& first_type_decl = + klass_diff->first_class_decl(); + const class_decl_sptr& second_type_decl = + klass_diff->second_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) { - if (dm_offset < range_begin) - continue; + decl_base_sptr member = m->second; + size_t dm_offset = get_data_member_offset(member); + 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 + matched = true; + } + if (!matched) + return false; } - else - if (dm_offset < range_begin || dm_offset > range_end) - continue; - - matched = true; } - if (!matched) + else return false; } } @@ -1311,7 +1338,7 @@ type_suppression::insertion_range::create_fn_call_expr_boundary(const string& s) bool type_suppression::insertion_range::eval_boundary(boundary_sptr boundary, class_decl_sptr context, - ssize_t& value) + uint64_t& value) { if (integer_boundary_sptr b = is_integer_boundary(boundary)) { @@ -1338,8 +1365,13 @@ type_suppression::insertion_range::eval_boundary(boundary_sptr boundary, if (fn_call->get_name() == "offset_of") value = get_data_member_offset(*it); else if (fn_call->get_name() == "offset_after") - value = get_data_member_offset(*it) + - (*it)->get_type()->get_size_in_bits(); + { + if (!get_next_data_member_offset(context, *it, value)) + { + value = get_data_member_offset(*it) + + (*it)->get_type()->get_size_in_bits(); + } + } else // We should not reach this point. abort(); @@ -1351,6 +1383,19 @@ type_suppression::insertion_range::eval_boundary(boundary_sptr boundary, return false; } +/// Test if a given value supposed to be inside an insertion range +/// represents the end of the range. +/// +/// @param value the value to test for. +/// +/// @return true iff @p value represents the end of the insertion +/// range. +bool +type_suppression::insertion_range::boundary_value_is_end(uint64_t value) +{ + return value == std::numeric_limits::max(); +} + /// Tests if a given instance of @ref /// type_suppression::insertion_range::boundary is actually an integer boundary. /// @@ -1398,13 +1443,13 @@ type_suppression::insertion_range::boundary::~boundary() /// type_suppression::insertion_range::integer_boundary. struct type_suppression::insertion_range::integer_boundary::priv { - int value_; + uint64_t value_; priv() : value_() {} - priv(int value) + priv(uint64_t value) : value_(value) {} }; // end type_suppression::insertion_range::integer_boundary::priv @@ -1413,22 +1458,22 @@ struct type_suppression::insertion_range::integer_boundary::priv /// type_suppression::insertion_range::integer_boundary. /// /// @param value the integer value of the newly created integer boundary. -type_suppression::insertion_range::integer_boundary::integer_boundary(int value) +type_suppression::insertion_range::integer_boundary::integer_boundary(uint64_t value) : priv_(new priv(value)) {} -/// Return the integer value of the current inace of @ref +/// Return the integer value of the current instance of @ref /// type_suppression::insertion_range::integer_boundary. /// /// @return the integer value of the current boundary. -int +uint64_t type_suppression::insertion_range::integer_boundary::as_integer() const {return priv_->value_;} /// Converts the current boundary into an integer value. /// /// @return the integer value of the current boundary. -type_suppression::insertion_range::integer_boundary::operator int() const +type_suppression::insertion_range::integer_boundary::operator uint64_t() const {return as_integer();} /// Destructor of @ref type_suppression::insertion_range::integer_boundary. diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index b83f05be..7edb1e24 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -1550,6 +1550,17 @@ test-diff-suppr/PR27267/v1.c \ test-diff-suppr/PR27267/libtestpr27267-v0.so \ test-diff-suppr/PR27267/libtestpr27267-v1.so \ test-diff-suppr/PR27267/report-1.txt \ +test-diff-suppr/PR28073/PR28073-bitfield-removed.c \ +test-diff-suppr/PR28073/PR28073-bitfield-removed.o \ +test-diff-suppr/PR28073/PR28073-bitfield-removed.o.abi \ +test-diff-suppr/PR28073/PR28073-output-1.txt \ +test-diff-suppr/PR28073/PR28073-output-2.txt \ +test-diff-suppr/PR28073/PR28073.after.o \ +test-diff-suppr/PR28073/PR28073.after.o.abi \ +test-diff-suppr/PR28073/PR28073.before.o \ +test-diff-suppr/PR28073/PR28073.before.o.abi \ +test-diff-suppr/PR28073/PR28073.c \ +test-diff-suppr/PR28073/bitfield.suppr \ \ test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1 \ test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi \ diff --git a/tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.c b/tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.c new file mode 100644 index 00000000..e88aec9e --- /dev/null +++ b/tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.c @@ -0,0 +1,14 @@ +/* + * Compile this with: + * gcc -g -c PR28073-bitfield-removed.c + */ +#include + +struct bigstruct { + char name[128]; + uint8_t other; +}; + +void access_bigstruct(struct bigstruct *st __attribute__((unused))) +{ +} diff --git a/tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.o b/tests/data/test-diff-suppr/PR28073/PR28073-bitfield-removed.o new file mode 100644 index 0000000000000000000000000000000000000000..bdfe7d35e40fbc3883ffbf2ffa6a27255ba8f2a3 GIT binary patch literal 3776 zcmbtX&2Jk;6rb_Nv6D^QBra`2KygrMn+mVv0BIVO)+i!PM2SjJkw74KZBOh4dmZhr zt0bsuD@3J=13_>^q7pqI_ya(K15yR*0VIwb=n;X$0db4O0p6Q^V{fKz_aCa0d|mGSibSo@{P;8JFnjU73etQNgVCL z=3#82VnzTD4S6hqB<~5kWZ3auBxABUde}mPSR7HjC+@fbB$0?m?2OU$^I#wyukl3k zQve3KB&8baedZQ0S6RY??h71Tgyss9i{k^*83?8(%0Ku8P`?iu2c}Ssy<1~u@-4LC zN0@1zHjNaphnSI?H=i<3nJZ~XJBV)biQ{DKA1F2irO5Ip=?*2C>8I01qe=VKBfk&=1H%20$XO4Ucoy*ETZ- z_?s~UTwAX1R9#WY;OW(yZZ)%qaqWg+#bOIa=ZXO!`Arf2f`>HMk8@imy#vK`Psc6KV0Z3Hb> zEL4RnJf{rM_R6(|&AHj^>=T)6mD%O8@cm+El3{9`O0L#yh+L&vdCkdHogi0tN;cTp zPCd8oYzjZO;RV7E{M`AqnYrnck2C7CB_~*SM7@&rM5B30RIKv9kCkirUe0mL^;SjX zAfUfr^nDTsTN}c+YRnHRu%;{?feVnGU0j^c9EXjZ`UktHE(P9^3_SS0f-77{{#Eqe zaKiHPfXzX8Q26#5!v{rP-=|YU*JF!=y-Q#a(p_7O+rxhUv)dqC z%x*N4is%eGCPr9YIs|D(SUl%cJ1{}5dKi(Um^UZ z#(zurHud`ct4|lsQ-1cyZs7vBtW}_jX`de-@5EfLqtRL9r*9lkMmbKwE zH-r~#Q7%y{u6y{&`~NZyA#l&s`KyQpQrdNdFxp0C5&&}1JA>oTV$(%*|6^c-HRr$j zV|~zLVp^5|Hv|#UZSf}#*11B&2G#GW2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-diff-suppr/PR28073/PR28073-output-1.txt b/tests/data/test-diff-suppr/PR28073/PR28073-output-1.txt new file mode 100644 index 00000000..9666a8fd --- /dev/null +++ b/tests/data/test-diff-suppr/PR28073/PR28073-output-1.txt @@ -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 + diff --git a/tests/data/test-diff-suppr/PR28073/PR28073-output-2.txt b/tests/data/test-diff-suppr/PR28073/PR28073-output-2.txt new file mode 100644 index 00000000..8731043c --- /dev/null +++ b/tests/data/test-diff-suppr/PR28073/PR28073-output-2.txt @@ -0,0 +1,14 @@ +Functions changes summary: 0 Removed, 1 Changed, 0 Added function +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + +1 function with some indirect sub-type change: + + [C] 'function void access_bigstruct(bigstruct*)' at PR28073-bitfield-removed.c:12:1 has some indirect sub-type changes: + parameter 1 of type 'bigstruct*' has sub-type changes: + in pointed to type 'struct bigstruct' at PR28073-bitfield-removed.c:7:1: + type size changed from 1040 to 1032 (in bits) + 1 data member deletion: + 'uint8_t bitfield0', at offset 1024 (in bits) at plop.c:5:1 + 1 data member change: + 'uint8_t other' offset changed from 1032 to 1024 (in bits) (by -8 bits) + diff --git a/tests/data/test-diff-suppr/PR28073/PR28073.after.o b/tests/data/test-diff-suppr/PR28073/PR28073.after.o new file mode 100644 index 0000000000000000000000000000000000000000..948323d75eeb8a8e82a5f8b914c050484bb47897 GIT binary patch literal 3848 zcmbtXO>7%Q6n^8i6DN*SCoXM5L2(eY2_ow_K$@m%YKYn<{Ha7#LWs&;+Z%hSvyOJx zC<%f9g(_7q1$shATsVN>zzK@P0SSRB?jSB45k1mdr5@nD**ErPY6L1z+IjDN^ZsV$ z?X10h;+c~%AwZFU1?XrB1-RbVk&99+!acAT&MaN}ed*Hcx0WuSxV7i2D{tb|g`Z+O zQn+&V`vk^HfJl-@f`O~8N_7Bo_NA>156?{ z5wSByvd^QP^nY9QC4WH0paA_+ggD8m)F!dGRMK%$L|j^BulwB|bDtL5d?=qhymxfRR)c#YO-I_F%PC96W-L+;fm;NK28V)~s~JUq&H; zwsXjZ5Vr@@#Hge2L18QmhI$O;J#y1gVIn&a*ff1@Gb1Y!L+>O+av^45fU*;;I(DO4 zfR^h!HP^1@=Q7Bw9sM{X+ z^`;l>j>;*e^{MC1JqwRehNhq~VZBT;89o z@6&L37b12q$;ghU?tl@vK{)L9K3g2k> zD(k;!xYB=PTt6@B0V3L8`4N;FK!&+){{Z7;PknNf^@AF&&T(49-(dZ54c}pXUc=vK zJ=zbH_d~{)nd^1t7^mKh_9vMB=2~Etkq2JL>q-jjjR4H56!nqXzH|Sd4qyn{Gj;wdVv&V01u!SuD2<~+ShQzozC=S8()|yi z4c$?9>reNI9+T3l{C(P_rpn(rbT1akDMB~+(wg9=p?i_+)O|X_w#Sg`F=?vK;5D{W zOt(Fa6FNq=InJxzn}70u8YjBdpW#B4Kh;m~i(Y>fv2OWKbN+KUA0^$E_PJaBA}9Kk zohd(k1@-*vh*3;cCyJ83>tHQ)@?sQjLwCZOD2+b*k9ilwSUU)TNEg!?thK_)%Ql(>;7Nk1eq3< z0rMMdsQR4FFN2TrS9rJF6yi_L|0^j-^q+!!b${v!{oO|huJik+e$x>~r0?GlV%_}J NPp%)OS7*@u{|4a1N=E + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-diff-suppr/PR28073/PR28073.before.o b/tests/data/test-diff-suppr/PR28073/PR28073.before.o new file mode 100644 index 0000000000000000000000000000000000000000..84d14ee6ab64609f28b89011a8dda0d92ae9de42 GIT binary patch literal 3768 zcmbtXO>7%Q6rSn_ zA$&zej{qJT^4KtvJRT0oaNt8o#>DH?aRUuv2}Fr_!f^vgA`p+*X_MI(z(6=&=UVbh z02;c)h04Of34I$V&f;QfRG@1t=>hpIJR_^{y2?i3&3H=0LRHqyKl}}m4+W&=P>tPa zu(9MjXv0r3T|cjDX<&~rExoKirJvJFS*Rj~aF&O734+DP`6KD9uFXu(jPr@%%yC#4 zxx?-aWx1Bt^)LX30K*~x#Y^c|VC_lHOIe&7nPsJ{2{A_veql@i#fme0ho2@PLz#eIU5mtahQ?GlWf^FPxm9Pq-x1IkPo3~&te zBjOqWAQ2afCpa7Fn`tS&8`HqG>-tXJwQD&%-)7sb=MFKh)v{T++=bbta=W;6$-|JQOGUKFBA&%g>$(x zn^4rc70^U}aW0o{1zp!(soSpYIaPp`S8c5HmKO7iPvr7-W>u@U@0SmXtT@4zV>fH_ zR0I~)X|_8?m6?rp%QkE6+Ut&4cLKBNR4j0`oTjP5n^1`_Q&R=OcE|RO2J?d&)Ro5#bpf)AtEz>;X9j*_cDBXY&f|OlMe!i4~n>qPp31xvDMVj8W@E1z&FN? zvpaVOO~N%BL_?d1R(N2dh27+UAWdVDW*C{(?(x}ZY%F3GspuPOX5gk6Pyk+6&>>$ybyj$$v@v#ap<+l2C7IP}*$ zL--?w|B3KTg@1+ccMAVK;U8#J&jt4!1?v~TX#z2pp;5Jen0U0uGneZ+rSJ~nd4+$I z@RJIEo$#{4?-7okJLbJXe2GT2&K&VE81dT447AX4I^}Vn)UH znc>+@%c$9vZoTZdTWy#Vx>c!o_8W($Ezff6_FGu=DXd9JT0LVq} z49-7`uK}X^p9UN3MfdBEeM60jX=VPu5JW_^#XnrI{}m%PsNSOHl%Y$5{SWPA-<(7v zkQI2;n8=ri{0u=vRND=hQ#mxhOQig6WC+z3*Ey*E+xT&SNPny!DYgC@aB57Tm`Uq? z89_u;+cL}z%Kt0n|CD?&KmOXO`8&X2Oj#$WLiQ;C9ZAqA^UD$Y$RPh6x=_&&@?y>A3ciTtA+>Zz3RzN$ao3H93titW?) YH-#V~>i&(x+#vs3l<1p?FRH5l-+ZY+KmY&$ literal 0 HcmV?d00001 diff --git a/tests/data/test-diff-suppr/PR28073/PR28073.before.o.abi b/tests/data/test-diff-suppr/PR28073/PR28073.before.o.abi new file mode 100644 index 00000000..81c4ac2b --- /dev/null +++ b/tests/data/test-diff-suppr/PR28073/PR28073.before.o.abi @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-diff-suppr/PR28073/PR28073.c b/tests/data/test-diff-suppr/PR28073/PR28073.c new file mode 100644 index 00000000..2b84d59c --- /dev/null +++ b/tests/data/test-diff-suppr/PR28073/PR28073.c @@ -0,0 +1,24 @@ +/* + * Compile this twice: + * gcc -g -c -DBEFORE -o PR28073.before.o PR28073.c + * gcc -g -c -o PR28073.after.o PR28073.c + */ + +#include + +struct bigstruct { + char name[128]; + uint8_t bitfield0:1 + #ifndef BEFORE + ,bitfield1:1 + #endif + ; + uint8_t other; +}; + +void access_bigstruct(struct bigstruct *st) +{ + #ifndef BEFORE + st->bitfield1 = 1; + #endif +} diff --git a/tests/data/test-diff-suppr/PR28073/bitfield.suppr b/tests/data/test-diff-suppr/PR28073/bitfield.suppr new file mode 100644 index 00000000..4acd81b0 --- /dev/null +++ b/tests/data/test-diff-suppr/PR28073/bitfield.suppr @@ -0,0 +1,4 @@ +[suppress_type] + name = bigstruct + type_kind = struct + has_data_member_inserted_between = {offset_of(bitfield0), offset_of(other)} diff --git a/tests/test-diff-suppr.cc b/tests/test-diff-suppr.cc index 5b4d08d3..0f797fa6 100644 --- a/tests/test-diff-suppr.cc +++ b/tests/test-diff-suppr.cc @@ -2036,6 +2036,26 @@ InOutSpec in_out_specs[] = "data/test-diff-suppr/PR27267/report-1.txt", "output/test-diff-suppr/PR27267/report-1.txt" }, + { + "data/test-diff-suppr/PR28073/PR28073.before.o.abi", + "data/test-diff-suppr/PR28073/PR28073.after.o.abi", + "", + "", + "data/test-diff-suppr/PR28073/bitfield.suppr", + "--drop-private-types --no-default-suppression", + "data/test-diff-suppr/PR28073/PR28073-output-1.txt", + "output/test-diff-suppr/PR28073/PR28073-output-1.txt" + }, + { + "data/test-diff-suppr/PR28073/PR28073.before.o.abi", + "data/test-diff-suppr/PR28073/PR28073-bitfield-removed.o.abi", + "", + "", + "data/test-diff-suppr/PR28073/bitfield.suppr", + "--drop-private-types --no-default-suppression", + "data/test-diff-suppr/PR28073/PR28073-output-2.txt", + "output/test-diff-suppr/PR28073/PR28073-output-2.txt" + }, // This should be the last entry {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} };