From patchwork Wed Aug 11 16:10:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 44641 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 759C43982404 for ; Wed, 11 Aug 2021 16:10:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 759C43982404 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1628698253; bh=C4Yy5oIjFFTx3NdSS8WF1wkXOdycU791lesX1km/wRM=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:From; b=c1VFRGmYNPEpS3YyBZ+tMK1mE5t+BkPrJAaZL/nSYxm1kPuiB3fPLAim8gVGPMv+0 KEcXZw5EJc+ECKG/anEpYQGljduEMHBzdaArB4qxsWKY/z61SSLvfcxPRKOMkd2Pei YDJU2s3HDI8VHkzUiB7u4j9eCodbywd6DER/5FM0= 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 ESMTP id 778AC3982413 for ; Wed, 11 Aug 2021 16:10:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 778AC3982413 Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-152-ZhacxstrM0WICkKADSgrfA-1; Wed, 11 Aug 2021 12:10:39 -0400 X-MC-Unique: ZhacxstrM0WICkKADSgrfA-1 Received: by mail-wm1-f71.google.com with SMTP id f25-20020a1c6a190000b029024fa863f6b0so2268573wmc.1 for ; Wed, 11 Aug 2021 09:10:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:organization:date:message-id :user-agent:mime-version; bh=C4Yy5oIjFFTx3NdSS8WF1wkXOdycU791lesX1km/wRM=; b=ZYA+GPnPkavCkXc8FC10u9LsGHFQxBxbLlqbhNMIZTuJ/Tr6OnvZftScAgPuEx5ZXt sKJrZ4whWmYeyTsyNQPC+k/N1OgUTzCuGO6chToMym9PeQH16fgEDu3bk4nfCUMstcET rOVZjTj4h+3ShpcVvg24x4OOrUVocDha6xE2tQsTbdiN8xa8gOmtjLAoclKpxUlY8PcY xq7FSgcCQg9CRGjZVwDg8Ceej+BVbnZvbWsH/bnlqFxfkH5X+M1fH4n8ZWbUHL2lZ57h Pxg0/8+HdfnUp5zmCNQBpo/ZrQA40ICKWb1Gdhl32BQKX6+As0Ylb/pWAvBh+Hz8uI4s xvWg== X-Gm-Message-State: AOAM530wIpSNELSeo30LPyM/r5gDW6vII9zjhCw6Z6kMn8PD4ynEM8eF yTy4LeqTsP6uuNreQioTqlLT717pHLns/LgNyw00dxXMldXU/S1xsF7ofV/sN7O00ahrzAbMFkM GPo3eyHiD3F6PrX7YdVQn312ujE0ZptvHo7rO4mdxDw5JZ74hTftFXflbbLdJNvqRLQyT X-Received: by 2002:a7b:c083:: with SMTP id r3mr29400567wmh.65.1628698237501; Wed, 11 Aug 2021 09:10:37 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy4BO08RUbIuLNAM7Zp7M//PLhuP/DztqZofPHFcdR1TdUiunExnfQn7RM1H82hGIaA1Szsxg== X-Received: by 2002:a7b:c083:: with SMTP id r3mr29400538wmh.65.1628698237221; Wed, 11 Aug 2021 09:10:37 -0700 (PDT) Received: from localhost ([88.120.130.27]) by smtp.gmail.com with ESMTPSA id p2sm27820805wrr.21.2021.08.11.09.10.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Aug 2021 09:10:36 -0700 (PDT) Received: by localhost (Postfix, from userid 1000) id D29DE5800FB; Wed, 11 Aug 2021 18:10:33 +0200 (CEST) To: libabigail@sourceware.org Subject: [PATCH 7/8, applied] Bug 27236 - Don't forget to emit some referenced types Organization: Red Hat / France X-Operating-System: Fedora 35 X-URL: http://www.redhat.com Date: Wed, 11 Aug 2021 18:10:33 +0200 Message-ID: <87h7fwc686.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=-12.3 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_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libabigail@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Dodji Seketeli via Libabigail From: Dodji Seketeli Reply-To: Dodji Seketeli Errors-To: libabigail-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libabigail" Hello, Since we arranged to only emit referenced types in translation units where they belong, it appears that in some cases we forget to emit some referenced types. This is because some referenced types might belong to a translation unit that is *already* emitted by the time we detect that a type is referenced. To fix this correctly, we should probably have a pass that walks the corpus to detect referenced types, so that we have their set even before we start emitting translation units. But for now, the patch just detects when we are emitting the last translation unit. In that case all the non-emitted referenced types are emitted. It doesn't seem to be an issue if those don't belong to that translation unit, compared to their original (from the DWARF) type. * include/abg-writer.h (write_translation_unit): Add a new parameter that says if we are emitting the last TU. * src/abg-writer.cc (write_translation_unit::{type_is_emitted, decl_only_type_is_emitted}): Constify these methods. (write_context::has_non_emitted_referenced_types): Define new member function using the const methods above. (write_translation_unit): When emitting the last TU, emit all the referenced types. (write_corpus): Set signal when emitting the last translation unit. Signed-off-by: Dodji Seketeli Applied to master. --- include/abg-writer.h | 3 +- src/abg-writer.cc | 103 ++++++++++++++++++++++++++++++++----------- 2 files changed, 79 insertions(+), 27 deletions(-) diff --git a/include/abg-writer.h b/include/abg-writer.h index 70d118a5..b6bdcb21 100644 --- a/include/abg-writer.h +++ b/include/abg-writer.h @@ -100,7 +100,8 @@ set_ostream(write_context& ctxt, ostream& os); bool write_translation_unit(write_context& ctxt, const translation_unit& tu, - const unsigned indent); + const unsigned indent, + bool last = true); bool write_corpus_to_archive(const corpus& corp, diff --git a/src/abg-writer.cc b/src/abg-writer.cc index ee24c17d..bf460eed 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -505,6 +505,30 @@ public: get_referenced_non_canonical_types() const {return m_referenced_non_canonical_types_set;} + /// Test if there are non emitted referenced types. + /// + /// @return true iff there are non emitted referenced types. + bool + has_non_emitted_referenced_types() const + { + for (const auto t : get_referenced_types()) + if (!type_is_emitted(t) + && !decl_only_type_is_emitted(t)) + return false; + + for (const auto t : get_referenced_non_canonical_types()) + if (!type_is_emitted(t) + && !decl_only_type_is_emitted(t)) + return false; + + for (const auto t : get_referenced_non_canonical_types()) + if (!type_is_emitted(t) + && !decl_only_type_is_emitted(t)) + return false; + + return true; + } + /// Record a given type as being referenced by a pointer, a /// reference or a typedef type that is being emitted to the XML /// output. @@ -708,7 +732,7 @@ public: /// @return true if the type has already been emitted, false /// otherwise. bool - type_is_emitted(const type_base *t) + type_is_emitted(const type_base *t) const { return m_emitted_type_set.find(t) != m_emitted_type_set.end(); } @@ -720,7 +744,7 @@ public: /// @return true if the type has already been emitted, false /// otherwise. bool - type_is_emitted(const type_base_sptr& t) + type_is_emitted(const type_base_sptr& t) const {return type_is_emitted(t.get());} /// Test if the name of a given decl has been written out to the XML @@ -783,7 +807,7 @@ public: /// @return true iff the declaration-only class @p t has been /// emitted. bool - decl_only_type_is_emitted(const type_base* t) + decl_only_type_is_emitted(const type_base* t) const { type_ptr_set_type::const_iterator i = m_emitted_decl_only_set.find(t); if (i == m_emitted_decl_only_set.end()) @@ -798,7 +822,7 @@ public: /// @return true iff the declaration-only class @p t has been /// emitted. bool - decl_only_type_is_emitted(const type_base_sptr& t) + decl_only_type_is_emitted(const type_base_sptr& t) const {return decl_only_type_is_emitted(t.get());} /// Record a declaration as emitted in the abixml output. @@ -2228,12 +2252,31 @@ write_canonical_types_of_scope(const scope_decl &scope, /// @param indent how many indentation spaces to use during the /// serialization. /// +/// @param is_last If true, it means the TU to emit is the last one of +/// the corpus. If this is the case, all the remaining referenced +/// types that were not emitted are going to be emitted here, +/// irrespective of if they belong to this TU or not. This is quite a +/// hack. Ideally, we should have a pass that walks all the TUs, +/// detect their non-emitted referenced types, before hand. Then, +/// when we start emitting the TUs, we know for each TU which +/// non-emitted referenced type should be emitted. As we don't yet +/// have such a pass, we do our best for now. +/// /// @return true upon successful completion, false otherwise. bool -write_translation_unit(write_context& ctxt, - const translation_unit& tu, - const unsigned indent) +write_translation_unit(write_context& ctxt, + const translation_unit& tu, + const unsigned indent, + bool is_last) { + if (tu.is_empty() && !is_last) + return false; + + if (is_last + && tu.is_empty() + && ctxt.has_non_emitted_referenced_types()) + return false; + ostream& o = ctxt.get_ostream(); const config& c = ctxt.get_config(); @@ -2259,7 +2302,7 @@ write_translation_unit(write_context& ctxt, << translation_unit_language_to_string(tu.get_language()) <<"'"; - if (tu.is_empty()) + if (tu.is_empty() && !is_last) { o << "/>\n"; return true; @@ -2304,18 +2347,20 @@ write_translation_unit(write_context& ctxt, // So this map of type -> string is to contain the referenced types // we need to emit. type_ptr_set_type referenced_types_to_emit; - for (type_ptr_set_type::const_iterator i = ctxt.get_referenced_types().begin(); i != ctxt.get_referenced_types().end(); ++i) - if (!ctxt.type_is_emitted(*i) - && !ctxt.decl_only_type_is_emitted(*i) - // Ensure that the referenced type is emitted in the - // translation that it belongs to. - && ((*i)->get_translation_unit()->get_absolute_path() - == tu.get_absolute_path())) + { + if (!ctxt.type_is_emitted(*i) + && !ctxt.decl_only_type_is_emitted(*i) + // Ensure that the referenced type is emitted in the + // translation that it belongs to. + && (is_last + || ((*i)->get_translation_unit()->get_absolute_path() + == tu.get_absolute_path()))) referenced_types_to_emit.insert(*i); + } for (fn_type_ptr_set_type::const_iterator i = ctxt.get_referenced_function_types().begin(); @@ -2325,8 +2370,9 @@ write_translation_unit(write_context& ctxt, && !ctxt.decl_only_type_is_emitted(*i) // Ensure that the referenced type is emitted in the // translation that it belongs to. - && ((*i)->get_translation_unit()->get_absolute_path() - == tu.get_absolute_path())) + && (is_last + || ((*i)->get_translation_unit()->get_absolute_path() + == tu.get_absolute_path()))) // A referenced type that was not emitted at all must be // emitted now. referenced_types_to_emit.insert(*i); @@ -2339,8 +2385,9 @@ write_translation_unit(write_context& ctxt, && !ctxt.decl_only_type_is_emitted(*i) // Ensure that the referenced type is emitted in the // translation that it belongs to. - && ((*i)->get_translation_unit()->get_absolute_path() - == tu.get_absolute_path())) + && (is_last + || ((*i)->get_translation_unit()->get_absolute_path() + == tu.get_absolute_path()))) // A referenced type that was not emitted at all must be // emitted now. referenced_types_to_emit.insert(*i); @@ -2399,8 +2446,9 @@ write_translation_unit(write_context& ctxt, && !ctxt.decl_only_type_is_emitted(*i) // Ensure that the referenced type is emitted in the // translation that it belongs to. - && ((*i)->get_translation_unit()->get_absolute_path() - == tu.get_absolute_path())) + && (is_last + || ((*i)->get_translation_unit()->get_absolute_path() + == tu.get_absolute_path()))) // A referenced type that was not emitted at all must be // emitted now. referenced_types_to_emit.insert(*i); @@ -2413,8 +2461,9 @@ write_translation_unit(write_context& ctxt, && !ctxt.decl_only_type_is_emitted(*i) // Ensure that the referenced type is emitted in the // translation that it belongs to. - && ((*i)->get_translation_unit()->get_absolute_path() - == tu.get_absolute_path())) + && (is_last + || ((*i)->get_translation_unit()->get_absolute_path() + == tu.get_absolute_path()))) // A referenced type that was not emitted at all must be // emitted now. referenced_types_to_emit.insert(*i); @@ -4453,14 +4502,16 @@ write_corpus(write_context& ctxt, } // Now write the translation units. + unsigned nb_tus = corpus->get_translation_units().size(), n = 0; for (translation_units::const_iterator i = corpus->get_translation_units().begin(); i != corpus->get_translation_units().end(); - ++i) + ++i, ++n) { translation_unit& tu = **i; - if (!tu.is_empty()) - write_translation_unit(ctxt, tu, get_indent_to_level(ctxt, indent, 1)); + write_translation_unit(ctxt, tu, + get_indent_to_level(ctxt, indent, 1), + n == nb_tus - 1); } do_indent_to_level(ctxt, indent, 0);