From patchwork Wed Apr 6 14:41:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1613994 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=bgMWtlsA; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KYRzy3kbxz9sFq for ; Thu, 7 Apr 2022 00:42:05 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A7C013840C26 for ; Wed, 6 Apr 2022 14:42:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A7C013840C26 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1649256122; bh=m40pmM0ipJH8k6CrzXVOIpll3QiVeLp3g6Bm6t3PHpU=; h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=bgMWtlsA4NFpC22HD1cg8s8PfxIexvq4tVI/MN/fcpGY6iWhAK1RnMkRlGlcWmoN4 bxr6i8xc20XGhhPMhdP7+MfC3OuuRBDmQAOF/s0eHiWeH3LiVYcYuLpKkRzArlgxmi RHtrvucTBJa/KRA20/VPPn7eAx3LoTE/HYlo3AoQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.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 347A438515C5 for ; Wed, 6 Apr 2022 14:41:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 347A438515C5 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-647-C7RxpzfhPQCprkU-z2sCpg-1; Wed, 06 Apr 2022 10:41:35 -0400 X-MC-Unique: C7RxpzfhPQCprkU-z2sCpg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2E7BC963D4A for ; Wed, 6 Apr 2022 14:41:35 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.195.172]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DFF8A1402642; Wed, 6 Apr 2022 14:41:34 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.16.1/8.16.1) with ESMTPS id 236EfW1t1584322 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 6 Apr 2022 16:41:32 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.16.1/8.16.1/Submit) id 236EfWKg1584321; Wed, 6 Apr 2022 16:41:32 +0200 Date: Wed, 6 Apr 2022 16:41:31 +0200 To: Jason Merrill Subject: [PATCH] c++: Handle __builtin_clear_padding on non-trivially-copyable types [PR102586] Message-ID: References: <20220211185550.GT2646553@tucnak> MIME-Version: 1.0 In-Reply-To: <20220211185550.GT2646553@tucnak> X-Scanned-By: MIMEDefang 2.85 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" On Fri, Feb 11, 2022 at 07:55:50PM +0100, Jakub Jelinek via Gcc-patches wrote: > Something like the https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102586#c16 > will still be needed with adjusted testcase from > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102586#c15 such that > __builtin_clear_padding is called directly on var addresses rather than > in separate functions. Here is an updated version of the https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102586#c15 patch which uses FIELD_DECL in the langhook instead of its TREE_TYPE, and the testcases have been adjusted for the builtin accepting pointers to non-trivially-copyable types only if it is address of a declaration. Bootstrapped/regtested on powerpc64le-linux, ok for trunk? 2022-04-06 Jakub Jelinek PR tree-optimization/102586 gcc/ * langhooks.h (struct lang_hooks_for_types): Add classtype_as_base langhook. * langhooks-def.h (LANG_HOOKS_CLASSTYPE_AS_BASE): Define. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. * gimple-fold.cc (clear_padding_type): Use ftype instead of TREE_TYPE (field) some more. For artificial FIELD_DECLs without name try the lang_hooks.types.classtype_as_base langhook and if it returns non-NULL, use that instead of ftype for recursive call. gcc/cp/ * cp-objcp-common.h (cp_classtype_as_base): Declare. (LANG_HOOKS_CLASSTYPE_AS_BASE): Redefine. * cp-objcp-common.cc (cp_classtype_as_base): New function. gcc/testsuite/ * g++.dg/torture/builtin-clear-padding-5.C: New test. * g++.dg/cpp2a/builtin-clear-padding1.C (bar): Uncomment one call that is now accepted. Jakub --- gcc/langhooks.h.jj 2022-02-11 00:18:54.909437559 +0100 +++ gcc/langhooks.h 2022-04-06 12:34:43.312087323 +0200 @@ -188,6 +188,11 @@ struct lang_hooks_for_types /* Returns a tree for the unit size of T excluding tail padding that might be used by objects inheriting from T. */ tree (*unit_size_without_reusable_padding) (tree); + + /* Returns type corresponding to FIELD's type when FIELD is a C++ base class + i.e., type without virtual base classes or tail padding. Returns + NULL_TREE otherwise. */ + tree (*classtype_as_base) (const_tree); }; /* Language hooks related to decls and the symbol table. */ --- gcc/langhooks-def.h.jj 2022-02-11 00:18:54.887437859 +0100 +++ gcc/langhooks-def.h 2022-04-06 12:31:39.149670170 +0200 @@ -216,6 +216,7 @@ extern tree lhd_unit_size_without_reusab #define LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO NULL #define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE lhd_type_dwarf_attribute #define LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING lhd_unit_size_without_reusable_padding +#define LANG_HOOKS_CLASSTYPE_AS_BASE hook_tree_const_tree_null #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \ LANG_HOOKS_MAKE_TYPE, \ @@ -243,7 +244,8 @@ extern tree lhd_unit_size_without_reusab LANG_HOOKS_GET_DEBUG_TYPE, \ LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO, \ LANG_HOOKS_TYPE_DWARF_ATTRIBUTE, \ - LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING \ + LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING, \ + LANG_HOOKS_CLASSTYPE_AS_BASE \ } /* Declaration hooks. */ --- gcc/gimple-fold.cc.jj 2022-04-06 09:59:32.744654454 +0200 +++ gcc/gimple-fold.cc 2022-04-06 12:35:29.413440758 +0200 @@ -4747,7 +4747,7 @@ clear_padding_type (clear_padding_struct "have well defined padding bits for %qs", field, "__builtin_clear_padding"); } - else if (is_empty_type (TREE_TYPE (field))) + else if (is_empty_type (ftype)) continue; else { @@ -4758,8 +4758,9 @@ clear_padding_type (clear_padding_struct gcc_assert (pos >= 0 && fldsz >= 0 && pos >= cur_pos); clear_padding_add_padding (buf, pos - cur_pos); cur_pos = pos; - clear_padding_type (buf, TREE_TYPE (field), - fldsz, for_auto_init); + if (tree asbase = lang_hooks.types.classtype_as_base (field)) + ftype = asbase; + clear_padding_type (buf, ftype, fldsz, for_auto_init); cur_pos += fldsz; } } --- gcc/cp/cp-objcp-common.h.jj 2022-02-11 00:18:54.730439994 +0100 +++ gcc/cp/cp-objcp-common.h 2022-04-06 12:31:39.151670141 +0200 @@ -31,6 +31,7 @@ extern int cp_decl_dwarf_attribute (cons extern int cp_type_dwarf_attribute (const_tree, int); extern void cp_common_init_ts (void); extern tree cp_unit_size_without_reusable_padding (tree); +extern tree cp_classtype_as_base (const_tree); extern tree cp_get_global_decls (); extern tree cp_pushdecl (tree); extern void cp_register_dumps (gcc::dump_manager *); @@ -167,6 +168,8 @@ extern tree cxx_simulate_record_decl (lo #define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE cp_type_dwarf_attribute #undef LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING #define LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING cp_unit_size_without_reusable_padding +#undef LANG_HOOKS_CLASSTYPE_AS_BASE +#define LANG_HOOKS_CLASSTYPE_AS_BASE cp_classtype_as_base #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing --- gcc/cp/cp-objcp-common.cc.jj 2022-02-11 00:18:54.720440130 +0100 +++ gcc/cp/cp-objcp-common.cc 2022-04-06 13:24:43.543051969 +0200 @@ -280,6 +280,23 @@ cp_unit_size_without_reusable_padding (t return TYPE_SIZE_UNIT (type); } +/* Returns type corresponding to FIELD's type when FIELD is a C++ base class + i.e., type without virtual base classes or tail padding. Returns + NULL_TREE otherwise. */ + +tree +cp_classtype_as_base (const_tree field) +{ + tree type = TREE_TYPE (field); + if (!DECL_ARTIFICIAL (field) + || DECL_NAME (field) != NULL_TREE + || TREE_CODE (type) != RECORD_TYPE) + return NULL_TREE; + if (!TYPE_LANG_SPECIFIC (type)) + return NULL_TREE; + return CLASSTYPE_AS_BASE (type); +} + /* Stubs to keep c-opts.cc happy. */ void push_file_scope (void) --- gcc/testsuite/g++.dg/torture/builtin-clear-padding-5.C.jj 2022-04-06 12:31:39.151670141 +0200 +++ gcc/testsuite/g++.dg/torture/builtin-clear-padding-5.C 2022-04-06 13:15:36.674717019 +0200 @@ -0,0 +1,44 @@ +// PR tree-optimization/102586 +// { dg-options "-Wno-inaccessible-base" } + +struct C0 {}; +struct C1 {}; +struct C2 : C1, virtual C0 {}; +struct C3 : virtual C2, C1 { virtual int foo () { return 1; } }; +struct C4 : virtual C3, C1 { virtual int foo () { return 2; } }; +struct C5 : C4 { virtual int foo () { return 3; } }; +struct C6 { char c; }; +struct C7 : virtual C6, virtual C3, C1 { virtual int foo () { return 4; } }; +struct C8 : C7 { virtual int foo () { return 5; } }; + +__attribute__((noipa)) int +bar (C5 *p) +{ + return p->foo (); +} + +__attribute__((noipa)) int +baz (C3 *p) +{ + return p->foo (); +} + +__attribute__((noipa)) int +qux (C8 *p) +{ + return p->foo (); +} + +int +main () +{ + C5 c5; + C8 c8; + c8.c = 42; + __builtin_clear_padding (&c5); + __builtin_clear_padding (&c8); + if (bar (&c5) != 3 || baz (&c5) != 3) + __builtin_abort (); + if (qux (&c8) != 5 || baz (&c8) != 5 || c8.c != 42) + __builtin_abort (); +} --- gcc/testsuite/g++.dg/cpp2a/builtin-clear-padding1.C.jj 2022-03-14 10:46:42.021766309 +0100 +++ gcc/testsuite/g++.dg/cpp2a/builtin-clear-padding1.C 2022-04-06 13:14:31.614628521 +0200 @@ -43,7 +43,7 @@ bar () __builtin_clear_padding (&c2); __builtin_clear_padding (&c3); __builtin_clear_padding (&c4); -// __builtin_clear_padding (&c5); + __builtin_clear_padding (&c5); __builtin_clear_padding (&c6); __builtin_clear_padding (&c7); __builtin_clear_padding (&c8);