From patchwork Thu Mar 3 14:56:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Giuliano Procida X-Patchwork-Id: 51534 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 3BAFE3858037 for ; Thu, 3 Mar 2022 14:56:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3BAFE3858037 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1646319391; bh=+Wmqd4Uiljo6ZpVXiN4oAifC6k2ZbSJk9dA+Kt7zlYs=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:Cc:From; b=McJ87+wERryOhAOtRA0oZAodpdQhW+0xSQHETWZxyfidRR0kcFPc9VpsXx+Nt/hiU YaEmH8o/WGL/er29YHo+Ha9bK0QdLaNK9986Tx5ixKw2ibBn5yzdfSIG5Dy8ai1Jx5 pQpnUfB8s44d1WFSNdpbfoESbZ9gG1fYqAsfGWJM= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-ej1-x649.google.com (mail-ej1-x649.google.com [IPv6:2a00:1450:4864:20::649]) by sourceware.org (Postfix) with ESMTPS id B3D723858D39 for ; Thu, 3 Mar 2022 14:56:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B3D723858D39 Received: by mail-ej1-x649.google.com with SMTP id m12-20020a1709062acc00b006cfc98179e2so2882295eje.6 for ; Thu, 03 Mar 2022 06:56:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=+Wmqd4Uiljo6ZpVXiN4oAifC6k2ZbSJk9dA+Kt7zlYs=; b=r5bIMVn8ULLIbAA9vM9gEKeXTyuKS6RWxWBDfAm8++2MbHRH7PbGfUbIPR+7MvfptM 2fHwjyWq+XNRZXgyGnDVfsuoX8cbyOJEE7AK9woHqxazx/unyc1THGOlGDXIl6mfbyaV rrwbrwE1p/Qfsh1+n9W/5l4VIRMmPz/G5AeRa6rGmeRDG4GM1c16L+mZJ7HzN7NooEOc HwkBcrsnvHy2UYbYnne7v+EgA2Z97NSq9s9/KpXrz53oUCqpa0nKx51uTMgYP6Nhoqql mWbaqy4vl/5GgTh79PO3c62vTJUWVdzAZgbT9YTIZoAT326mDU/wdmhAINPIs3y2MjV8 eEQA== X-Gm-Message-State: AOAM5302GJdgp307xhMtmKI9u/FfR6j3ToG6oT8u3L8umvHfQvZdp9ZH LSmaz8L8YVzKXrw4RWiCVUlOUSQkU7fy7gS6HtFfmYNvvle2hPPBi1uJepX4KgxkPHaWM8mkgw5 2aqmHYwvGyAiebTxlV2k3nJe0WWHthMASqOo0ArlC3snHVgXXRE4/zR6+5mati3c8eOFo4o8= X-Google-Smtp-Source: ABdhPJwnY2k/pKBmnXkHZYJqx8tq0rfU+DVmQmrR0fRM2oTiD9Z9GwnlaLlJrGOk96Fg2lfHbnV6UTN7hSrsxQ== X-Received: from tef.lon.corp.google.com ([2a00:79e0:d:210:8881:1f48:4120:d051]) (user=gprocida job=sendgmr) by 2002:a17:906:5e4f:b0:6d6:e3d0:e558 with SMTP id b15-20020a1709065e4f00b006d6e3d0e558mr11483054eju.118.1646319385017; Thu, 03 Mar 2022 06:56:25 -0800 (PST) Date: Thu, 3 Mar 2022 14:56:19 +0000 Message-Id: <20220303145619.385117-1-gprocida@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.35.1.574.g5d30c73bfb-goog Subject: [PATCH] Increase stability of child diff order To: libabigail@sourceware.org X-Spam-Status: No, score=-21.8 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libabigail@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Giuliano Procida via Libabigail From: Giuliano Procida Reply-To: Giuliano Procida Cc: maennich@google.com, kernel-team@android.com Errors-To: libabigail-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libabigail" Bug 28939 - diff output is sensitive to implementation of std::sort This change increases the stability of child diff order. One test case is affected, potentially indicating the presence of a bug (should the parameter 1 diff not be reported unconditionally?). * src/abg-comparison-priv.h (diff_less_than_functor::operator()): This now compares the second diff subject names if the first diff subject names are the same. It also handles all possble null pointer values, though in practice they should never occur. * src/abg-comparison.cc (diff::append_child_node): Replace std::sort with std::stable_sort. * tests/data/test-abidiff-exit/test-member-size-report0.txt: Refresh test. Signed-off-by: Giuliano Procida Signed-off-by: Dodji Seketeli --- src/abg-comparison-priv.h | 34 +++++++++++++++---- src/abg-comparison.cc | 6 ++-- .../test-member-size-report0.txt | 15 ++++---- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/abg-comparison-priv.h b/src/abg-comparison-priv.h index 8e2e59c6..bf219f96 100644 --- a/src/abg-comparison-priv.h +++ b/src/abg-comparison-priv.h @@ -340,13 +340,33 @@ struct diff_less_than_functor bool operator()(const diff* l, const diff* r) const { - if (!l || !r || !l->first_subject() || !r->first_subject()) - return false; - - string l_qn = get_name(l->first_subject()); - string r_qn = get_name(r->first_subject()); - - return l_qn < r_qn; + if ((l == nullptr) != (r == nullptr)) + return l < r; + if (l == nullptr) + return true; + const type_or_decl_base* l_first_subject = l->first_subject().get(); + const type_or_decl_base* r_first_subject = r->first_subject().get(); + if ((l_first_subject == nullptr) != (r_first_subject == nullptr)) + return l_first_subject < r_first_subject; + if (l_first_subject != nullptr) + { + string l_qn = get_name(l_first_subject); + string r_qn = get_name(r_first_subject); + if (l_qn != r_qn) + return l_qn < r_qn; + } + const type_or_decl_base* l_second_subject = l->second_subject().get(); + const type_or_decl_base* r_second_subject = r->second_subject().get(); + if ((l_second_subject == nullptr) != (r_second_subject == nullptr)) + return l_second_subject < r_second_subject; + if (l_second_subject != nullptr) + { + string l_qn = get_name(l_second_subject); + string r_qn = get_name(r_second_subject); + if (l_qn != r_qn) + return l_qn < r_qn; + } + return true; } /// An operator that takes two instances of @ref diff_sptr returns diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc index 71048ce2..c7f043c8 100644 --- a/src/abg-comparison.cc +++ b/src/abg-comparison.cc @@ -1999,9 +1999,9 @@ diff::append_child_node(diff_sptr d) priv_->children_.push_back(d.get()); diff_less_than_functor comp; - std::sort(priv_->children_.begin(), - priv_->children_.end(), - comp); + std::stable_sort(priv_->children_.begin(), + priv_->children_.end(), + comp); d->priv_->parent_ = this; } diff --git a/tests/data/test-abidiff-exit/test-member-size-report0.txt b/tests/data/test-abidiff-exit/test-member-size-report0.txt index 5c8ece62..78705efb 100644 --- a/tests/data/test-abidiff-exit/test-member-size-report0.txt +++ b/tests/data/test-abidiff-exit/test-member-size-report0.txt @@ -4,16 +4,15 @@ Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 2 functions with some indirect sub-type change: [C] 'function void reg1(S*, T*, T*)' at test-member-size-v1.cc:26:1 has some indirect sub-type changes: - parameter 1 of type 'S*' has sub-type changes: - in pointed to type 'struct S' at test-member-size-v1.cc:3:1: - type size changed from 128 to 192 (in bits) - 1 data member insertion: - 'int y', at offset 128 (in bits) at test-member-size-v1.cc:6:1 - no data member change (1 filtered); - parameter 2 of type 'T*' has sub-type changes: + parameter 3 of type 'T*' has sub-type changes: in pointed to type 'struct T' at test-member-size-v1.cc:14:1: type size changed from 192 to 256 (in bits) - 1 data member changes (1 filtered): + 2 data member changes: + type of 'S s' changed: + type size changed from 128 to 192 (in bits) + 1 data member insertion: + 'int y', at offset 128 (in bits) at test-member-size-v1.cc:6:1 + no data member change (1 filtered); 'int a' offset changed from 128 to 192 (in bits) (by +64 bits) [C] 'function void reg2(U*)' at test-member-size-v1.cc:27:1 has some indirect sub-type changes: