From patchwork Thu Mar 2 18:59:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 65919 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 960C23858408 for ; Thu, 2 Mar 2023 19:00:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 960C23858408 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677783612; bh=BJVNdpEbeQlcuzsrSF8GxpgqHsshQFN/A+luVbm2VIU=; h=To:Cc:Subject:References:Date:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Help:List-Subscribe:From: Reply-To:From; b=kXSqOxg3Jhq0Jw2aP4zJ9p/BISv9JLwrNQ/8M9sFFyCGv4dFwB/WG/sl3swcH4TB1 VO9AIyPF/PL2TonpgjJmL2Pt1D/dC3Xl55CpSUX7lg8w14TtDsleDgqDJgCjIS3wAv qjswcCHXdnbfBS8LK1U2Ix3ynmmGGvDsD7VpioGo= 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.133.124]) by sourceware.org (Postfix) with ESMTPS id 6AFBF3858D33 for ; Thu, 2 Mar 2023 19:00:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6AFBF3858D33 Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-228-Yyijyr1EMlGJDP3oQ2HIXw-1; Thu, 02 Mar 2023 13:59:58 -0500 X-MC-Unique: Yyijyr1EMlGJDP3oQ2HIXw-1 Received: by mail-qk1-f197.google.com with SMTP id q25-20020a37f719000000b00742bfdd63ecso7054384qkj.4 for ; Thu, 02 Mar 2023 10:59:58 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677783597; h=mime-version:user-agent:message-id:in-reply-to:date:references :organization:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BJVNdpEbeQlcuzsrSF8GxpgqHsshQFN/A+luVbm2VIU=; b=7iCeo33y1+f/f/pTBocWLBrz2t1IohEHKKPqYB+wbwt2DCeFsOrS9IinyWuMER83s0 wkybg8W9BB5Pou8Qy4W3lEH+HDm4jDAQf/DLeA/ciTuT7t4jVrImUszpMvrEGj5ygOfP CSeQC80Rsfb4YxhsO4rSmLcYH8UC1SLyTMotHWKsIPtikGhYTm4+RzFlgTCuOKZ0pXx0 t32dsrEIh4gOn/KR6us1Vxavo7TIGwd9TDtbdxxmBUv4PkUDgW0urCAX12vNaOwkESAt 9063RN4gJEihZhF53FxdirJlWvTUF8A588823PxOX0h5oh0rIG0R8k3YkMSqKAbQ7fpz E+Ug== X-Gm-Message-State: AO0yUKWPRHYKPmFHJrn4oWJZWdUTn7wN0LTzIF1UD8QxMf7zcxlGIntE APla61mIZIypvcMAK1bP0C7RS2ST0iK9Rav5Mcbf2VJcPCC7QPOmm0RpES8VrOEYwN15BNSL7io y8zCtBFtrpNXlQzWBis84d4YUaQ== X-Received: by 2002:a05:622a:1829:b0:3bf:aa76:f4e1 with SMTP id t41-20020a05622a182900b003bfaa76f4e1mr19116297qtc.40.1677783596293; Thu, 02 Mar 2023 10:59:56 -0800 (PST) X-Google-Smtp-Source: AK7set+8LNmjgrqfXE4ZWjkxygOOCKAtJkQBNafqxHZkI8RGowxQAZj2KH8PYb3zzLm7Po0P5PCR6w== X-Received: by 2002:a05:622a:1829:b0:3bf:aa76:f4e1 with SMTP id t41-20020a05622a182900b003bfaa76f4e1mr19116220qtc.40.1677783595193; Thu, 02 Mar 2023 10:59:55 -0800 (PST) Received: from localhost ([88.120.130.27]) by smtp.gmail.com with ESMTPSA id y12-20020ac8704c000000b003bfb6ddc49dsm249083qtm.1.2023.03.02.10.59.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 10:59:54 -0800 (PST) Received: by localhost (Postfix, from userid 1000) id AFA1C581C79; Thu, 2 Mar 2023 19:59:52 +0100 (CET) To: Dodji Seketeli Cc: libabigail@sourceware.org, ckalina@redhat.com Subject: [PATCH 06/13] comparison, suppression: Support [allow_type] directive Organization: Red Hat / France References: <877cvzrnws.fsf@redhat.com> <87356nrnmq.fsf@redhat.com> X-Operating-System: Fedora 38 X-URL: http://www.redhat.com Date: Thu, 02 Mar 2023 19:59:52 +0100 In-Reply-To: <87356nrnmq.fsf@redhat.com> (Dodji Seketeli's message of "Thu, 02 Mar 2023 19:53:17 +0100") Message-ID: <877cvzq8rb.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.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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 patch adds support for a new 'allow_type' suppression directive. It suppresses all the changes that are NOT matched by the directive. In other words, this directive determines the set of type changes that are NOT suppressed. Any other change is suppressed. This thus called a "negated suppression directive". The way these negated suppression directives interact with the direct suppression directives that already exist is the following. The suppression evaluation pass visits every single diff node (carrying a type change) of the diff graph. Negated suppressions are evaluated first, in order of occurrence. There are thus, two alternatives: 1/ At least one negated suppression matches the current diff node. or 2/ No negated suppression matches the current diff node. In case of 1/ then direct suppression specifications are considered. There are two alternatives: 1.1/ At least one direct suppression matches the current diff node. The diff node is suppressed: categorized as being in the SUPPRESSED_CATEGORY category) or 1.2/ No direct suppression matches the current diff node. The diff node is not suppressed: categorized as being in the HAS_ALLOWED_CHANGE_CATEGORY category. In case of 2/ then direct suppression specifications are considered. There are two alternatives: 2.1 At least one direct suppression matches the current diff node. The diff node is categorized as being in the SUPPRESSED_CATEGORY category, just like in 1.1. 2.2 No direct suppression matches the current diff node. The diff node is not suppressed and not categorized. As a result of the category propagation pass, a node which has a parent node categorized as HAS_ALLOWED_CHANGE_CATEGORY is itself categorized as HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY. A node which has a descendant categorized as HAS_ALLOWED_CHANGE_CATEGORY will itself be categorized as HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY. Nodes that are categorized as HAS_ALLOWED_CHANGE_CATEGORY, HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY and HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY are not suppressed by the reporting passes. This is needed for the reporting passes to emit the impact sub-tree up to the diff node which carry the change that was actually categorized as HAS_ALLOWED_CHANGE_CATEGORY. * include/abg-comparison.h: Include abg-suppression.h (diff, diff_context, diff_sptr, diff_context_sptr): Remove these forward decls from here. (enum diff_category::{HAS_ALLOWED_CHANGE_CATEGORY, HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY, HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY}): Add new enumerators. (enum diff_category::EVERYTHING_CATEGORY): Update enumerator. (diff_context::{negated_suppressions, direct_suppressions}): Declare new member functions. (diff_context::suppressions): Add overload. (diff::{is_filtered_out_without_looking_at_allowed_changes, is_allowed_by_specific_negated_suppression, has_descendant_allowed_by_specific_negated_suppression, has_parent_allowed_by_specific_negated_suppression}): Declare new member functions. * include/abg-suppression.h (class negated_suppression_base, class negated_type_suppression): Declare new classes. (negated_suppression_sptr, negated_suppression_type): Define new typedefs. (is_negated_suppression): Declare new functions. * src/abg-suppression.cc (negated_suppression_base::{negated_suppression_base, ~negated_suppression_base}): Define member functions. (negated_type_suppression::{negated_type_suppression, suppresses_diff, ~negated_type_suppression}): Likewise. (is_negated_suppression): Define functions. (read_type_suppression): Allow parsing the "allow_type" directive and instantiate a negated_type_suppression. * src/abg-comparison-priv.h (diff_context::priv::{negated_suppression_type_, direct_suppressions}): Define new data members. (diff::priv::is_filtered_out): A node categorized as HAS_DESCENDANT_ALLOWED_BY_SPECIFIC_NEGATED_SUPPRESSION, HAS_PARENT_ALLOWED_BY_SPECIFIC_NEGATED_SUPPRESSION and HAS_ALLOWED_CHANGE_CATEGORY is not filtered out. * src/abg-comparison.cc (diff_context::suppressions): Add a non-const overload. (diff_context::{negated,direct}_suppressions): Define new member function. (diff_context::add_suppression): Invalidate the cache data members diff_context::priv::{negated,direct}_suppressions_. (diff::is_filtered_out): A node categorized as HAS_DESCENDANT_ALLOWED_BY_SPECIFIC_NEGATED_SUPPRESSION, HAS_PARENT_ALLOWED_BY_SPECIFIC_NEGATED_SUPPRESSION and HAS_ALLOWED_CHANGE_CATEGORY is not filtered out. (diff::is_filtered_out_without_looking_at_allowed_changes): Define new member function. (diff::is_suppressed): If there is at least one negated suppression that match the diff node, then it's not suppressed, unless it's matched by a direct suppression. (diff::{is_allowed_by_specific_negated_suppression, has_descendant_allowed_by_specific_negated_suppression, has_parent_allowed_by_specific_negated_suppression}): Define new member functions. (operator<<(ostream& o, diff_category c)): Serialize HAS_{DESCENDANT_WITH,PARENT_WITH}_ALLOWED_CHANGE_CATEGORY enumerators. (category_propagation_visitor::visit_end): Do not propagate HAS_ALLOWED_CHANGE_CATEGORY, HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY and HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY categories. (suppression_categorization_visitor::visit_begin): Categorize a node that is not suppressed by a direct suppression and is suppressed by a negated one as HAS_ALLOWED_CHANGE_CATEGORY. Propagate it to descendant nodes as HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY ... (suppression_categorization_visitor::visit_end): ... and to parent node as HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY. * src/abg-default-reporter.cc (default::reporter): In the overload for typedef_diff, qualified_type_diff, reference_diff, fn_parm_diff, function_type_diff, array_diff, base_diff, function_decl_diff, report local changes only on node that are not filtered out wrt allowed changed. * tests/data/test-abidiff-exit/test-allow-type-array-suppr.txt: New test input. * tests/data/test-abidiff-exit/test-allow-type-array-v0--v1-report-{1,2}.txt: Likewise. * tests/data/test-abidiff-exit/test-allow-type-array-v0--v2-report-{1,2}.txt: Likewise. * tests/data/test-abidiff-exit/test-allow-type-array-v0--v3-report-{1,2}.txt: Likewise. * tests/data/test-abidiff-exit/test-allow-type-array-v{0,1,2,3}.c: Source code of new binary test inputs. * tests/data/test-abidiff-exit/test-allow-type-array-v{0,1,2,3}.o: New binary test inputs. * tests/data/test-abidiff-exit/test-allow-type-region-suppr.txt: New test input. * tests/data/test-abidiff-exit/test-allow-type-region-v0--v1-report-{1,2}.txt: * tests/data/test-abidiff-exit/test-allow-type-region-v0--v2-report-{1,2}.txt: Likewise. * tests/data/test-abidiff-exit/test-allow-type-region-v0--v3-report-{1,2}.txt: Likewise. * tests/data/test-abidiff-exit/test-allow-type-region-v0--v4-report-{1,2}.txt: Likewise. * tests/data/test-abidiff-exit/test-allow-type-region-v0--v5-report-{1,2}.txt: Likewise. * tests/data/test-abidiff-exit/test-allow-type-region-v{0,1,2,3,4,5}.c: Source code of new binary test input. * tests/data/test-abidiff-exit/test-allow-type-region-v{0,1,2,3,4,5}.o: New binary test inputs. * tests/data/test-abidiff-exit/test-allow-type-suppr{1,2}.txt: New test inputs. * tests/data/Makefile.am: Add the new testing files above to source distribution. Signed-off-by: Dodji Seketeli --- include/abg-comparison.h | 62 +++- include/abg-suppression.h | 69 +++- src/abg-comparison-priv.h | 17 + src/abg-comparison.cc | 289 +++++++++++++-- src/abg-default-reporter.cc | 348 +++++++++--------- src/abg-suppression.cc | 116 +++++- tests/data/Makefile.am | 40 ++ .../test-allow-type-array-suppr.txt | 7 + .../test-allow-type-array-v0--v1-report-1.txt | 23 ++ .../test-allow-type-array-v0--v1-report-2.txt | 3 + .../test-allow-type-array-v0--v2-report-1.txt | 20 + .../test-allow-type-array-v0--v2-report-2.txt | 15 + .../test-allow-type-array-v0--v3-report-1.txt | 23 ++ .../test-allow-type-array-v0--v3-report-2.txt | 3 + .../test-allow-type-array-v0.c | 18 + .../test-allow-type-array-v0.o | Bin 0 -> 3392 bytes .../test-allow-type-array-v1.c | 20 + .../test-allow-type-array-v1.o | Bin 0 -> 3448 bytes .../test-allow-type-array-v2.c | 20 + .../test-allow-type-array-v2.o | Bin 0 -> 3456 bytes .../test-allow-type-array-v3.c | 20 + .../test-allow-type-array-v3.o | Bin 0 -> 3456 bytes .../test-allow-type-region-suppr.txt | 11 + ...test-allow-type-region-v0--v1-report-1.txt | 20 + ...test-allow-type-region-v0--v1-report-2.txt | 3 + ...test-allow-type-region-v0--v2-report-1.txt | 21 ++ ...test-allow-type-region-v0--v2-report-2.txt | 16 + ...test-allow-type-region-v0--v3-report-1.txt | 23 ++ ...test-allow-type-region-v0--v3-report-2.txt | 18 + ...test-allow-type-region-v0--v4-report-1.txt | 28 ++ ...test-allow-type-region-v0--v4-report-2.txt | 3 + ...test-allow-type-region-v0--v5-report-1.txt | 30 ++ ...test-allow-type-region-v0--v5-report-2.txt | 25 ++ .../test-allow-type-region-v0.c | 22 ++ .../test-allow-type-region-v0.o | Bin 0 -> 3576 bytes .../test-allow-type-region-v1.c | 23 ++ .../test-allow-type-region-v1.o | Bin 0 -> 3632 bytes .../test-allow-type-region-v2.c | 23 ++ .../test-allow-type-region-v2.o | Bin 0 -> 3632 bytes .../test-allow-type-region-v3.c | 24 ++ .../test-allow-type-region-v3.o | Bin 0 -> 3688 bytes .../test-allow-type-region-v4.c | 23 ++ .../test-allow-type-region-v4.o | Bin 0 -> 3640 bytes .../test-allow-type-region-v5.c | 24 ++ .../test-allow-type-region-v5.o | Bin 0 -> 3696 bytes .../test-allow-type-suppr1.txt | 7 + .../test-allow-type-suppr2.txt | 7 + tests/test-abidiff-exit.cc | 187 ++++++++++ 48 files changed, 1442 insertions(+), 209 deletions(-) create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-suppr.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v0--v1-report-1.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v0--v1-report-2.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v0--v2-report-1.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v0--v2-report-2.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v0--v3-report-1.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v0--v3-report-2.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v0.c create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v0.o create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v1.c create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v1.o create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v2.c create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v2.o create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v3.c create mode 100644 tests/data/test-abidiff-exit/test-allow-type-array-v3.o create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-suppr.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0--v1-report-1.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0--v1-report-2.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0--v2-report-2.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0--v3-report-1.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0--v3-report-2.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0--v4-report-1.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0--v4-report-2.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0--v5-report-1.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0--v5-report-2.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0.c create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v0.o create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v1.c create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v1.o create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v2.c create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v2.o create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v3.c create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v3.o create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v4.c create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v4.o create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v5.c create mode 100644 tests/data/test-abidiff-exit/test-allow-type-region-v5.o create mode 100644 tests/data/test-abidiff-exit/test-allow-type-suppr1.txt create mode 100644 tests/data/test-abidiff-exit/test-allow-type-suppr2.txt new file mode 100644 index 00000000..648f835a new file mode 100644 index 00000000..2024aa8e new file mode 100644 index 00000000..e8111f69 new file mode 100644 index 00000000..0706c4d6 new file mode 100644 index 00000000..09c1ec8d new file mode 100644 index 00000000..e95b3115 new file mode 100644 index 00000000..a7a638cc new file mode 100644 index 00000000..bcb26e95 new file mode 100644 index 00000000..a3a33698 new file mode 100644 index 00000000..18725f37 diff --git a/include/abg-comparison.h b/include/abg-comparison.h index 440080a5..839478bf 100644 --- a/include/abg-comparison.h +++ b/include/abg-comparison.h @@ -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_sptr; - -/// Convenience typedef for a weak_ptr for the @ref diff class -typedef weak_ptr diff_wptr; - /// Hasher for @ref diff_sptr. struct diff_sptr_hasher { @@ -261,14 +254,6 @@ typedef unordered_map string_elf_symbol_map; /// value is a @ref var_diff_sptr. typedef unordered_map string_var_diff_ptr_map; -class diff_context; - -/// Convenience typedef for a shared pointer of @ref diff_context. -typedef shared_ptr diff_context_sptr; - -/// Convenience typedef for a weak pointer of @ref diff_context. -typedef weak_ptr 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; diff --git a/include/abg-suppression.h b/include/abg-suppression.h index bfc37a40..05b0e8b4 100644 --- a/include/abg-suppression.h +++ b/include/abg-suppression.h @@ -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_sptr; /// Convenience typedef for vector of @ref type_suppression_sptr. typedef vector 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_sptr; + +/// Convenience typedef for a vector of @ref negated_suppression_sptr +typedef vector 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. diff --git a/src/abg-comparison-priv.h b/src/abg-comparison-priv.h index 46438e94..fb843665 100644 --- a/src/abg-comparison-priv.h +++ b/src/abg-comparison-priv.h @@ -174,7 +174,17 @@ struct diff_context::priv unordered_diff_sptr_set live_diffs_; vector canonical_diffs; vector 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. diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc index 969c32d8..609c5bf2 100644 --- a/src/abg-comparison.cc +++ b/src/abg-comparison.cc @@ -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 diff --git a/src/abg-default-reporter.cc b/src/abg-default-reporter.cc index 0c7d3e1d..243ddbfb 100644 --- a/src/abg-default-reporter.cc +++ b/src/abg-default-reporter.cc @@ -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()) { diff --git a/src/abg-suppression.cc b/src/abg-suppression.cc index a79deb35..aaf175ca 100644 --- a/src/abg-suppression.cc +++ b/src/abg-suppression.cc @@ -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(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(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(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) // +// + +/// 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() +{ +} + +// + /// 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) { diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index a343759e..aafa41de 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -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 \ diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-suppr.txt b/tests/data/test-abidiff-exit/test-allow-type-array-suppr.txt new file mode 100644 index 00000000..043cfb39 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-array-suppr.txt @@ -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} diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-v0--v1-report-1.txt b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v1-report-1.txt new file mode 100644 index 00000000..36987f27 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v1-report-1.txt @@ -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 + diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-v0--v1-report-2.txt b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v1-report-2.txt new file mode 100644 index 00000000..9666a8fd --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v1-report-2.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-abidiff-exit/test-allow-type-array-v0--v2-report-1.txt b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v2-report-1.txt new file mode 100644 index 00000000..5d2fb16c --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v2-report-1.txt @@ -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 + diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-v0--v2-report-2.txt b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v2-report-2.txt new file mode 100644 index 00000000..cade60df --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v2-report-2.txt @@ -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) + diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-v0--v3-report-1.txt b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v3-report-1.txt new file mode 100644 index 00000000..b0e1d85c --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v3-report-1.txt @@ -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 + diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-v0--v3-report-2.txt b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v3-report-2.txt new file mode 100644 index 00000000..9666a8fd --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-array-v0--v3-report-2.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-abidiff-exit/test-allow-type-array-v0.c b/tests/data/test-abidiff-exit/test-allow-type-array-v0.c new file mode 100644 index 00000000..174de3a0 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-array-v0.c @@ -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; +} diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-v0.o b/tests/data/test-abidiff-exit/test-allow-type-array-v0.o new file mode 100644 index 0000000000000000000000000000000000000000..83dc3783c1bdbaec61f46a705554269a55bba07d GIT binary patch literal 3392 zcmc&$&2Jl35TEDuCYx*$J24*(0cDLqZ6kK=4OIy#DM6t$5vZV|s+WSZwx8`K{)pC_ zPgEf;h$t73IC4TQz(~6@^PBn2ynSEx z2Up&BEh7Xd5pWq!JcR-*8!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*$(sgBKcN}=qB{Zicvy~wmNR`(kXTkiTHP|)_;?cRvA+yk_K)E}{o4sVVE-G|$-e3vsjtpCr1ESh^Pgs% z^6A-QpYBZ(h5s;c@h4{>3jdS+ORSUiEyihX;`0Mef3FjIRn%cH&@E+!ayJBrE*)^H z{XRH>Y*(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_z&pVIu(ubbj4 xJgqm?ZgKw>514+3=vOnzr!`HUU4-BcpC5~ym?XcS#+AnZn8*KZj7w&c|2JnMH)a3; literal 0 HcmV?d00001 diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-v1.c b/tests/data/test-abidiff-exit/test-allow-type-array-v1.c --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-array-v1.c @@ -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; +} diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-v1.o b/tests/data/test-abidiff-exit/test-allow-type-array-v1.o new file mode 100644 index 0000000000000000000000000000000000000000..9be83bf41befede1b2da405aa7036bca3a37edcf GIT binary patch literal 3448 zcmcImOK&4Z5U%!kl1U~HJLZuPP#gr>hZs8(R=Z)BEJ4w-37}=QXtfd#C1bm753$Fq z@gyXRcpX3+1tE|)a^wI9PF#?~Wi>g#%ScTL%E zUwQtSj1Ztmz-2hp6bi6y9m-3wxCHk=0dB7B{k#pDRHc?yx4#L(kl&swYKIhYrZjumWUW_l(sCI)l&16b^e z2Rz8?TAI8wMON?_J{hVS68DUn+IGB@c)f_S ziMD5v3n6|V8zn}KgAWQbaSvt0OlG_nHug0I4E0qbFU*l|%zNu*zHW+gCWC%guiY#z zyBCVCTY9|Y7U$>Y=UsQ+EuOw1YsD2W;sxj2nWEE4gxBq1^1WWx3X=z2=u2epGJx6%5eu{8l+^Mh-@oVc@mOwXWQdktEci z6b`2-Q|xZJ=0#pCI=EKz>vczN`_ca#{e*3uumo3^moFAitMaA4V7tA}1&@<#q6qkf_@ zQun07EwRw=ch<=^NwcUBrcZ=dl12$x_dkVe)TjT}pYC6eN$FJnKS)WCZcBYdQ)?+< zLt>5(#A1g$Vq~YjDf|x+(;~k0n6&T`gI~s0hcDgsIxguLSr2k^&KlSKgJC;sth@RQWf9(8~cor+W0<6yh%DZ*sx(`$WH{x4y|1H=5Rl=7<-TyDlemcm0 + c1->m0; +} diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-v2.o b/tests/data/test-abidiff-exit/test-allow-type-array-v2.o new file mode 100644 index 0000000000000000000000000000000000000000..88f3d0bfb043d22f936663784792614fb2aeb844 GIT binary patch literal 3456 zcmc&$&2Jl35TEDu#+z)M*fErZfU@R8{Sdp(nyL-0QjAP#B2ZNYRYiQcYx~(=Vz0}3 zlO{!c34s~~p(1hYkqZYTBrZrC;lPm_e*yObmk1#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>Sz?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!zsLNfN5Wb-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$DeO^n1M2 z>^I+VOKmqOb=^98wH>!x@;iZvp}6lk-BNSF*LlDRH7SlM;* zu&o@MpUh~t@KMl%l8-8!pP9;il&WUOuAqb9Bu(_5((ub)Noz`C$D-yjdTa-1%CM~* zz{pTALy{;Ewva?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`Om0 + c1->m0; +} diff --git a/tests/data/test-abidiff-exit/test-allow-type-array-v3.o b/tests/data/test-abidiff-exit/test-allow-type-array-v3.o new file mode 100644 index 0000000000000000000000000000000000000000..5fb6bf50c1869701bc5779720ae8eb61bf80a262 GIT binary patch literal 3456 zcmc&$&2Jk;6o2FO#+z)M*l~e`fMO%6eu!PiZq|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?lpb6ow_Wz+942H_KF8)(GsG&*-kc*VcnqHyWeuTwMoqo8*a}V0qimw> zNn9CYe@rE5p~Arjg#}SVF}4t!9=a7=lfn2%HPXzS{MNj$VWt}<%g18KyL9b<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_fI?HQ`*pylCqxvBN8WjdbXub4VH$&e;TS# zkgLLfmHK(P>i)A5ryRq1f;-sm23{4{z#pzHB?Wvd0GC=3xYfY`T%UJ5x6Z2@P3(G& zKJE$Gt5$u!d0^Y~yj&J$uHg&_oUpFq%f*?sgrGZ2pJ0M{1p5-3S?SRfLy-HI pGGY3CqF+;;Pj{++y9mLaZ1!1FLPLLl$}5WhgUtWy5SK)q|2NDSKh*#L literal 0 HcmV?d00001 diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-suppr.txt b/tests/data/test-abidiff-exit/test-allow-type-region-suppr.txt --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-suppr.txt @@ -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) + } diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v0--v1-report-1.txt b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v1-report-1.txt new file mode 100644 index 00000000..7249e6c8 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v1-report-1.txt @@ -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 + diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v0--v1-report-2.txt b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v1-report-2.txt new file mode 100644 index 00000000..9666a8fd --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v1-report-2.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-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt new file mode 100644 index 00000000..0db5dda4 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v2-report-1.txt @@ -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 + diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v0--v2-report-2.txt b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v2-report-2.txt new file mode 100644 index 00000000..e807fcec --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v2-report-2.txt @@ -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) + diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v0--v3-report-1.txt b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v3-report-1.txt new file mode 100644 index 00000000..c5dbee67 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v3-report-1.txt @@ -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 + diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v0--v3-report-2.txt b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v3-report-2.txt new file mode 100644 index 00000000..e4f836e9 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v3-report-2.txt @@ -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) + diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v0--v4-report-1.txt b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v4-report-1.txt new file mode 100644 index 00000000..8a435001 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v4-report-1.txt @@ -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 + diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v0--v4-report-2.txt b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v4-report-2.txt new file mode 100644 index 00000000..9666a8fd --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v4-report-2.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-abidiff-exit/test-allow-type-region-v0--v5-report-1.txt b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v5-report-1.txt new file mode 100644 index 00000000..ffc32324 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v5-report-1.txt @@ -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 + diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v0--v5-report-2.txt b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v5-report-2.txt new file mode 100644 index 00000000..c467ab22 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0--v5-report-2.txt @@ -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 + diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v0.c b/tests/data/test-abidiff-exit/test-allow-type-region-v0.c new file mode 100644 index 00000000..d053a313 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v0.c @@ -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; +} diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v0.o b/tests/data/test-abidiff-exit/test-allow-type-region-v0.o new file mode 100644 index 0000000000000000000000000000000000000000..4a036677aa27e0c2cc8b16106ed3421cf6820086 GIT binary patch literal 3576 zcmc&$&2Jl35TEDu#tzPh6BkHGQEUWiTCsMVhLSc)F^WnP6+u;0RpO)R+J3f|_#;|x zLK=h$mr7BD)JhyU^adBs2&pPZEs)&AgAD z^{oqUz7Z1wvLHs%S1a!Q zhL&BKg*1WK-G*H$!t|dC-++NUf`Kpa0b&@ek#jk*m^zyqTFoq^&>N{_k4p6zDSDwkYEzr>h$X(W@frl+RI#CRh8EN%{m z;;s+o#cPw8EQRS)Cni@jnQ}X8*~d*H*ghnaIEUpYL49Y0-!<1Z8kd} zIl;{hi9vO*({{FI^OgTG^W&<5i_6RBvNL#wC;!6%s@s9DDr>QG1;ln*ObsQHckm|B zEz~zr>DNcnw`0r01J}@jW1Z!YANxdvSTGvFlK*fYPpx@8v_E?9AA1j}N3!TMc?#|DF6d0e z(`vOn&T+)k?>gJh7(AQs90NMvgMNbe6!SEPu7RkxLp<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?IbaOO$WOnU`1eK05| 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 diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v1.c b/tests/data/test-abidiff-exit/test-allow-type-region-v1.c --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v1.c @@ -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; +} diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v1.o b/tests/data/test-abidiff-exit/test-allow-type-region-v1.o new file mode 100644 index 0000000000000000000000000000000000000000..668224e36f697e124c0928a75922eac538893d5a 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;rn3ZHgK^;0uzS&Au7@6AvNcn+TgjS=LANkomB&t7mJ0W4tn*4W6Zf@%p%nMAP}`M+EK0L z22g7G9Z{vu6Q}4<4#Dq##re$Gn-9R` z_d?Gx(Gw>oR)`Z5t@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@!NiROPtc?AAPB)-&X010_1LeOm0 + c1->m0; +} diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v2.o b/tests/data/test-abidiff-exit/test-allow-type-region-v2.o new file mode 100644 index 0000000000000000000000000000000000000000..924ae596926394cd7f0f020d9486c5eecfca4294 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+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@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 zps(8sg<>a!0^Ms+sP%eK2t>yzG(>Hyg*SE6$1#bWS}hRUM~0oi@mk_&NXPYr3c(Tz z5?z&c-S2h<{YpgR{|0h; zP6}D!`Zvgki0)g(vAFuG&<4j+eY)55`ZtlIoT^WRQtoj5UlhSw)mQpm`|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 diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v3.c b/tests/data/test-abidiff-exit/test-allow-type-region-v3.c --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v3.c @@ -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; +} diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v3.o b/tests/data/test-abidiff-exit/test-allow-type-region-v3.o new file mode 100644 index 0000000000000000000000000000000000000000..b30403eba8fe5a73be8dda242406da5fac9b2ed8 GIT binary patch literal 3688 zcmc&$O=u)l5U!q{PC7gJnPieRF)NvfvOm}}nIx`pm#mRtcM}wqm1Ph9Bt0{4X4=g3 zEIplUl4V^_;u3@v1Ob?<;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|=9Tvw8IixsP!NR zebrVAj4?S`(y6JX7#~t*t2_f~0*QC(R=EIE6B4gMPY!*1KBEX@0L;O2)5iJKlc|-= zLJFOcu@5k2#xU(vs>4m&Mh0i}2&7UMQsy9LvDklljD|>zw2?j5s zw9xkqO2aVz92_7)yN(ZnDT0tNrV>M)VMztcfWEG3ju}?}*Vb6o8m?MKK9Rt&?l!wp|7)`TwtuZ*f2lzuXD} zQ4WuCn>`dbe~6iba@`FeUvD) 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~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 z2m0 + c1->m0; +} diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v4.o b/tests/data/test-abidiff-exit/test-allow-type-region-v4.o new file mode 100644 index 0000000000000000000000000000000000000000..8c77f1ab621c96d80c1e49893ffe116c04ebc514 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-aMim}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&)NQhiwqTel3k+=Wwlw;gVE^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<_*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!a8Hfd`SUP8Pi<$Iy=-n=PkA$Hh4DSQ3kZX(cL;7iPvKw z>Xisjb#Jo$y1~E4cEjLrv)wcJui3s~@NB}z2CwJ&jls9s{=wjXWcwG^=6va(gF+x%UZEx{TMfLi>s|CI>{Tj(+&<#=0Sk=`fW-7?@p zjc8B=oB1cuNAJPE&8Pi0`=oNZe#USbruy5U+i{taBC^Q~(&U6m^iiCCXYqGO$$4ze zKFQH#@>3Oc*qE`eqRZqc`WPS1`NLF&%-9!^jT`?R^@9nZ^J)AAPB+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 diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v5.c b/tests/data/test-abidiff-exit/test-allow-type-region-v5.c --- /dev/null +++ b/tests/data/test-abidiff-exit/test-allow-type-region-v5.c @@ -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; +} diff --git a/tests/data/test-abidiff-exit/test-allow-type-region-v5.o b/tests/data/test-abidiff-exit/test-allow-type-region-v5.o new file mode 100644 index 0000000000000000000000000000000000000000..a1da2d31dfa842f08f93a6e54b71b3ee9dbb50cf 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%$Ebf;*r#S?E1XfdfABN( z7*sf|_?*HSh4(8wpnMK0yif6mAk$}ieh7ViYEITd2{J=JaoQ2(qtfOwL`G>x6}Hjp zM-B$+oeqczHCeJr^isqpl-aJ%LXJS{{iahQI7_->yKQlo?qz>ZHBaofRETLa|R6IF6 zp0%c@rboqCI`;@bhC}g01`6WYNlccd?1v|p#>uCAaC4GUz*G37XpW!`Pa$gbB6|db zS5VvNdknP@;?LnBQnc&%AebfyDKVWIiH0Q;Yyks3)0za8F*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|C86XI=Zp?)++tnaPGa-!chMe zbl{jIMHjXYe*Y_}&q}P202aS9W{ibBNn&A!B(XqMnLS-rR7Df`SaFW^T7WerK`aTk9qxb%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{oZ=0@Xt(RJvU#1hVB8YO=D{!0KM_V4uQnr4q>X zUEOZr`VF}|q~-ZihhPc~iC$KAwbO1({2mqjPACglx14V1R#$jn*<7v%Zd>v~{-c`0 zc-kXhP=Z8qu4`!`d!9fBPD0CHOHim8%%zzymlJX_hsxdIr2WhmveR}R3X#% zd1RC3pW}(@c$z=`pPKWpA!m+>6kOo^SICHo>AQ@5N%_m1=qkrjeyVq7{#E2?Og&G8 zN