From patchwork Tue Apr 2 09:45:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 87919 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 CB1023858287 for ; Tue, 2 Apr 2024 09:45:47 +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 537873858C5E for ; Tue, 2 Apr 2024 09:45:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 537873858C5E 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 537873858C5E 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=1712051140; cv=none; b=Sfi54b782SrCLjpijw9gymjiUhgUgZJsIHDBiGVk0Lj4WUNUJI1r5UrF2Tmn6/LzVJsSfUEtw95v2iFRJJ4AlBdkAlkfkaS5ws32/6GHKCtn9Y8VHpgqoHq4Sm2wRnvt/GPT+00TKaDFiMO2b0Z9ZJyIaye54Ny6rWo2ITnSNkA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712051140; c=relaxed/simple; bh=SSg5FCk4Oba7itBQ6hk+1kd6BpZszID2aNRBEg5aarU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=HKgMo0XElw2ZXQ3XsvnByGxdYErPhWIaT+HYY0KUsR1isaW+HUii4AXAmRACaPV5L4d9gHsYU4ymVOC5UBDksj3IkPv9h6MkCWX63gDyYpeC4cGsyBXICKIQuVT5RBqeXyfiZhfcVCNVYwU086OU4RTz/LS27rlQ4yyybjnVGV0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712051133; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=N0SOfFTDNUHLOhHVe8J51Vy4m6Pc+yVkg9463y6Doh4=; b=Tp985zoNc2JpkMQowRE1MRluO2G8nVOHupCh2I++doJJEjM4YfBbFvmrW0I3O874nPUEUk 6aAGHSFD04oS+IZIusV4hNxR8AsfLzU/rL7ccJV3pipv3FaEYIY9f96ZMgrCyfkvolYja5 zCx3Lqwip88TFsjXX3qkvaOGkbyLbkc= Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-625-sBHtJU2oNDyQksO6jKKAHg-1; Tue, 02 Apr 2024 05:45:29 -0400 X-MC-Unique: sBHtJU2oNDyQksO6jKKAHg-1 Received: by mail-qk1-f199.google.com with SMTP id af79cd13be357-78a33e4f134so609882585a.0 for ; Tue, 02 Apr 2024 02:45:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712051129; x=1712655929; 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=N0SOfFTDNUHLOhHVe8J51Vy4m6Pc+yVkg9463y6Doh4=; b=XIpjAuK3G/6NetvEElNlCyCHhl9kKciHlQSKELLMtns+rErhR+8tJXmMeiMrh4XHns 0bZHNxHHQhhDEla9bsuZ11dC1gzI68/l0A8eUG853OSaQPc8DydD6iPWoRbMR840/Ypn Vdxiaz0BYAz8oABfWqtAKcRx/PIFhtW3lbDqqE3xyDkyHuiWdn9AAqu9KnUds7jvwGvr 49Dy4+wVmaga1qdZwQ5ynRm2znGForz96bDBFuV0bte3Ofi1lNstW9alyit5Ah7Z72vs xIvYL14pvqX7j4xkl4INx9w0VO+oY8VnKoeKPoKOPi6cMT8VcQYx8UGk40yDSq/7gKMX wuTw== X-Gm-Message-State: AOJu0YxiZvXtctGcdDRmsAEWaEGeFIAeinhDJfN0+vTOvcyL4BMPaY3Z uNCO5GR9rX/X8Ec5FisMRVj4BU5nB9b5a+OGyAudNACcOsYYO8o4mtLAKr8k5Khhrs5gteiP0gh eaAjeMT6cg0y4QwmRZr8jW1YDSZ5BDeH3fDM/oOcNe1mk5NfQbdZqdxn8aGZCT/oER9gIWQdxSu LHtDo3HSmo4xjptKQipUzM1f6ZZ5rQnB8vicKtyg== X-Received: by 2002:a0c:e944:0:b0:696:2390:6eba with SMTP id n4-20020a0ce944000000b0069623906ebamr11992951qvo.60.1712051126931; Tue, 02 Apr 2024 02:45:26 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEQNDlhWGWfEC8xCI4r/i4scoOMA18rPIO0I9SBeKlyfmZm2hPG1LhBOF9fshGScJVg0pVYUQ== X-Received: by 2002:a0c:e944:0:b0:696:2390:6eba with SMTP id n4-20020a0ce944000000b0069623906ebamr11992872qvo.60.1712051123824; Tue, 02 Apr 2024 02:45:23 -0700 (PDT) Received: from localhost (88-120-130-27.subs.proxad.net. [88.120.130.27]) by smtp.gmail.com with ESMTPSA id ql2-20020a056214540200b00696b117a325sm5316392qvb.108.2024.04.02.02.45.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Apr 2024 02:45:22 -0700 (PDT) Received: by localhost (Postfix, from userid 1000) id 9F4D8C1B73C3; Tue, 2 Apr 2024 11:45:20 +0200 (CEST) From: Dodji Seketeli To: libabigail@sourceware.org Subject: [PATCH, applied] Bug 31513 - abidiff considers data members moved to base class as harmful Organization: Red Hat / France X-Operating-System: AlmaLinux 9.3 X-URL: http://www.redhat.com Date: Tue, 02 Apr 2024 11:45:20 +0200 Message-ID: <87r0fom72n.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=-7.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_LOTSOFHASH, KAM_STOCKGEN, LIKELY_SPAM_BODY, LOTS_OF_MONEY, MONEY_NOHTML, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SORBS_WEB, 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, Consider the 'struct type' below and its use in the file example-v0.cc: //----> example-v0.cc: <------ struct type { int m0; }; int use(type& t) { return t.m0; } //---->8<----- Now, consider a second version of that program where the data member of the 'struct type' is moved into a base class: //----> example-v1.cc: <------ struct base { int m0; }; struct type : public base { }; int use(type& t) { return t.m0; } //---->8<------ The first and second version of 'struct type' are ABI compatible because neither the size of 'struct type' nor the offset of the data member m0 has changed. But then look at what abidiff says: $ abidiff example-v0.o example-v1.o || echo "exit code: $?" 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 use(type&)' at example-v0.cc:7:1 has some indirect sub-type changes: parameter 1 of type 'type&' has sub-type changes: in referenced type 'struct type' at example-v1.cc:6:1: type size hasn't changed 1 base class insertion: struct base at example-v1.cc:1:1 1 data member deletion: 'int m0', at offset 0 (in bits) at example-v0.cc:3:1 exit code: 4 $ abidiff considers that the mere addition of a base class constitutes a potential ABI incompatibility. Also, abidiff fails to see that although the data member m0 was removed from 'struct type' itself, it was moved into its new base type. In practice, the data member m0 is still a member of 'struct type', by definition of class type inheritance. Thus, the exit code of abidiff is ABIDIFF_ABI_CHANGE which value is 4. This patch fixes this problem. First of all, here is what abidiff now says with this patch: $ abidiff example-v0.o example-v1.o && echo "return code: $?" Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function Variables changes summary: 0 Removed, 0 Changed, 0 Added variable return code: 0 $ In other words, abidiff now recognizes the changes as being ABI compatible and filters them out by default. Furthermore, here are the changes that abidiff sees when asked to avoid filtering these (now considered harmless) changes: $ abidiff --harmless example-v0.o example-v1.o && echo "return code: $?" 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 use(type&)' at example-v0.cc:7:1 has some indirect sub-type changes: parameter 1 of type 'type&' has sub-type changes: in referenced type 'struct type' at example-v1.cc:6:1: type size hasn't changed 1 base class insertion: struct base at example-v1.cc:1:1 $ We can see that abidiff no longer considers that the data member m0 was deleted. At its core, this patch teaches class_diff::ensure_lookup_tables_populated to detect data members being moved to base classes. That detection prevents the code base to consider those data members as being removed from the class. Now that the moved data members are not considered as removed, the patch goes further to consider data member moves to base classes that are not accompanied with any size or offset change as being harmless, and thus, to be filtered out by default. To that end, the patch teaches categorize_harmful_diff_node that an added base classes is not necessarily a harmful change if it is not accompanied with a size or offset change. Rather, an added base classes (or any change to a class) not accompanied with a size or offset change is now categorized into HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY. Note that the previous HARMLESS_UNION_CHANGE_CATEGORY was renamed into HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY. Incidentally, a removal of a base class or any change accompanied with an offset change is always categorized as harmful change. The patch also adds several non-regression tests. * include/abg-comparison.h (typedef string_decl_base_sptr_map): Move this typedef to include/abg-fwd.h: (HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY): Inside the enum diff_category, rename the enumerator HARMLESS_UNION_CHANGE_CATEGORY into this. (EVERYTHING_CATEGORY): Adjust this enum to refer to HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY, no more HARMLESS_UNION_CHANGE_CATEGORY * include/abg-fwd.h (typedef string_decl_base_sptr_map): Move this typedef here from abg-comparison.h (collect_non_anonymous_data_members): Declare new function. * src/abg-comp-filter.cc (has_offset_changes) (type_has_offset_changes, has_offset_changes) (has_subtype_changes, class_diff_has_only_harmless_changes): Define new static functions. (base_classes_removed): Rename base_classes_added_or_removed into this and update comment. (categorize_harmless_diff_node): Changes that were categorized as HARMLESS_UNION_CHANGE_CATEGORY is now categorized as HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY. Also, a diff that satisfies either union_diff_has_harmless_changes or class_diff_has_only_harmless_changes is categorized as HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY. (categorize_harmful_diff_node): Adjust to invoke base_classes_removed instead of base_classes_added_or_removed. An added base class doesn't necessarily qualifies as a harmful change anymore. Rather, a diff node that carries an offset change as detected by type_has_offset_changes is categorized as SIZE_OR_OFFSET_CHANGE_CATEGORY. * src/abg-comparison.cc (get_default_harmless_categories_bitmap): Adjust to use abigail::comparison::HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY rather than abigail::comparison::HARMLESS_UNION_CHANGE_CATEGORY. (operator<<(ostream& o, diff_category c)): Likewise. (class_diff::ensure_lookup_tables_populated): Detect data members that are moved into base classes to avoid considering those data members as being removed from the class. * src/abg-default-reporter.cc (default_reporter::report): Adjust to use HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY rather than HARMLESS_UNION_CHANGE_CATEGORY. * src/abg-ir.cc (collect_non_anonymous_data_members): Define function overloads. * tests/data/test-abidiff-exit/PR31513/non-regr/libtest[1-4]-v{0,1}.so: New binary test input files. * tests/data/test-abidiff-exit/PR31513/non-regr/report[1-4.txt: New reference output files. * tests/data/test-abidiff-exit/PR31513/non-regr/test[1-4]-v{0,1}.cc: Source code of the binary input files above. * tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-{1,2}.txt: New reference output files. * tests/data/test-abidiff-exit/PR31513/reported/libloremipsum_gcc{7,11}.so: New binary test input files. * tests/data/test-abidiff-exit/PR31513/reported/libstdcpp.suppr: New test suppression file. * tests/data/Makefile.am: Add new test files above to source distribution. * tests/test-abidiff-exit.cc (in_out_specs): Add the new input test files to this test harness. * tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Adjust. * tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt: Adjust. Signed-off-by: Dodji Seketeli Applied to the master branch. --- include/abg-comparison.h | 10 +- include/abg-fwd.h | 10 + src/abg-comp-filter.cc | 255 +++++++++++++++++- src/abg-comparison.cc | 46 +++- src/abg-default-reporter.cc | 2 +- src/abg-ir.cc | 68 +++++ tests/data/Makefile.am | 26 ++ .../PR31513/non-regr/libtest1-v0.so | Bin 0 -> 16768 bytes .../PR31513/non-regr/libtest1-v1.so | Bin 0 -> 16800 bytes .../PR31513/non-regr/libtest2-v0.so | Bin 0 -> 16768 bytes .../PR31513/non-regr/libtest2-v1.so | Bin 0 -> 16816 bytes .../PR31513/non-regr/libtest3-v0.so | Bin 0 -> 16768 bytes .../PR31513/non-regr/libtest3-v1.so | Bin 0 -> 16824 bytes .../PR31513/non-regr/libtest4-v0.so | Bin 0 -> 16768 bytes .../PR31513/non-regr/libtest4-v1.so | Bin 0 -> 16824 bytes .../PR31513/non-regr/report1.txt | 12 + .../PR31513/non-regr/report2.txt | 12 + .../PR31513/non-regr/report3.txt | 12 + .../PR31513/non-regr/report4.txt | 16 ++ .../PR31513/non-regr/test1-v0.cc | 13 + .../PR31513/non-regr/test1-v1.cc | 16 ++ .../PR31513/non-regr/test2-v0.cc | 13 + .../PR31513/non-regr/test2-v1.cc | 17 ++ .../PR31513/non-regr/test3-v0.cc | 13 + .../PR31513/non-regr/test3-v1.cc | 17 ++ .../PR31513/non-regr/test4-v0.cc | 13 + .../PR31513/non-regr/test4-v1.cc | 17 ++ .../reported/PR31513-reported-report-1.txt | 58 ++++ .../reported/PR31513-reported-report-2.txt | 5 + .../PR31513/reported/libloremipsum_gcc11.so | Bin 0 -> 115160 bytes .../PR31513/reported/libloremipsum_gcc7.so | Bin 0 -> 103808 bytes .../PR31513/reported/libstdcpp.suppr | 19 ++ ...bb-4.3-3.20141204.fc23.x86_64-report-0.txt | 73 +---- ...bb-4.3-3.20141204.fc23.x86_64-report-1.txt | 47 +--- tests/test-abidiff-exit.cc | 90 +++++++ 35 files changed, 743 insertions(+), 137 deletions(-) create mode 100755 tests/data/test-abidiff-exit/PR31513/non-regr/libtest1-v0.so create mode 100755 tests/data/test-abidiff-exit/PR31513/non-regr/libtest1-v1.so create mode 100755 tests/data/test-abidiff-exit/PR31513/non-regr/libtest2-v0.so create mode 100755 tests/data/test-abidiff-exit/PR31513/non-regr/libtest2-v1.so create mode 100755 tests/data/test-abidiff-exit/PR31513/non-regr/libtest3-v0.so create mode 100755 tests/data/test-abidiff-exit/PR31513/non-regr/libtest3-v1.so create mode 100755 tests/data/test-abidiff-exit/PR31513/non-regr/libtest4-v0.so create mode 100755 tests/data/test-abidiff-exit/PR31513/non-regr/libtest4-v1.so create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/report1.txt create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/report2.txt create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/report3.txt create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/report4.txt create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/test1-v0.cc create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/test1-v1.cc create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/test2-v0.cc create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/test2-v1.cc create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/test3-v0.cc create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/test3-v1.cc create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/test4-v0.cc create mode 100644 tests/data/test-abidiff-exit/PR31513/non-regr/test4-v1.cc create mode 100644 tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-1.txt create mode 100644 tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-2.txt create mode 100644 tests/data/test-abidiff-exit/PR31513/reported/libloremipsum_gcc11.so create mode 100644 tests/data/test-abidiff-exit/PR31513/reported/libloremipsum_gcc7.so create mode 100644 tests/data/test-abidiff-exit/PR31513/reported/libstdcpp.suppr new file mode 100755 index 0000000000000000000000000000000000000000..a33440914ff0a6b9ac7dd081cb1c0eada0b41722 GIT binary patch literal 16800 zcmeHOYiJzT6~435TI;U$uob6%r5YI->^M8pO12}%$d)WiTBVjBvfVl%$YkoceMAuICgM6qG^I#lh`YkB_W2%pzmf6)D4O_95;(@ z>D#<)`UIDXDiu@Fp=9hsnn-3n)5j`zy5M1X#S)J$t}E5LRop&YIZ-Ahvu zB_AQmI1~|ggK#$p$MhEE$uy?I$Q&`x%M>q2`^b-J5O;%cLE1w&rq~CzWAFL)!}NEA zaKSpVyh()@Ou4_KfWx{xXyeN~P5m{x4#RZbOsTxGo;q}fV`k#e2^e?U70iY05t2bA z8`>U$PZNC5|BZL|z5eWXt{pz}@}*;c`rD=-p4qu@6dkcUjEQm7`NVW!Wkda6>=%+G z)+OVh-CW0l=d0JzV?XuuPc+b<0R0-VO5C9Wt_4{()65p#l3DgG&o@nBP9C2!ZO3!6 z`LgeL$EQXMZpk@rr3;R-)wh_LdCQ#1m#jkmEI2+pFyp$@JN$)NM-=kuvTtX$Z#T-W zu?xjwmCI%_W*Ma<>N83|ad2|~sM&Ay8#^&WxFYn267m;-@;I2=kY9;D-$o-ez90EM zxJ8cF=ze4U&q;qhplA8oJ{1qICDxkT^%^}5F=@I{qsOtrZK+1jV_w>Zl}8JZ+W1Nv z9>WTR6$mR3Rv@fESb?wtVFkhp{BKv_pY5Ofck2A#W2uYL-}DNR`sNisQn{Ww|LfS> zGV#jJ--5cb<#%vw?-~XUR%vg=E{^)P-BAtN+-Sx_Y}QrM;8-<6Zv|2rxzgVwI(t_O1iVc+B_Q&=i=( z-1ZZx^FtA2Qy1RzS3&5z@EUdV8A$7<4TpE4TfnHDg1)Q$BmVs}U_1es)P=9!PF)Oswf!+c798hfd8!9&K?6lD4JG70fT4I;rhp!&cA#Uk|N<{}M+B(MD z);--GKNCAA_HEen_&|^RSrmQX^<6ANO!?d8NL$BCk*1;CGzZ#^F#W9w+F)$`##cwKZopEklXeOMpP zb>pYx%(*^Bed2mVqV+Xe}35(?2`X#3VflsH6kqUB|BL-T{X61#TjiL9QOac5=< zu4O0OSwHWV%0r2Q3HO>=6ltp*SaF}pS)S<4xkabfcI_|cd$W1J7uMHX>3r787kX#% z^G>;U*7KdRU+z6JJ&@d)9O#9G{hm`UL-2$&2s|ber;|n|1663yuqw^s!%EPM-}4dp z_UHSH?d_zWrE$#q&7|k&59gGAj?RO>1smWZdFx z!SNm2=&SF6yHWC{<$2bE>6CnLLCkno(J}40VsQZ=HIfOQ{yna>Lmv`!N;alvn&Z^{RhV|Z0%N>;o8kGpSm}v&NiO6RZ-q@OfQ}Z?qqf5j5RoQH%ih5zIZgf4LzJtuzts zAy38y`~N)HajwmHo{uxVM0lJ=!&gOhe$VsdW1z#X7|-*2raYeq7uhgIZTk`kIJagz z&!?I4dkW{zeoS$qgmd+(OpZKn*Qv8${-hT8{6Prg`TcHxqf{9Unl&2^5gdn zrtF7!oErx57eR+L;rF5HbA+BJ{N4pFvT+_PzXVJzUMF0YvLjJ`Ofg*y;D^b;^bZa2 ztbQ$k=jS6+oNv^&VE*3&Bj(Tb7dm+p<@ZX`%4@|u(x1Sm7O(556@sa)#Ojgj&x&6F z1G50WU8?gC-oG03XPN0$z~bDAZnx^Z=UM`k(AZB&%QEZLd}A5U^N#EH!E-#Em*Cjp z{&~K^`@^Wp3NE?}{KjOYE8*Lpz-O_#^z1Lw{3CYWmR{CI}1=QJ5sXsCP z)`C6YB0Wzg6(E>b(6^@n{uRRinEGWB#P>D8C;JuR5(9|_@p~KKuM+;~eeh2cK6svM z1{Cnc26)cnL<9UH;Sb#hk8!Hs9W}m7gg;3}9c=hNA|6lty^R0&;jss7wGHl4?AJI^ VvIInU)2WYt^GOA80)T)h{sS|k_}Tyf literal 0 HcmV?d00001 new file mode 100755 index 0000000000000000000000000000000000000000..3b6817902e01554bbed4c88426d949375a627d11 GIT binary patch literal 16816 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 S;Z3J8{_0aczzzTcqWBNJCif5k literal 0 HcmV?d00001 new file mode 100755 index 0000000000000000000000000000000000000000..842368a9c5f4f8e9d5da5d48fd78c2b6f17bfbe4 GIT binary patch literal 16824 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 bRP2|yqh#@kq6_r(@b5gO0Jaa{6UBc3RP_K% literal 0 HcmV?d00001 new file mode 100755 index 0000000000000000000000000000000000000000..52172876278c56e15baeb31f573601255e8885ee GIT binary patch literal 16824 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 class_diff_sptr; /// associated to the first one. typedef unordered_map pointer_map; -/// Convenience typedef for a map which key is a string and which -/// value is a @ref decl_base_sptr. -typedef unordered_map string_decl_base_sptr_map; - /// Convenience typedef for a map which key is a string and which /// value is a @ref type_base_sptr. typedef unordered_map string_type_base_sptr_map; @@ -357,8 +353,8 @@ enum diff_category HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY = 1 << 6, /// This means that a diff node in the sub-tree carries a harmless - /// union change. - HARMLESS_UNION_CHANGE_CATEGORY = 1 << 7, + /// union or class change. + HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY = 1 << 7, /// This means that a diff node in the sub-tree carries a harmless /// data member change. An example of harmless data member change @@ -455,7 +451,7 @@ enum diff_category | STATIC_DATA_MEMBER_CHANGE_CATEGORY | HARMLESS_ENUM_CHANGE_CATEGORY | HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY - | HARMLESS_UNION_CHANGE_CATEGORY + | HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY | HARMLESS_DATA_MEMBER_CHANGE_CATEGORY | SUPPRESSED_CATEGORY | PRIVATE_TYPE_CATEGORY diff --git a/include/abg-fwd.h b/include/abg-fwd.h index a730b181..fe18740f 100644 --- a/include/abg-fwd.h +++ b/include/abg-fwd.h @@ -153,6 +153,10 @@ class decl_base; // Convenience typedef for a smart pointer on @ref decl_base. typedef shared_ptr decl_base_sptr; +/// Convenience typedef for a map which key is a string and which +/// value is a @ref decl_base_sptr. +typedef unordered_map string_decl_base_sptr_map; + class type_decl; /// Convenience typedef for a shared pointer on a @ref type_decl. typedef shared_ptr type_decl_sptr; @@ -767,6 +771,12 @@ get_last_data_member(const class_or_union*); var_decl_sptr get_last_data_member(const class_or_union_sptr&); +bool +collect_non_anonymous_data_members(const class_or_union* cou, string_decl_base_sptr_map& dms); + +bool +collect_non_anonymous_data_members(const class_or_union_sptr &cou, string_decl_base_sptr_map& dms); + bool is_anonymous_data_member(const decl_base&); diff --git a/src/abg-comp-filter.cc b/src/abg-comp-filter.cc index 63716775..caea9d0c 100644 --- a/src/abg-comp-filter.cc +++ b/src/abg-comp-filter.cc @@ -28,6 +28,10 @@ namespace comparison namespace filtering { +static bool +has_offset_changes(const string_decl_base_sptr_map& f_data_members, + const string_decl_base_sptr_map& s_data_members); + using std::dynamic_pointer_cast; /// Walk the diff sub-trees of a a @ref corpus_diff and apply a filter @@ -158,6 +162,55 @@ type_size_changed(const type_base_sptr f, const type_base_sptr s) return f->get_size_in_bits() != s->get_size_in_bits(); } +/// Detect if a type has offset changes. +/// +/// The type must be either a class or a union. This function returns +/// true iff the type has a data member which has an offset change. +/// +/// @param f the first version of the type to consider. +/// +/// @param s the second version of the type to consider. +/// +/// @return true iff the type has a data member which has an offset +/// change. +static bool +type_has_offset_changes(const type_base_sptr f, const type_base_sptr s) +{ + if (!f || !s) + return false; + + class_or_union_sptr first = is_class_or_union_type(f); + class_or_union_sptr second = is_class_or_union_type(s); + if (!first || !second) + return false; + + // collect the data members + string_decl_base_sptr_map f_data_members, s_data_members; + collect_non_anonymous_data_members(first, f_data_members); + collect_non_anonymous_data_members(second, s_data_members); + + // detect offset changes + if (has_offset_changes(f_data_members, s_data_members)) + return true; + + return false; +} + +/// Detect if a type has offset changes. +/// +/// The type must be either a class or a union. This function returns +/// true iff the type has a data member which has an offset change. +/// +/// @param f the first version of the type to consider. +/// +/// @param s the second version of the type to consider. +/// +/// @return true iff the type has a data member which has an offset +/// change. +static bool +type_has_offset_changes(const decl_base_sptr f, const decl_base_sptr s) +{return type_has_offset_changes(is_type(f), is_type(s));} + /// Tests if the size of a given type changed. /// /// @param f the declaration of the first version of the type to @@ -193,6 +246,184 @@ has_type_size_change(const diff* diff) return type_size_changed(f, s); } + +/// Find a data member that is at a given offset. +/// +/// @param data_members the set of data member to consider. +/// +/// @param the offset to consider. +/// +/// @return the data member found at offset @p offset of nil if none +/// was found with that offset; +static var_decl_sptr +find_data_member_at_offset(const string_decl_base_sptr_map& data_members, + unsigned offset) +{ + for (auto e : data_members) + { + var_decl_sptr dm = is_var_decl(e.second); + ABG_ASSERT(dm); + unsigned off = get_absolute_data_member_offset(dm); + if (offset == off) + return dm; + } + return var_decl_sptr(); +} + +/// Test if a set of data members contains at least one data member +/// that has an offset change. +/// +/// @param f_data_members the first version of data members to +/// consider. +/// +/// @param s_data_members the second version of data members to +/// consider. +/// +/// @return true iff there is at least one data member which has an +/// offset change between the first version of data members and the +/// second version. +static bool +has_offset_changes(const string_decl_base_sptr_map& f_data_members, + const string_decl_base_sptr_map& s_data_members) +{ + // Compare the offsets of the data members + for (auto entry : f_data_members) + { + var_decl_sptr f_member = is_var_decl(entry.second); + ABG_ASSERT(f_member); + unsigned f_offset = get_absolute_data_member_offset(f_member); + auto i = s_data_members.find(entry.first); + var_decl_sptr s_member; + if (i == s_data_members.end()) + { + s_member = find_data_member_at_offset(s_data_members, f_offset); + if (!s_member) + // A data member was suppressed; that's bad; let's consider + // that as an offset change. + return true; + } + + if (!s_member) + s_member = is_var_decl(i->second); + ABG_ASSERT(s_member); + unsigned s_offset = get_absolute_data_member_offset(s_member); + if (f_offset != s_offset) + return true; + } + return false; +} + +/// Test if a set of data members contains at least one data member +/// that has a sub-type change. +/// +/// @param f_data_members the first version of data members to +/// consider. +/// +/// @param s_data_members the second version of data members to +/// consider. +/// +/// @return true iff there is at least one data member which has a +/// sub-type change between the first version of data members and the +/// second version. +static bool +has_subtype_changes(const string_decl_base_sptr_map& f_data_members, + const string_decl_base_sptr_map& s_data_members, + diff_context_sptr ctxt) +{ + // Now compare the offsets of the data members collected. + var_decl_sptr s_member; + for (auto entry : f_data_members) + { + var_decl_sptr f_member = is_var_decl(entry.second); + ABG_ASSERT(f_member); + + auto i = s_data_members.find(entry.first); + if (i == s_data_members.end()) + { + unsigned offset = get_data_member_offset(f_member); + s_member = find_data_member_at_offset(s_data_members, offset); + if (!s_member) + // A data member was suppressed; that's bad; let's consider + // that as a sub-type change. + return true; + } + + if (!s_member) + s_member = is_var_decl(i->second); + ABG_ASSERT(s_member); + diff_sptr d =compute_diff(f_member->get_type(), s_member->get_type(), ctxt); + if (d->has_changes()) + return true; + } + return false; +} + +/// Test if the changes of a @ref class_diff are harmless. +/// +/// Potentially harmful changes are basically: +/// 1/ name change (that changes the type altogether) +/// 2/ size change +/// 3/ offset change of any data member +/// 4/ any subtype change. +/// +/// Thus, this function tests that the class_diff carries none of the +/// 4 kinds of changes above. +/// +/// @param d the @ref class_diff to consider. +/// +/// @return true iff @p d has only harmless changes. +static bool +class_diff_has_only_harmless_changes(const class_diff* d) +{ + if (!d || !d->has_changes()) + return true; + + class_decl_sptr f = d->first_class_decl(), s = d->second_class_decl(); + + if (f->get_qualified_name() != s->get_qualified_name()) + return false; + + if (f->get_size_in_bits() != s->get_size_in_bits()) + return false; + + // collect the data members + string_decl_base_sptr_map f_data_members, s_data_members; + collect_non_anonymous_data_members(f, f_data_members); + collect_non_anonymous_data_members(s, s_data_members); + + // detect offset changes + if (has_offset_changes(f_data_members, s_data_members)) + return false; + + // detect subtype changes + if (has_subtype_changes(f_data_members, s_data_members, d->context())) + return false; + + return true; +} + +/// Test if the changes of a @ref class_diff are harmless. +/// +/// Potentially harmful changes are basically: +/// 1/ name change (that changes the type altogether) +/// 2/ size change +/// 3/ offset change of any data member +/// 4/ any subtype change. +/// +/// Thus, this function tests that the class_diff carries none of the +/// 4 kinds of changes above. +/// +/// @param d the @ref class_diff to consider. +/// +/// @return true iff @p d has only harmless changes. +static bool +class_diff_has_only_harmless_changes(diff* d) +{ + if (const class_diff* class_dif = is_class_diff(d)) + return class_diff_has_only_harmless_changes(class_dif); + return false; +} + /// Tests if the access specifiers for a member declaration changed. /// /// @param f the declaration for the first version of the member @@ -1025,27 +1256,27 @@ static bool has_non_virtual_mem_fn_change(const diff* diff) {return has_non_virtual_mem_fn_change(dynamic_cast(diff));} -/// Test if a class_diff carries base classes adding or removals. +/// Test if a class_diff carries a base class removal. /// /// @param diff the class_diff to consider. /// -/// @return true iff @p diff carries base classes adding or removals. +/// @return true iff @p diff carries a base classe removal. static bool -base_classes_added_or_removed(const class_diff* diff) +base_classes_removed(const class_diff* diff) { if (!diff) return false; - return diff->deleted_bases().size() || diff->inserted_bases().size(); + return diff->deleted_bases().size(); } -/// Test if a class_diff carries base classes adding or removals. +/// Test if a class_diff carries a base classes removal. /// /// @param diff the class_diff to consider. /// -/// @return true iff @p diff carries base classes adding or removals. +/// @return true iff @p diff carries a base class removal. static bool -base_classes_added_or_removed(const diff* diff) -{return base_classes_added_or_removed(dynamic_cast(diff));} +base_classes_removed(const diff* diff) +{return base_classes_removed(dynamic_cast(diff));} /// Test if two classes that are decl-only (have the decl-only flag /// and carry no data members) but are different just by their size. @@ -1827,8 +2058,9 @@ categorize_harmless_diff_node(diff *d, bool pre) || class_diff_has_harmless_odr_violation_change(d)) category |= HARMLESS_DECL_NAME_CHANGE_CATEGORY; - if (union_diff_has_harmless_changes(d)) - category |= HARMLESS_UNION_CHANGE_CATEGORY; + if (union_diff_has_harmless_changes(d) + || class_diff_has_only_harmless_changes(d)) + category |= HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY; if (has_non_virtual_mem_fn_change(d)) category |= NON_VIRT_MEM_FUN_CHANGE_CATEGORY; @@ -1907,10 +2139,11 @@ categorize_harmful_diff_node(diff *d, bool pre) if (!has_class_decl_only_def_change(d) && !has_enum_decl_only_def_change(d) && (type_size_changed(f, s) + || type_has_offset_changes(f, s) || data_member_offset_changed(f, s) || non_static_data_member_type_size_changed(f, s) || non_static_data_member_added_or_removed(d) - || base_classes_added_or_removed(d) + || base_classes_removed(d) || has_harmful_enum_change(d) || crc_changed(d) || namespace_changed(d))) diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc index 8f4aa5fc..3dc3d28d 100644 --- a/src/abg-comparison.cc +++ b/src/abg-comparison.cc @@ -3144,7 +3144,7 @@ get_default_harmless_categories_bitmap() | abigail::comparison::STATIC_DATA_MEMBER_CHANGE_CATEGORY | abigail::comparison::HARMLESS_ENUM_CHANGE_CATEGORY | abigail::comparison::HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY - | abigail::comparison::HARMLESS_UNION_CHANGE_CATEGORY + | abigail::comparison::HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY | abigail::comparison::HARMLESS_DATA_MEMBER_CHANGE_CATEGORY | abigail::comparison::TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY | abigail::comparison::FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY @@ -3250,11 +3250,11 @@ operator<<(ostream& o, diff_category c) emitted_a_category |= true; } - if (c & HARMLESS_UNION_CHANGE_CATEGORY) + if (c & HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY) { if (emitted_a_category) o << "|"; - o << "HARMLESS_UNION_CHANGE_CATEGORY"; + o << "HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY"; emitted_a_category |= true; } @@ -5844,6 +5844,46 @@ class_diff::ensure_lookup_tables_populated(void) const get_priv()->inserted_bases_[name] = b; } } + + // =============================================================== + // Detect when a data member is deleted from the class but is now + // present in one of the bases at the same offset. In that case, + // the data member should not be considered as removed. + // =============================================================== + string_decl_base_sptr_map& deleted_data_members = + class_or_union_diff::priv_->deleted_data_members_; + + vector deleted_data_members_present_in_bases; + for (auto entry : deleted_data_members) + { + var_decl_sptr deleted_member = is_var_decl(entry.second); + ABG_ASSERT(deleted_member); + for (class_decl::base_spec_sptr base : second_class_decl()->get_base_specifiers()) + { + class_decl_sptr klass = base->get_base_class(); + var_decl_sptr member = klass->find_data_member(deleted_member->get_name()); + if (member) + deleted_data_members_present_in_bases.push_back(member); + } + } + // Walk the deleted data members that are now in one of the bases, + // of the new type, at the same offset, and let's see if they have + // sub-type changes. In any cases, these should not be considered + // as being deleted. + for (var_decl_sptr m : deleted_data_members_present_in_bases) + { + string name = m->get_name(); + auto it = deleted_data_members.find(name); + ABG_ASSERT(it != deleted_data_members.end()); + var_decl_sptr deleted_member = is_var_decl(it->second); + if (*deleted_member != *m) + { + var_diff_sptr dif = compute_diff(deleted_member, m, context()); + ABG_ASSERT(dif); + class_or_union_diff::priv_->subtype_changed_dm_[name]= dif; + } + deleted_data_members.erase(name); + } } sort_string_base_sptr_map(get_priv()->deleted_bases_, diff --git a/src/abg-default-reporter.cc b/src/abg-default-reporter.cc index 426b27b4..3721d383 100644 --- a/src/abg-default-reporter.cc +++ b/src/abg-default-reporter.cc @@ -1534,7 +1534,7 @@ default_reporter::report(const union_diff& d, ostream& out, d.class_or_union_diff::report(out, indent); - if (d.context()->get_allowed_category() & HARMLESS_UNION_CHANGE_CATEGORY + if (d.context()->get_allowed_category() & HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY && filtering::union_diff_has_harmless_changes(&d)) { // The user wants to see harmless changes and the union diff we diff --git a/src/abg-ir.cc b/src/abg-ir.cc index 0c4e8aa6..f91d67a2 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -6036,6 +6036,74 @@ var_decl_sptr get_last_data_member(const class_or_union_sptr &klass) {return get_last_data_member(klass.get());} +/// Collect all the non-anonymous data members of a class or union type. +/// +/// If the class contains any anonymous data member, this function +/// looks through it to collect the non-anonymous data members that it +/// contains. The function also also looks through the base classes +/// of the current type. +/// +/// @param cou the class or union type to consider. +/// +/// @param dms output parameter. This is populated by the function +/// with a map containing the non-anonymous data members that were +/// collected. The key of the map is the name of the data member. +/// This is set iff the function returns true. +/// +/// @return true iff at least one non-anonymous data member was +/// collected. +bool +collect_non_anonymous_data_members(const class_or_union* cou, + string_decl_base_sptr_map& dms) +{ + if (!cou) + return false; + + bool result = false; + class_decl* klass = is_class_type(cou); + if (klass) + // First look into base classes for data members. + for (class_decl::base_spec_sptr base : klass->get_base_specifiers()) + result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms); + + // Then look into our data members + for (var_decl_sptr member : cou->get_non_static_data_members()) + { + if (is_anonymous_data_member(member)) + { + class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member); + ABG_ASSERT(cl); + result |= collect_non_anonymous_data_members(cl.get(), dms); + } + else + { + dms[member->get_name()] = member; + result = true; + } + } + return true; +} + +/// Collect all the non-anonymous data members of a class or union type. +/// +/// If the class contains any anonymous data member, this function +/// looks through it to collect the non-anonymous data members that it +/// contains. The function also also looks through the base classes +/// of the current type. +/// +/// @param cou the class or union type to consider. +/// +/// @param dms output parameter. This is populated by the function +/// with a map containing the non-anonymous data members that were +/// collected. The key of the map is the name of the data member. +/// This is set iff the function returns true. +/// +/// @return true iff at least one non-anonymous data member was +/// collected. +bool +collect_non_anonymous_data_members(const class_or_union_sptr &cou, string_decl_base_sptr_map& dms) +{return collect_non_anonymous_data_members(cou.get(), dms);} + /// Test if a decl is an anonymous data member. /// /// @param d the decl to consider. diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index b5a9335f..5be64c4c 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -419,6 +419,32 @@ test-abidiff-exit/PR31377/flex/lib64/librte_pipeline.so.24.1 \ test-abidiff-exit/PR31377/reference/include/rte_pipeline.h \ test-abidiff-exit/PR31377/reference/lib64/librte_pipeline.so.24.0 \ test-abidiff-exit/PR31377/test-PR31377-report-1.txt \ +test-abidiff-exit/PR31513/reported/PR31513-reported-report-1.txt \ +test-abidiff-exit/PR31513/reported/PR31513-reported-report-2.txt \ +test-abidiff-exit/PR31513/reported/libloremipsum_gcc11.so \ +test-abidiff-exit/PR31513/reported/libloremipsum_gcc7.so \ +test-abidiff-exit/PR31513/reported/libstdcpp.suppr \ +test-abidiff-exit/PR31513/non-regr/libtest1-v0.so \ +test-abidiff-exit/PR31513/non-regr/libtest1-v1.so \ +test-abidiff-exit/PR31513/non-regr/libtest2-v0.so \ +test-abidiff-exit/PR31513/non-regr/libtest2-v1.so \ +test-abidiff-exit/PR31513/non-regr/libtest3-v0.so \ +test-abidiff-exit/PR31513/non-regr/libtest3-v1.so \ +test-abidiff-exit/PR31513/non-regr/libtest4-v0.so \ +test-abidiff-exit/PR31513/non-regr/libtest4-v1.so \ +test-abidiff-exit/PR31513/non-regr/report1.txt \ +test-abidiff-exit/PR31513/non-regr/report2.txt \ +test-abidiff-exit/PR31513/non-regr/report3.txt \ +test-abidiff-exit/PR31513/non-regr/report4.txt \ +test-abidiff-exit/PR31513/non-regr/test1-v0.cc \ +test-abidiff-exit/PR31513/non-regr/test1-v1.cc \ +test-abidiff-exit/PR31513/non-regr/test2-v0.cc \ +test-abidiff-exit/PR31513/non-regr/test2-v1.cc \ +test-abidiff-exit/PR31513/non-regr/test3-v0.cc \ +test-abidiff-exit/PR31513/non-regr/test3-v1.cc \ +test-abidiff-exit/PR31513/non-regr/test4-v0.cc \ +test-abidiff-exit/PR31513/non-regr/test4-v1.cc \ +\ test-diff-dwarf/test0-v0.cc \ test-diff-dwarf/test0-v0.o \ test-diff-dwarf/test0-v1.cc \ diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/libtest1-v0.so b/tests/data/test-abidiff-exit/PR31513/non-regr/libtest1-v0.so new file mode 100755 index 0000000000000000000000000000000000000000..e4ba91f64b3d274a162b12f700c280dcffc767db GIT binary patch literal 16768 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 literal 0 HcmV?d00001 diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/libtest2-v1.so b/tests/data/test-abidiff-exit/PR31513/non-regr/libtest2-v1.so diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/libtest3-v0.so b/tests/data/test-abidiff-exit/PR31513/non-regr/libtest3-v0.so new file mode 100755 index 0000000000000000000000000000000000000000..2a0f5d630d125dd271c8086a7ed7bcf0d57aa2e8 GIT binary patch literal 16768 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 literal 0 HcmV?d00001 diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/libtest4-v1.so b/tests/data/test-abidiff-exit/PR31513/non-regr/libtest4-v1.so diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/report1.txt b/tests/data/test-abidiff-exit/PR31513/non-regr/report1.txt new file mode 100644 index 00000000..dff216f8 --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/report1.txt @@ -0,0 +1,12 @@ +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(type&)' at test1-v0.cc:10:1 has some indirect sub-type changes: + parameter 1 of type 'type&' has sub-type changes: + in referenced type 'struct type' at test1-v1.cc:8:1: + type size hasn't changed + 1 base class insertion: + struct base at test1-v1.cc:2:1 + diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/report2.txt b/tests/data/test-abidiff-exit/PR31513/non-regr/report2.txt new file mode 100644 index 00000000..25d39e9b --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/report2.txt @@ -0,0 +1,12 @@ +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(type&)' at test2-v0.cc:10:1 has some indirect sub-type changes: + parameter 1 of type 'type&' has sub-type changes: + in referenced type 'struct type' at test2-v1.cc:9:1: + type size hasn't changed + 1 base class insertion: + struct base at test2-v1.cc:2:1 + diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/report3.txt b/tests/data/test-abidiff-exit/PR31513/non-regr/report3.txt new file mode 100644 index 00000000..5883066e --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/report3.txt @@ -0,0 +1,12 @@ +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(type&)' at test3-v0.cc:10:1 has some indirect sub-type changes: + parameter 1 of type 'type&' has sub-type changes: + in referenced type 'struct type' at test3-v1.cc:9:1: + type size changed from 64 to 96 (in bits) + 1 base class insertion: + struct base at test3-v1.cc:2:1 + diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/report4.txt b/tests/data/test-abidiff-exit/PR31513/non-regr/report4.txt new file mode 100644 index 00000000..9a78f7b7 --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/report4.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(type&)' at test4-v0.cc:10:1 has some indirect sub-type changes: + parameter 1 of type 'type&' has sub-type changes: + in referenced type 'struct type' at test4-v1.cc:8:1: + type size changed from 64 to 96 (in bits) + 1 base class insertion: + struct base at test4-v1.cc:2:1 + 1 data member deletion: + 'char m1', at offset 32 (in bits) at test4-v0.cc:6:1 + 1 data member insertion: + 'char m3', at offset 64 (in bits) at test4-v1.cc:10:1 + diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/test1-v0.cc b/tests/data/test-abidiff-exit/PR31513/non-regr/test1-v0.cc new file mode 100644 index 00000000..d9f72e95 --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/test1-v0.cc @@ -0,0 +1,13 @@ +// g++ -shared -g -o libtest1-v0.so test1-v0.cc + +struct type +{ + int m0; + char m1; +}; + +int +foo(type& t) +{ + return t.m1; +} diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/test1-v1.cc b/tests/data/test-abidiff-exit/PR31513/non-regr/test1-v1.cc new file mode 100644 index 00000000..dc015335 --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/test1-v1.cc @@ -0,0 +1,16 @@ +// g++ -shared -g -o libtest1-v1.so test1-v1.cc +struct base +{ + int m0; + char m1; +}; + +struct type : public base +{ +}; + +int +foo(type& t) +{ + return t.m1; +} diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/test2-v0.cc b/tests/data/test-abidiff-exit/PR31513/non-regr/test2-v0.cc new file mode 100644 index 00000000..fd03cfb3 --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/test2-v0.cc @@ -0,0 +1,13 @@ +// g++ -shared -g -o libtest2-v0.so test2-v0.cc + +struct type +{ + int m0; + char m1; +}; + +int +foo(type& t) +{ + return t.m1; +} diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/test2-v1.cc b/tests/data/test-abidiff-exit/PR31513/non-regr/test2-v1.cc new file mode 100644 index 00000000..4b72f89f --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/test2-v1.cc @@ -0,0 +1,17 @@ +// g++ -shared -g -o libtest2-v1.so test2-v1.cc +struct base +{ + int m0; + char m1; + char m2; +}; + +struct type : public base +{ +}; + +int +foo(type& t) +{ + return t.m1; +} diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/test3-v0.cc b/tests/data/test-abidiff-exit/PR31513/non-regr/test3-v0.cc new file mode 100644 index 00000000..47806cc4 --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/test3-v0.cc @@ -0,0 +1,13 @@ +// g++ -shared -g -o libtest3-v0.so test3-v0.cc + +struct type +{ + int m0; + char m1; +}; + +int +foo(type& t) +{ + return t.m1; +} diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/test3-v1.cc b/tests/data/test-abidiff-exit/PR31513/non-regr/test3-v1.cc new file mode 100644 index 00000000..0be4717a --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/test3-v1.cc @@ -0,0 +1,17 @@ +// g++ -shared -g -o libtest3-v1.so test3-v1.cc +struct base +{ + int m0; + char m1; + float m2; +}; + +struct type : public base +{ +}; + +int +foo(type& t) +{ + return t.m1; +} diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/test4-v0.cc b/tests/data/test-abidiff-exit/PR31513/non-regr/test4-v0.cc new file mode 100644 index 00000000..47d44d7d --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/test4-v0.cc @@ -0,0 +1,13 @@ +// g++ -shared -g -o libtest4-v0.so test4-v0.cc + +struct type +{ + int m0; + char m1; +}; + +int +foo(type& t) +{ + return t.m1; +} diff --git a/tests/data/test-abidiff-exit/PR31513/non-regr/test4-v1.cc b/tests/data/test-abidiff-exit/PR31513/non-regr/test4-v1.cc new file mode 100644 index 00000000..71d2b8c3 --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/non-regr/test4-v1.cc @@ -0,0 +1,17 @@ +// g++ -shared -g -o libtest4-v1.so test4-v1.cc +struct base +{ + int m0; + float m2; +}; + +struct type : public base +{ + char m3; +}; + +int +foo(type& t) +{ + return t.m0; +} diff --git a/tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-1.txt b/tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-1.txt new file mode 100644 index 00000000..f86917bb --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-1.txt @@ -0,0 +1,58 @@ +Functions changes summary: 16 Removed, 0 Changed (20 filtered out), 21 Added functions +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable +Function symbols changes summary: 2 Removed, 2 Added function symbols not referenced by debug info +Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referenced by debug info + +16 Removed functions: + + [D] 'method void __gnu_cxx::new_allocator::destroy(char*)' {_ZN9__gnu_cxx13new_allocatorIcE7destroyIcEEvPT_} + [D] 'method char* std::__copy_move::__copy_m(const char*, char*)' {_ZNSt11__copy_moveILb1ELb1ESt26random_access_iterator_tagE8__copy_mIcEEPT_PKS3_S6_S4_} + [D] 'function char* std::__copy_move_a2(char*, char*, char*)' {_ZSt14__copy_move_a2ILb1EPcS0_ET1_T0_S2_S1_} + [D] 'function char* std::__copy_move_a(char*, char*, char*)' {_ZSt13__copy_move_aILb1EPcS0_ET1_T0_S2_S1_} + [D] 'function std::move_iterator std::__make_move_if_noexcept_iterator(char*)' {_ZSt32__make_move_if_noexcept_iteratorIcSt13move_iteratorIPcEET0_PT_} + [D] 'function char* std::__miter_base(char*)' {_ZSt12__miter_baseIPcET_S1_} + [D] 'function char* std::__miter_base(std::move_iterator)' {_ZSt12__miter_baseIPcEDTcl12__miter_basecldtfp_4baseEEESt13move_iteratorIT_E} + [D] 'method char* std::__uninitialized_copy::__uninit_copy, char*>(std::move_iterator, char*)' {_ZNSt20__uninitialized_copyILb1EE13__uninit_copyISt13move_iteratorIPcES3_EET0_T_S6_S5_} + [D] 'function char* std::__uninitialized_copy_a, char*, char>(std::move_iterator, std::move_iterator, char*, std::allocator&)' {_ZSt22__uninitialized_copy_aISt13move_iteratorIPcES1_cET0_T_S4_S3_RSaIT1_E} + [D] 'function char* std::__uninitialized_move_if_noexcept_a >(char*, char*, char*, std::allocator&)' {_ZSt34__uninitialized_move_if_noexcept_aIPcS0_SaIcEET0_T_S3_S2_RT1_} + [D] 'method void std::allocator_traits >::destroy(char*)' {_ZNSt16allocator_traitsISaIcEE7destroyIcEEvRS0_PT_} + [D] 'function char* std::copy, char*>(std::move_iterator, std::move_iterator, char*)' {_ZSt4copyISt13move_iteratorIPcES1_ET0_T_S4_S3_} + [D] 'method std::move_iterator::iterator_type std::move_iterator::base() const' {_ZNKSt13move_iteratorIPcE4baseEv} + [D] 'method void std::move_iterator::move_iterator(std::move_iterator::iterator_type)' {_ZNSt13move_iteratorIPcEC2ES0_, aliases _ZNSt13move_iteratorIPcEC1ES0_} + [D] 'function char* std::uninitialized_copy, char*>(std::move_iterator, std::move_iterator, char*)' {_ZSt18uninitialized_copyISt13move_iteratorIPcES1_ET0_T_S4_S3_} + [D] 'method void std::vector >::emplace_back()' {_ZNSt6vectorIcSaIcEE12emplace_backIJcEEEvDpOT_} + +21 Added functions: + + [A] 'function bool __gnu_cxx::__is_null_pointer(const char*)' {_ZN9__gnu_cxx17__is_null_pointerIKcEEbPT_} + [A] 'method __gnu_cxx::__normal_iterator > >::reference __gnu_cxx::__normal_iterator > >::operator*() const' {_ZNK9__gnu_cxx17__normal_iteratorIPcSt6vectorIcSaIcEEEdeEv} + [A] 'method __gnu_cxx::__normal_iterator > > __gnu_cxx::__normal_iterator > >::operator-(__gnu_cxx::__normal_iterator > >::difference_type) const' {_ZNK9__gnu_cxx17__normal_iteratorIPcSt6vectorIcSaIcEEEmiEl} + [A] 'method bool __gnu_cxx::char_traits::eq(const __gnu_cxx::char_traits::char_type&)' {_ZN9__gnu_cxx11char_traitsIcE2eqERKcS3_} + [A] 'method std::size_t __gnu_cxx::char_traits::length()' {_ZN9__gnu_cxx11char_traitsIcE6lengthEPKc} + [A] 'method __gnu_cxx::new_allocator::size_type __gnu_cxx::new_allocator::_M_max_size() const' {_ZNK9__gnu_cxx13new_allocatorIcE11_M_max_sizeEv} + [A] 'method std::_Vector_base >::_Vector_impl_data::_Vector_impl_data()' {_ZNSt12_Vector_baseIcSaIcEE17_Vector_impl_dataC2Ev, aliases _ZNSt12_Vector_baseIcSaIcEE17_Vector_impl_dataC1Ev} + [A] 'method void std::__cxx11::basic_string, std::allocator >::_M_construct(const char*, const char*, std::forward_iterator_tag)' {_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag} + [A] 'method void std::__cxx11::basic_string, std::allocator >::basic_string<>(const char*, const std::allocator&)' {_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IS3_EEPKcRKS3_, aliases _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IS3_EEPKcRKS3_} + [A] 'function std::iterator_traits::difference_type std::__distance(const char*, const char*, std::random_access_iterator_tag)' {_ZSt10__distanceIPKcENSt15iterator_traitsIT_E15difference_typeES3_S3_St26random_access_iterator_tag} + [A] 'function std::iterator_traits::iterator_category std::__iterator_category(const char* const&)' {_ZSt19__iterator_categoryIPKcENSt15iterator_traitsIT_E17iterator_categoryERKS3_} + [A] 'function char* std::__relocate_a >(char*, char*, char*, std::allocator&)' {_ZSt12__relocate_aIPcS0_SaIcEET0_T_S3_S2_RT1_} + [A] 'function std::__enable_if_t std::__relocate_a_1(char*, char*, char*, std::allocator&)' {_ZSt14__relocate_a_1IccENSt9enable_ifIXsrSt24__is_bitwise_relocatableIT_vE5valueEPS2_E4typeES4_S4_S4_RSaIT0_E} + [A] 'method std::size_t std::char_traits::length()' {_ZNSt11char_traitsIcE6lengthEPKc} + [A] 'function std::iterator_traits::difference_type std::distance(const char*, const char*)' {_ZSt8distanceIPKcENSt15iterator_traitsIT_E15difference_typeES3_S3_} + [A] 'function const unsigned long int& std::min(const unsigned long int&, const unsigned long int&)' {_ZSt3minImERKT_S2_S2_} + [A] 'method std::vector >::pointer std::vector >::_S_do_relocate(std::vector >::pointer, std::vector >::pointer, std::vector >::_Tp_alloc_type&, std::true_type)' {_ZNSt6vectorIcSaIcEE14_S_do_relocateEPcS2_S2_RS0_St17integral_constantIbLb1EE} + [A] 'method std::vector >::size_type std::vector >::_S_max_size()' {_ZNSt6vectorIcSaIcEE11_S_max_sizeERKS0_} + [A] 'method std::vector >::pointer std::vector >::_S_relocate(std::vector >::pointer, std::vector >::pointer, std::vector >::_Tp_alloc_type&)' {_ZNSt6vectorIcSaIcEE11_S_relocateEPcS2_S2_RS0_} + [A] 'method std::vector >::reference std::vector >::back()' {_ZNSt6vectorIcSaIcEE4backEv} + [A] 'method std::vector >::reference std::vector >::emplace_back()' {_ZNSt6vectorIcSaIcEE12emplace_backIJcEEERcDpOT_} + +2 Removed function symbols not referenced by debug info: + + [D] _fini + [D] _init + +2 Added function symbols not referenced by debug info: + + [A] _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderD1Ev, aliases _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderD2Ev + [A] _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderD2Ev + diff --git a/tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-2.txt b/tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-2.txt new file mode 100644 index 00000000..b8e9599b --- /dev/null +++ b/tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-2.txt @@ -0,0 +1,5 @@ +Functions changes summary: 0 Removed (16 filtered out), 0 Changed (20 filtered out), 0 Added (21 filtered out) functions +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable +Function symbols changes summary: 0 Removed (2 filtered out), 0 Added (2 filtered out) function symbols not referenced by debug info +Variable symbols changes summary: 0 Removed, 0 Added variable symbol not referenced by debug info + diff --git a/tests/data/test-abidiff-exit/PR31513/reported/libloremipsum_gcc11.so b/tests/data/test-abidiff-exit/PR31513/reported/libloremipsum_gcc11.so new file mode 100644 index 0000000000000000000000000000000000000000..94897ee3566b5523bfe9a1bcde962295c05a4425 GIT binary patch literal 115160 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