From patchwork Mon Mar 27 09:38:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 66933 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 EB79F3858C50 for ; Mon, 27 Mar 2023 09:38:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EB79F3858C50 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679909940; bh=r0pVpQvaaqpTQlwBQmkg7ALQH+/Sz8XQ4V7aQBG26vA=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:From; b=M8m/Hng8Lj/EJQxaf6TzJIpQToOEqZ7g56Fys+elZD84DrO0OyNSYUq/KaCCfPUkq kvT8ZHeSb83noHcftItKIlAU3lfRZ2+WXOiidw8SrJQz7WNM2xX182/N6HGtva/nCy rH5iZZltGVPPi9AS3NSbRzTWECCQZuSoVb+c9l1A= 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 EB6E63858D39 for ; Mon, 27 Mar 2023 09:38:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EB6E63858D39 Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-618-9ETlulH8MXOGUrY6A806Rw-1; Mon, 27 Mar 2023 05:38:53 -0400 X-MC-Unique: 9ETlulH8MXOGUrY6A806Rw-1 Received: by mail-qv1-f70.google.com with SMTP id g6-20020ad45426000000b005a33510e95aso3264209qvt.16 for ; Mon, 27 Mar 2023 02:38:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679909933; h=mime-version:user-agent:message-id:date:organization:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=r0pVpQvaaqpTQlwBQmkg7ALQH+/Sz8XQ4V7aQBG26vA=; b=fR78XweaKGagY3q0aKh/bqRWk1vG0N+90xsd6Z9rrto2O+EhNzrjEngaGrJvvcPe0H nuvSnHddS0inV2T/e9dBZt/mrnXY+QkyXnjccDhxmYkWJwdiVHgctzzngX/opzIwMHvD IKKuls/qkd+SX5zriKtWyzD44YVick3Umdi3UZxelD8vHFxvRBUHhuUhMT3GxRyAPcLp pMW+UL8ZowUb5UwLdMY0AaIjBehKb6qKp/6oqqq0LjyD48REWE8YNWlmrxU5fI3fLNwa RuGk7FPJL83+Om9NuI2FzjozKL0fBEPyflQnD97WZrj8EjrzKYiUNkJkPTTskdmyfsIU Occg== X-Gm-Message-State: AAQBX9fXCb0L1FdY897PaZmaK/r3cio2pS3kL5PfmgOTptd3N0TtW3b9 rhxXwQ4JfBiGqMDLLClqiYBOZvbXr2l7a5r/kEfCW/2f6Znrz7bmho3zrQ1Cno5uXF+z+B9acUs sB8UZZR7G31Ckhm7hIXE7Mo8dt3IJIEFqBpWpnzy7CtvjCYb58AHXhJHJFMDe/T7bDxfDUgbfbe XT X-Received: by 2002:a05:6214:2b0c:b0:5c6:cc1b:2ccb with SMTP id jx12-20020a0562142b0c00b005c6cc1b2ccbmr20244305qvb.2.1679909932713; Mon, 27 Mar 2023 02:38:52 -0700 (PDT) X-Google-Smtp-Source: AKy350aWfKLNJQS7fzW5Obt7pWspaSxfD2STtmb37hgBFDHK59nGWRBFMYiDxRit5BBEbOrL3ScyHQ== X-Received: by 2002:a05:6214:2b0c:b0:5c6:cc1b:2ccb with SMTP id jx12-20020a0562142b0c00b005c6cc1b2ccbmr20244288qvb.2.1679909932346; Mon, 27 Mar 2023 02:38:52 -0700 (PDT) Received: from localhost ([88.120.130.27]) by smtp.gmail.com with ESMTPSA id u15-20020a0cee8f000000b005dd8b9345d5sm2802666qvr.109.2023.03.27.02.38.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Mar 2023 02:38:51 -0700 (PDT) Received: by localhost (Postfix, from userid 1000) id 2C500581C79; Mon, 27 Mar 2023 11:38:50 +0200 (CEST) To: libabigail@sourceware.org Subject: [PATCH, applied] Bug 29686 - Fix testing the presence of anonymous data member in a struct Organization: Red Hat / France X-Operating-System: Fedora 38 X-URL: http://www.redhat.com Date: Mon, 27 Mar 2023 11:38:49 +0200 Message-ID: <87fs9qmt3q.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.8 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, When in "updating mode", add_or_update_class_type fails (in some cases) to detect that an anonymous data member has already been added to the class and thus, the class ends up having that data member added twice, leading to issues later down the road. In the particular example filed in this bug, class_or_union::find_data_member is using the flat representation of the type of the data member to try to identify it inside the class. This doesn't work, for instance, if the anonymous data member's type contain a recursive type that is currently being built. To fix that, a new function anonymous_data_member_exists_in_class is introduced. It looks up for every single named sub-member of the anonymous data member inside the class, to see if the anonymous data member exists in the class. That is close to how anonymous data members are meant to work, as far as member lookup is concerned. * include/abg-fwd.h (anonymous_data_member_to_class_or_union): Add a new overload. (anonymous_data_member_exists_in_class): Declare new function. * src/abg-dwarf-reader.cc (add_or_update_class_type): Use the new anonymous_data_member_exists_in_class function. * src/abg-ir.cc (anonymous_data_member_to_class_or_union): Define new function. * tests/data/test-read-dwarf/test-libandroid.so.abi: Adjust. Signed-off-by: Dodji Seketeli --- include/abg-fwd.h | 7 +++ src/abg-dwarf-reader.cc | 3 +- src/abg-ir.cc | 56 +++++++++++++++++++ .../test-read-dwarf/test-libandroid.so.abi | 3 - 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/include/abg-fwd.h b/include/abg-fwd.h index 747a625c..25e67395 100644 --- a/include/abg-fwd.h +++ b/include/abg-fwd.h @@ -727,6 +727,13 @@ anonymous_data_member_to_class_or_union(const var_decl*); class_or_union_sptr anonymous_data_member_to_class_or_union(const var_decl_sptr&); +class_or_union_sptr +anonymous_data_member_to_class_or_union(const var_decl&); + +bool +anonymous_data_member_exists_in_class(const var_decl& anon_dm, + const class_or_union& clazz); + bool scope_anonymous_or_typedef_named(const decl_base&); diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 37367dba..5ca1cee7 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -13138,7 +13138,8 @@ add_or_update_class_type(reader& rdr, die_access_specifier(&child, access); var_decl_sptr dm(new var_decl(n, t, loc, m)); - if (n.empty() && result->find_data_member(dm)) + if (n.empty() + && anonymous_data_member_exists_in_class(*dm, *result)) // dm is an anonymous data member that was already // present in the current class so let's not add it. continue; diff --git a/src/abg-ir.cc b/src/abg-ir.cc index 514013c7..a5b8e90a 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -5951,6 +5951,20 @@ anonymous_data_member_to_class_or_union(const var_decl* d) return 0; } +/// Get the @ref class_or_union type of a given anonymous data member. +/// +/// @param d the anonymous data member to consider. +/// +/// @return the @ref class_or_union type of the anonymous data member +/// @p d. +class_or_union_sptr +anonymous_data_member_to_class_or_union(const var_decl& d) +{ + if (is_anonymous_data_member(d)) + return is_class_or_union_type(d.get_type()); + return class_or_union_sptr(); +} + /// Test if a data member has annonymous type or not. /// /// @param d the data member to consider. @@ -6006,6 +6020,48 @@ anonymous_data_member_to_class_or_union(const var_decl_sptr &d) return class_or_union_sptr(); } +/// Test if a given anonymous data member exists in a class or union. +/// +/// @param anon_dm the anonymous data member to consider. +/// +/// @param clazz the class to consider. +/// +/// @return true iff @p anon_dm exists in the @clazz. +bool +anonymous_data_member_exists_in_class(const var_decl& anon_dm, + const class_or_union& clazz) +{ + if (!anon_dm.get_is_anonymous() + || !is_class_or_union_type(anon_dm.get_type())) + return false; + + class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type()); + ABG_ASSERT(cl); + + // Look for the presence of each data member of anon_dm in clazz. + // + // If one data member of anon_dm is not present in clazz, then the + // data member anon_dm is considered to not exist in clazz. + for (auto anon_dm_m : cl->get_non_static_data_members()) + { + // If the data member anon_dm_m is not an anonymous data member, + // it's easy to look for it. + if (!is_anonymous_data_member(anon_dm_m)) + { + if (!clazz.find_data_member(anon_dm_m->get_name())) + return false; + } + // If anon_dm_m is itself an anonymous data member then recurse + else + { + if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz)) + return false; + } + } + + return true; +} + /// Test if the scope of a given decl is anonymous or anonymous with a /// naming typedef. /// diff --git a/tests/data/test-read-dwarf/test-libandroid.so.abi b/tests/data/test-read-dwarf/test-libandroid.so.abi index 8b15c0e9..4ef47d7a 100644 --- a/tests/data/test-read-dwarf/test-libandroid.so.abi +++ b/tests/data/test-read-dwarf/test-libandroid.so.abi @@ -11061,9 +11061,6 @@ - - -