From patchwork Fri Oct 20 10:01:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 78216 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 A0F7D3858D39 for ; Fri, 20 Oct 2023 10:01:50 +0000 (GMT) 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.129.124]) by sourceware.org (Postfix) with ESMTPS id 2CF1C38582BD for ; Fri, 20 Oct 2023 10:01:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2CF1C38582BD Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2CF1C38582BD Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697796106; cv=none; b=BRUIle9r7CITnKND2hqpHIMA+KNVksIptF/QqtqL2HM4cbjAK5d4d3zCsqS8QaYyaXcdWa9o+UV34PE2gCHER4emrd95yonSvWRiwOtMD8Vav7WvqaNtT/2GagYbTY5e4S9NgPsAbZEw8fpADg2SpfBmzh2MJnsDIJWt+YH4Whs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697796106; c=relaxed/simple; bh=zRD1IyXv5zLcgsa+5kvkMDcz8iPZ+S1G/+rCj334NWs=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=WX52dm5uWl/oxf2cpGBnocpBU/OUH3h708Hn+2JsoJK+Tv+uxpYVmJsyqDWHIS5rusv9GmpEoI7E5SJ4R9jcWkVT653o+Jd7v4R3yDEn4IuDf6ZSytsvy1i4vlK2zQDxdT09wSd6zy5ZMqqENMwyh8ZzPAYEd6mZTLziy967Ado= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1697796102; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=1BdPAvXAuhBnIJmD+6ciFsWRBga3YK6n8Y6c+IeC7xw=; b=Ywtx2j/lP+05pCjfHizqCz0RSR5GeoegI4/T8Lq3wyTpS/BaD9l3rKImug4UwOcU8R/4tZ h9ElJ0EW1qNNkewz3XmkvZSIx09pCkvQqsDRlUA8bEolCB3jcixQyiGIrq5Ocd0Sxpa2yO /bhmDYV/+Dwpc1EcjpL57l/fVbSZ8F8= Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-319-9a8eDKyXMVmkyxouAb2A0w-1; Fri, 20 Oct 2023 06:01:41 -0400 X-MC-Unique: 9a8eDKyXMVmkyxouAb2A0w-1 Received: by mail-qk1-f200.google.com with SMTP id af79cd13be357-77892f2ee51so74058685a.1 for ; Fri, 20 Oct 2023 03:01:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697796101; x=1698400901; 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=1BdPAvXAuhBnIJmD+6ciFsWRBga3YK6n8Y6c+IeC7xw=; b=Qs7py4SAgmA+D+uKjj4TDO2NbfouTO4AbzpvnD93WygzJgwjSBrLNH/NynISMQf81V t5YLhu8v/OeWdeDOXVHHKPbysHhW4S0RFbUW+aLQUCHg7QOsOdWQXw/ZlDuduBJ4+oND M176j18RbGpS0Q6TN+5rG7damn1nOQ+cIht7TkE+hR4i110eGMbVvTdbJTINCMlT71ZD EnZ9BJ8evYBQAs0yxVg3D+tdK5KQnGfg98KWcXB0J3V9Meir2hz6UYtLETGMQ9hdu2P3 GCJzbWk7BmKHbG4DqAphiS1sW+ozwAgcQjaGZsGLGIYEK+OgACou+/ykwR9IkBR6N9JD HIyQ== X-Gm-Message-State: AOJu0YxYSgUTIjV2UBHKhCMYtQIOfKbvaRhIDHcXhLtJwAHb+2J1WqIJ G+agNAFNPGHNNDdy9vLEB1o+LtKmyRnjmsAh2bdGnaZcu4uQMXXSEJ9u8MUVApRNidBiAnd5sCE DbyaWQgUOw3ryF4+hbTt6 X-Received: by 2002:a05:622a:134d:b0:41c:c692:e3ed with SMTP id w13-20020a05622a134d00b0041cc692e3edmr1499078qtk.34.1697796099772; Fri, 20 Oct 2023 03:01:39 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEzKeTUVh7WmdTnPbf0sotf7ia+CD4wxx6OKVsyABDxE/GCOG46pg9bsD+WJcjFkcXrkQ6ujw== X-Received: by 2002:a05:622a:134d:b0:41c:c692:e3ed with SMTP id w13-20020a05622a134d00b0041cc692e3edmr1499029qtk.34.1697796098920; Fri, 20 Oct 2023 03:01:38 -0700 (PDT) Received: from localhost ([88.120.130.27]) by smtp.gmail.com with ESMTPSA id l9-20020ac80789000000b00419732075b4sm468502qth.84.2023.10.20.03.01.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 03:01:38 -0700 (PDT) Received: by localhost (Postfix, from userid 1000) id BCFD95077C49; Fri, 20 Oct 2023 12:01:36 +0200 (CEST) From: Dodji Seketeli To: Dodji Seketeli Cc: John Moon , Trilok Soni , Satya Durga Srinivasu Prabhala , libabigail@sourceware.org Subject: [PATCH 5/7, applied] comparison: Represent changed unreachable anonymous unions, structs & enums Organization: Red Hat / France References: <87cyx97h4j.fsf@redhat.com> X-Operating-System: AlmaLinux 9.2 X-URL: http://www.redhat.com Date: Fri, 20 Oct 2023 12:01:36 +0200 In-Reply-To: <87cyx97h4j.fsf@redhat.com> (Dodji Seketeli's message of "Fri, 20 Oct 2023 11:55:24 +0200") Message-ID: <87r0lp629r.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, 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.30 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libabigail-bounces+patchwork=sourceware.org@sourceware.org Hello, Following the changes to represent changed anonymous unreachable enums, this patch does the same for anonymous unreachable unions, classes and structs. Basically, without this patch, this change: union { int a; int b; }; ------ union { int a; int b; int c; }; yields: 1 removed type unreachable from any public interface: [D] 'union {int a; int b;}' at test_1.c:1:1 1 added type unreachable from any public interface: [A] 'union {int a; int b; int c;}' at test_2.c:1:1 But with the patch, it does yield: 1 changed type unreachable from any public interface: [C] 'union {int a; int b;}' changed: type size hasn't changed 1 data member insertion: 'int c' at test-anon-union-v1.c:5:1 type changed from: union {int a; int b;} to: union {int a; int b; int c;} * include/abg-fwd.h (class_or_union_types_of_same_kind) (is_data_member_of_anonymous_class_or_union): Declare new functions. * include/abg-ir.h (lookup_data_member): Likewise, declare a new overload. * src/abg-ir.cc (class_or_union_types_of_same_kind) (lookup_data_member, is_data_member_of_anonymous_class_or_union): Define news functions & overloads. * src/abg-reporter-priv.cc (represent): When representing a change in the name of a data member, if the context is an anonymous type, use the non-qualified name of the data member, not its qualified name. * src/abg-comparison.cc (corpus_diff::priv::ensure_lookup_tables_populated): Handle deleted/added anonymous enums, unions, classes and structs similarly. That is, if an anonymous type was removed and another one got added, if they both have data members (or enumerators) in common, then we are probably looking at an anonymous type that was changed. This is because these anonymous types are named using their flat representation. * tests/data/test-abidiff-exit/test-anon-types-report-1.txt: New reference test comparison output. * tests/data/test-abidiff-exit/test-anon-types-v{0,1}.o: New binary tests input files. * tests/data/test-abidiff-exit/test-anon-types-v{0,1}.c: Source code of new binary test input. * tests/data/Makefile.am: Add the new test material above to source distribution. * tests/test-abidiff-exit.cc (in_out_specs): Add the test inputs above to this test harness. Signed-off-by: Dodji Seketeli Applied to master. --- include/abg-fwd.h | 17 ++ include/abg-ir.h | 4 + src/abg-comparison.cc | 162 ++++++++++++------ src/abg-ir.cc | 92 ++++++++++ src/abg-reporter-priv.cc | 8 +- tests/data/Makefile.am | 5 + .../test-anon-types-report-1.txt | 31 ++++ .../test-abidiff-exit/test-anon-types-v0.c | 42 +++++ .../test-abidiff-exit/test-anon-types-v0.o | Bin 0 -> 3240 bytes .../test-abidiff-exit/test-anon-types-v1.c | 33 ++++ .../test-abidiff-exit/test-anon-types-v1.o | Bin 0 -> 3168 bytes tests/test-abidiff-exit.cc | 16 ++ 12 files changed, 360 insertions(+), 50 deletions(-) create mode 100644 tests/data/test-abidiff-exit/test-anon-types-report-1.txt create mode 100644 tests/data/test-abidiff-exit/test-anon-types-v0.c create mode 100644 tests/data/test-abidiff-exit/test-anon-types-v0.o create mode 100644 tests/data/test-abidiff-exit/test-anon-types-v1.c create mode 100644 tests/data/test-abidiff-exit/test-anon-types-v1.o new file mode 100644 index 00000000..73716a1f index 4c1eaea5..b9ea4792 100644 diff --git a/include/abg-fwd.h b/include/abg-fwd.h index e494de07..0edc9927 100644 --- a/include/abg-fwd.h +++ b/include/abg-fwd.h @@ -495,6 +495,14 @@ is_class_or_union_type(const type_or_decl_base*); class_or_union_sptr is_class_or_union_type(const type_or_decl_base_sptr&); +bool +class_or_union_types_of_same_kind(const class_or_union *, + const class_or_union*); + +bool +class_or_union_types_of_same_kind(const class_or_union_sptr&, + const class_or_union_sptr&); + bool is_union_type(const type_or_decl_base&); @@ -731,6 +739,15 @@ is_anonymous_data_member(const var_decl*); bool is_anonymous_data_member(const var_decl&); +bool +is_data_member_of_anonymous_class_or_union(const var_decl&); + +bool +is_data_member_of_anonymous_class_or_union(const var_decl*); + +bool +is_data_member_of_anonymous_class_or_union(const var_decl_sptr&); + const var_decl_sptr get_first_non_anonymous_data_member(const var_decl_sptr); diff --git a/include/abg-ir.h b/include/abg-ir.h index b599ef3e..0cb378ad 100644 --- a/include/abg-ir.h +++ b/include/abg-ir.h @@ -4626,6 +4626,10 @@ const var_decl* lookup_data_member(const type_base* type, const char* dm_name); +const var_decl_sptr +lookup_data_member(const type_base_sptr& type, + const var_decl_sptr& dm); + const function_decl::parameter* get_function_parameter(const decl_base* fun, unsigned parm_num); diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc index 1126ed58..8a705c54 100644 --- a/src/abg-comparison.cc +++ b/src/abg-comparison.cc @@ -9630,69 +9630,135 @@ corpus_diff::priv::ensure_lookup_tables_populated() // to show what the user expects, namely, a changed anonymous // enum. { - std::set deleted_anon_enums; - std::set added_anon_enums; + std::set deleted_anon_types; + std::set added_anon_types; for (auto entry : deleted_unreachable_types_) - if (is_enum_type(entry.second) - && is_enum_type(entry.second)->get_is_anonymous()) - deleted_anon_enums.insert(is_enum_type(entry.second)); - - for (auto entry : added_unreachable_types_) - if (is_enum_type(entry.second) - && is_enum_type(entry.second)->get_is_anonymous()) - added_anon_enums.insert(is_enum_type(entry.second)); + { + if ((is_enum_type(entry.second) + && is_enum_type(entry.second)->get_is_anonymous()) + || (is_class_or_union_type(entry.second) + && is_class_or_union_type(entry.second)->get_is_anonymous())) + deleted_anon_types.insert(entry.second); + } - string_type_base_sptr_map added_anon_enum_to_erase; - string_type_base_sptr_map removed_anon_enum_to_erase; - // Look for deleted anonymous enums which have enumerators - // present in an added anonymous enums ... - for (auto deleted_enum : deleted_anon_enums) + for (auto entry : added_unreachable_types_) + if ((is_enum_type(entry.second) + && is_enum_type(entry.second)->get_is_anonymous()) + || (is_class_or_union_type(entry.second) + && is_class_or_union_type(entry.second)->get_is_anonymous())) + added_anon_types.insert(entry.second); + + string_type_base_sptr_map added_anon_types_to_erase; + string_type_base_sptr_map removed_anon_types_to_erase; + enum_type_decl_sptr deleted_enum; + class_or_union_sptr deleted_class; + + // Look for deleted anonymous types (enums, unions, structs & + // classes) which have enumerators or data members present in an + // added anonymous type ... + for (auto deleted: deleted_anon_types) { - // Look for any enumerator of 'deleted_enum' that is also - // present in an added anonymous enum. - for (auto enr : deleted_enum->get_enumerators()) + deleted_enum = is_enum_type(deleted); + deleted_class = is_class_or_union_type(deleted); + + // For enums, look for any enumerator of 'deleted_enum' that + // is also present in an added anonymous enum. + if (deleted_enum) { - bool this_enum_got_changed = false; - for (auto added_enum : added_anon_enums) + for (auto enr : deleted_enum->get_enumerators()) { - if (is_enumerator_present_in_enum(enr, *added_enum)) + bool this_enum_got_changed = false; + for (auto t : added_anon_types) { - // So the enumerator 'enr' from the - // 'deleted_enum' enum is also present in the - // 'added_enum' enum so we assume that - // 'deleted_enum' and 'added_enum' are the same - // enum that got changed. Let's represent it - // using a diff node. - diff_sptr d = compute_diff(deleted_enum, - added_enum, ctxt); - ABG_ASSERT(d->has_changes()); - string repr = - abigail::ir::get_pretty_representation(is_type(deleted_enum), - /*internal=*/false); - changed_unreachable_types_[repr]= d; - this_enum_got_changed = true; - string r1 = abigail::ir::get_pretty_representation(is_type(deleted_enum)); - string r2 = abigail::ir::get_pretty_representation(is_type(added_enum)); - removed_anon_enum_to_erase[r1] = deleted_enum; - added_anon_enum_to_erase[r2] = added_enum; - break; + if (enum_type_decl_sptr added_enum = is_enum_type(t)) + if (is_enumerator_present_in_enum(enr, *added_enum)) + { + // So the enumerator 'enr' from the + // 'deleted_enum' enum is also present in the + // 'added_enum' enum so we assume that + // 'deleted_enum' and 'added_enum' are the same + // enum that got changed. Let's represent it + // using a diff node. + diff_sptr d = compute_diff(deleted_enum, + added_enum, ctxt); + ABG_ASSERT(d->has_changes()); + string repr = + abigail::ir::get_pretty_representation(is_type(deleted_enum), + /*internal=*/false); + changed_unreachable_types_[repr]= d; + this_enum_got_changed = true; + string r1 = + abigail::ir::get_pretty_representation(is_type(deleted_enum), + /*internal=*/false); + string r2 = + abigail::ir::get_pretty_representation(is_type(added_enum), + /*internal=*/false); + removed_anon_types_to_erase[r1] = deleted_enum; + added_anon_types_to_erase[r2] = added_enum; + break; + } } + if (this_enum_got_changed) + break; + } + } + else if (deleted_class) + { + // For unions, structs & classes, look for any data + // member of 'deleted_class' that is also present in an + // added anonymous class. + for (auto dm : deleted_class->get_data_members()) + { + bool this_class_got_changed = false; + for (auto klass : added_anon_types) + { + if (class_or_union_sptr added_class = + is_class_or_union_type(klass)) + if (class_or_union_types_of_same_kind(deleted_class, + added_class) + && lookup_data_member(added_class, dm)) + { + // So the data member 'dm' from the + // 'deleted_class' class is also present in + // the 'added_class' class so we assume that + // 'deleted_class' and 'added_class' are the + // same anonymous class that got changed. + // Let's represent it using a diff node. + diff_sptr d = compute_diff(is_type(deleted_class), + is_type(added_class), + ctxt); + ABG_ASSERT(d->has_changes()); + string repr = + abigail::ir::get_pretty_representation(is_type(deleted_class), + /*internal=*/false); + changed_unreachable_types_[repr]= d; + this_class_got_changed = true; + string r1 = + abigail::ir::get_pretty_representation(is_type(deleted_class), + /*internal=*/false); + string r2 = + abigail::ir::get_pretty_representation(is_type(added_class), + /*internal=*/false); + removed_anon_types_to_erase[r1] = deleted_class; + added_anon_types_to_erase[r2] = added_class; + break; + } + } + if (this_class_got_changed) + break; } - if (this_enum_got_changed) - break; } } - // Now remove the added/removed anonymous enums from their maps, - // as they are now represented as a changed enum, not an added - // and removed enum. - - for (auto entry : added_anon_enum_to_erase) + // Now remove the added/removed anonymous types from their maps, + // as they are now represented as a changed type, not an added + // and removed anonymous type. + for (auto entry : added_anon_types_to_erase) added_unreachable_types_.erase(entry.first); - for (auto entry : removed_anon_enum_to_erase) + for (auto entry : removed_anon_types_to_erase) deleted_unreachable_types_.erase(entry.first); } } diff --git a/src/abg-ir.cc b/src/abg-ir.cc index 171267f8..bb9483c9 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -6061,6 +6061,47 @@ is_anonymous_data_member(const var_decl& d) && is_class_or_union_type(d.get_type())); } +/// Test if a @ref var_decl is a data member belonging to an anonymous +/// type. +/// +/// @param d the @ref var_decl to consider. +/// +/// @return true iff @p d is a data member belonging to an anonymous +/// type. +bool +is_data_member_of_anonymous_class_or_union(const var_decl& d) +{ + if (is_data_member(d)) + { + scope_decl* scope = d.get_scope(); + if (scope && scope->get_is_anonymous()) + return true; + } + return false; +} + +/// Test if a @ref var_decl is a data member belonging to an anonymous +/// type. +/// +/// @param d the @ref var_decl to consider. +/// +/// @return true iff @p d is a data member belonging to an anonymous +/// type. +bool +is_data_member_of_anonymous_class_or_union(const var_decl* d) +{return is_data_member_of_anonymous_class_or_union(*d);} + +/// Test if a @ref var_decl is a data member belonging to an anonymous +/// type. +/// +/// @param d the @ref var_decl to consider. +/// +/// @return true iff @p d is a data member belonging to an anonymous +/// type. +bool +is_data_member_of_anonymous_class_or_union(const var_decl_sptr& d) +{return is_data_member_of_anonymous_class_or_union(d.get());} + /// Get the @ref class_or_union type of a given anonymous data member. /// /// @param d the anonymous data member to consider. @@ -10791,6 +10832,36 @@ shared_ptr is_class_or_union_type(const shared_ptr& t) {return dynamic_pointer_cast(t);} +/// Test if two class or union types are of the same kind. +/// +/// @param first the first type to consider. +/// +/// @param second the second type to consider. +/// +/// @return true iff @p first is of the same kind as @p second. +bool +class_or_union_types_of_same_kind(const class_or_union* first, + const class_or_union* second) +{ + if ((is_class_type(first) && is_class_type(second)) + || (is_union_type(first) && is_union_type(second))) + return true; + + return false; +} + +/// Test if two class or union types are of the same kind. +/// +/// @param first the first type to consider. +/// +/// @param second the second type to consider. +/// +/// @return true iff @p first is of the same kind as @p second. +bool +class_or_union_types_of_same_kind(const class_or_union_sptr& first, + const class_or_union_sptr& second) +{return class_or_union_types_of_same_kind(first.get(), second.get());} + /// Test if a type is a @ref union_decl. /// /// @param t the type to consider. @@ -27430,6 +27501,27 @@ lookup_data_member(const type_base* type, return cou->find_data_member(dm_name).get(); } +/// Look for a data member of a given class, struct or union type and +/// return it. +/// +/// The data member is designated by its name. +/// +/// @param type the class, struct or union type to consider. +/// +/// @param dm the data member to lookup. +/// +/// @return the data member iff it was found in @type or NULL if no +/// data member with that name was found. +const var_decl_sptr +lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm) +{ + class_or_union_sptr cou = is_class_or_union_type(type); + if (!cou) + return var_decl_sptr(); + + return cou->find_data_member(dm); +} + /// Get the function parameter designated by its index. /// /// Note that the first function parameter has index 0. diff --git a/src/abg-reporter-priv.cc b/src/abg-reporter-priv.cc index cc38f240..c8122af3 100644 --- a/src/abg-reporter-priv.cc +++ b/src/abg-reporter-priv.cc @@ -402,8 +402,12 @@ represent(const var_diff_sptr &diff, const bool o_anon = !!is_anonymous_data_member(o); const bool n_anon = !!is_anonymous_data_member(n); const bool is_strict_anonymous_data_member_change = o_anon && n_anon; - const string o_name = o->get_qualified_name(); - const string n_name = n->get_qualified_name(); + const string o_name = (is_data_member_of_anonymous_class_or_union(o) + ? o->get_name() + : o->get_qualified_name()); + const string n_name = (is_data_member_of_anonymous_class_or_union(n) + ? n->get_name() + : n->get_qualified_name()); const uint64_t o_size = get_var_size_in_bits(o); const uint64_t n_size = get_var_size_in_bits(n); const uint64_t o_offset = get_data_member_offset(o); diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index adb6d8bd..3134df7d 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -362,6 +362,11 @@ test-abidiff-exit/test-anonymous-enums-change-v0.c \ test-abidiff-exit/test-anonymous-enums-change-v0.o \ test-abidiff-exit/test-anonymous-enums-change-v1.c \ test-abidiff-exit/test-anonymous-enums-change-v1.o \ +test-abidiff-exit/test-anon-types-report-1.txt \ +test-abidiff-exit/test-anon-types-v0.c \ +test-abidiff-exit/test-anon-types-v0.o \ +test-abidiff-exit/test-anon-types-v1.c \ +test-abidiff-exit/test-anon-types-v1.o \ \ test-diff-dwarf/test0-v0.cc \ test-diff-dwarf/test0-v0.o \ diff --git a/tests/data/test-abidiff-exit/test-anon-types-report-1.txt b/tests/data/test-abidiff-exit/test-anon-types-report-1.txt new file mode 100644 index 00000000..916b880d --- /dev/null +++ b/tests/data/test-abidiff-exit/test-anon-types-report-1.txt @@ -0,0 +1,31 @@ +Functions changes summary: 0 Removed, 0 Changed, 0 Added function +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable +Unreachable types summary: 2 removed, 3 changed, 0 added types + +2 removed types unreachable from any public interface: + + [D] 'struct {char z; int w;}' at test-anon-types-v0.c:34:1 + [D] 'union {char x; unsigned int y;}' at test-anon-types-v0.c:28:1 + +3 changed types unreachable from any public interface: + + [C] 'struct {int a; int b;}' changed: + type size changed from 64 to 96 (in bits) + 1 data member insertion: + 'int c', at offset 64 (in bits) at test-anon-types-v1.c:18:1 + + [C] 'enum {a=0, b=1, c=2, d=3, }' changed: + type size hasn't changed + 2 enumerator insertions: + 'e' value '4' + 'f' value '5' + + [C] 'union {int a; int b; int d;}' changed: + type size hasn't changed + 1 data member change: + name of 'd' changed to 'c' at test-anon-types-v1.c:11:1 + type changed from: + union {int a; int b; int d;} + to: + union {int a; int b; int c;} + diff --git a/tests/data/test-abidiff-exit/test-anon-types-v0.c b/tests/data/test-abidiff-exit/test-anon-types-v0.c new file mode 100644 index 00000000..2f9a2599 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-anon-types-v0.c @@ -0,0 +1,42 @@ +/** + * Compile with: + * + * gcc -c -g -fno-eliminate-unused-debug-types test-anon-types-v{0,1}.c + */ + +union +{ + int a; + int b; + int d; +}; + +struct +{ + int a; + int b; +}; + +enum +{ + a, + b, + c, + d +}; + +union +{ + char x; + unsigned y; +}; + +struct +{ + char z; + int w; +}; + +void +fun() +{} diff --git a/tests/data/test-abidiff-exit/test-anon-types-v0.o b/tests/data/test-abidiff-exit/test-anon-types-v0.o new file mode 100644 index 0000000000000000000000000000000000000000..32d7fdfc3631aa467094410a8df1e50d39792972 GIT binary patch literal 3240 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 literal 0 HcmV?d00001 diff --git a/tests/test-abidiff-exit.cc b/tests/test-abidiff-exit.cc --- a/tests/test-abidiff-exit.cc +++ b/tests/test-abidiff-exit.cc @@ -1064,6 +1064,22 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-anonymous-enums-change-report-v1.txt", "output/test-abidiff-exit/test-anonymous-enums-change-report-v1.txt" }, + { + "data/test-abidiff-exit/test-anon-types-v0.o", + "data/test-abidiff-exit/test-anon-types-v1.o", + "", + "", + "", + "", + "", + "", + "", + "--no-default-suppression --harmless --non-reachable-types", + abigail::tools_utils::ABIDIFF_ABI_CHANGE + | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE, + "data/test-abidiff-exit/test-anon-types-report-1.txt", + "output/test-abidiff-exit/test-anon-types-report-1.txt" + }, #ifdef WITH_BTF { "data/test-abidiff-exit/btf/test0-v0.o",