From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14140 invoked by alias); 22 Oct 2019 15:04:34 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 14052 invoked by uid 89); 22 Oct 2019 15:04:33 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-7.6 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_2,GIT_PATCH_3 autolearn=ham version=3.3.1 spammy=thereof, handwritten, Partial X-HELO: us-smtp-delivery-1.mimecast.com Received: from us-smtp-1.mimecast.com (HELO us-smtp-delivery-1.mimecast.com) (205.139.110.61) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 22 Oct 2019 15:04:31 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571756669; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=6P3kIoQkGt6iGTQdgfWT34nE4gu69veyncb/fNNDTCo=; b=TfvsBh9ciIjz+w3DOF8XdKj4b7U8HUq4/Sd8uBzjt60z86RPm7r73+l3fns61hqCPdE5QU t91DRlGl4soB+avi/QFkZWms1UCuKgLIKO0WOQyI4Evl3xNwoxN51uFOdKaTnuD366csHh nBIxGyzQf1V48v3QPV6ASNRFa02ATqI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-42-tLGnSzrxPZqXhPFQbS3Y4g-1; Tue, 22 Oct 2019 11:04:25 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0C4615E9; Tue, 22 Oct 2019 15:03:54 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.36.118.135]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A9114612AB; Tue, 22 Oct 2019 15:03:53 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id x9MF3pkU008668; Tue, 22 Oct 2019 17:03:51 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id x9MF3jmn008667; Tue, 22 Oct 2019 17:03:45 +0200 Date: Tue, 22 Oct 2019 15:20:00 -0000 From: Jakub Jelinek To: Jason Merrill , Martin Sebor Cc: gcc-patches@gcc.gnu.org Subject: [C++ PATCH] Partial fix for a recent regression (PR c++/90947) Message-ID: <20191022150345.GD2116@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 User-Agent: Mutt/1.11.3 (2019-02-01) X-Mimecast-Spam-Score: 0 Content-Type: text/plain; charset=WINDOWS-1252 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline X-IsSubscribed: yes X-SW-Source: 2019-10/txt/msg01581.txt.bz2 Hi! The following patch is just a partial fix for a regression introduced in the PR90947 changes, the testcase is fixed for just C++17/20. type_initializer_zero_p has been added to the generic code, supposedly because similar initializer_zerop is in generic code too, but that means it has a hand-written copy of next_initializable_field which can't do exactly what next_initializable_field does. The following patch moves it into the C++ FE which is the only user of that function and uses next_initializable_field in there. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? I'm afraid I'm lost on how to fix the C++11/14 case, the object being initialized has std::atomic type, which doesn't have any direct non-static data members, and has std::__atomic_base as base class that has some field. The only FIELD_DECL in std::atomic is DECL_ARTIFICIAL field for the base class, so next_initializable_field or the hand-written variant thereof doesn't find any initializable fields for 11/14. The initializer is initializer list { {1} } and the function just returns true if it doesn't find any initializable fields, so in the end we misoptimize it as { {0} }. 2019-10-22 Jakub Jelinek PR c++/90947 * tree.h (type_initializer_zero_p): Remove. * tree.c (type_initializer_zero_p): Remove. cp/ * cp-tree.h (type_initializer_zero_p): Declare. * decl.c (reshape_init_array_1): Formatting fix. * tree.c (type_initializer_zero_p): New function. Moved from ../tree.c, use next_initializable_field, formatting fix. --- gcc/tree.h.jj 2019-09-20 12:25:13.737920929 +0200 +++ gcc/tree.h 2019-10-22 10:07:26.411826804 +0200 @@ -4690,12 +4690,6 @@ extern tree first_field (const_tree); extern bool initializer_zerop (const_tree, bool * =3D NULL); extern bool initializer_each_zero_or_onep (const_tree); =20 -/* Analogous to initializer_zerop but also examines the type for - which the initializer is being used. Unlike initializer_zerop, - considers empty strings to be zero initializers for arrays and - non-zero for pointers. */ -extern bool type_initializer_zero_p (tree, tree); - extern wide_int vector_cst_int_elt (const_tree, unsigned int); extern tree vector_cst_elt (const_tree, unsigned int); =20 --- gcc/tree.c.jj 2019-10-19 09:22:14.830893404 +0200 +++ gcc/tree.c 2019-10-22 10:08:36.501748481 +0200 @@ -11396,73 +11396,6 @@ initializer_each_zero_or_onep (const_tre } } =20 -/* Given an initializer INIT for a TYPE, return true if INIT is zero - so that it can be replaced by value initialization. This function - distinguishes betwen empty strings as initializers for arrays and - for pointers (which make it return false). */ - -bool -type_initializer_zero_p (tree type, tree init) -{ - if (type =3D=3D error_mark_node || init =3D=3D error_mark_node) - return false; - - STRIP_NOPS (init); - - if (POINTER_TYPE_P (type)) - return TREE_CODE (init) !=3D STRING_CST && initializer_zerop (init); - - if (TREE_CODE (init) !=3D CONSTRUCTOR) - return initializer_zerop (init); - - if (TREE_CODE (type) =3D=3D ARRAY_TYPE) - { - tree elt_type =3D TREE_TYPE (type); - elt_type =3D TYPE_MAIN_VARIANT (elt_type); - if (elt_type =3D=3D char_type_node) - return initializer_zerop (init); - - tree elt_init; - unsigned HOST_WIDE_INT i; - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, elt_init) - if (!type_initializer_zero_p (elt_type, elt_init)) - return false; - return true; - } - - if (TREE_CODE (type) !=3D RECORD_TYPE) - return initializer_zerop (init); - - tree fld =3D TYPE_FIELDS (type); - - tree fld_init; - unsigned HOST_WIDE_INT i; - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, fld_init) - { - /* Advance to the next member, skipping over everything that - canot be initialized (including unnamed bit-fields). */ - while (TREE_CODE (fld) !=3D FIELD_DECL - || DECL_ARTIFICIAL (fld) - || (DECL_BIT_FIELD (fld) && !DECL_NAME (fld))) - { - fld =3D DECL_CHAIN (fld); - if (!fld) - return true; - continue; - } - - tree fldtype =3D TREE_TYPE (fld); - if (!type_initializer_zero_p (fldtype, fld_init)) - return false; - - fld =3D DECL_CHAIN (fld); - if (!fld) - break; - } - - return true; -} - /* Check if vector VEC consists of all the equal elements and that the number of elements corresponds to the type of VEC. The function returns first element of the vector --- gcc/cp/cp-tree.h.jj 2019-10-22 08:15:53.810775827 +0200 +++ gcc/cp/cp-tree.h 2019-10-22 10:10:57.265582861 +0200 @@ -7379,6 +7379,11 @@ extern tree cxx_copy_lang_qualifiers (c =20 extern void cxx_print_statistics (void); extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t); +/* Analogous to initializer_zerop but also examines the type for + which the initializer is being used. Unlike initializer_zerop, + considers empty strings to be zero initializers for arrays and + non-zero for pointers. */ +extern bool type_initializer_zero_p (tree, tree); =20 /* in ptree.c */ extern void cxx_print_xnode (FILE *, tree, int); --- gcc/cp/decl.c.jj 2019-10-22 08:57:12.913654620 +0200 +++ gcc/cp/decl.c 2019-10-22 10:13:39.038094034 +0200 @@ -5982,9 +5982,8 @@ reshape_init_array_1 (tree elt_type, tre /* Pointers initialized to strings must be treated as non-zero even if the string is empty. */ tree init_type =3D TREE_TYPE (elt_init); - if ((POINTER_TYPE_P (elt_type) !=3D POINTER_TYPE_P (init_type))) - last_nonzero =3D index; - else if (!type_initializer_zero_p (elt_type, elt_init)) + if (POINTER_TYPE_P (elt_type) !=3D POINTER_TYPE_P (init_type) + || !type_initializer_zero_p (elt_type, elt_init)) last_nonzero =3D index; =20 /* This can happen with an invalid initializer (c++/54501). */ --- gcc/cp/tree.c.jj 2019-10-19 09:22:16.594866462 +0200 +++ gcc/cp/tree.c 2019-10-22 10:10:29.151015397 +0200 @@ -5527,6 +5527,65 @@ maybe_warn_zero_as_null_pointer_constant return false; } =0C +/* Given an initializer INIT for a TYPE, return true if INIT is zero + so that it can be replaced by value initialization. This function + distinguishes betwen empty strings as initializers for arrays and + for pointers (which make it return false). */ + +bool +type_initializer_zero_p (tree type, tree init) +{ + if (type =3D=3D error_mark_node || init =3D=3D error_mark_node) + return false; + + STRIP_NOPS (init); + + if (POINTER_TYPE_P (type)) + return TREE_CODE (init) !=3D STRING_CST && initializer_zerop (init); + + if (TREE_CODE (init) !=3D CONSTRUCTOR) + return initializer_zerop (init); + + if (TREE_CODE (type) =3D=3D ARRAY_TYPE) + { + tree elt_type =3D TREE_TYPE (type); + elt_type =3D TYPE_MAIN_VARIANT (elt_type); + if (elt_type =3D=3D char_type_node) + return initializer_zerop (init); + + tree elt_init; + unsigned HOST_WIDE_INT i; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, elt_init) + if (!type_initializer_zero_p (elt_type, elt_init)) + return false; + return true; + } + + if (TREE_CODE (type) !=3D RECORD_TYPE) + return initializer_zerop (init); + + tree fld =3D TYPE_FIELDS (type); + + tree fld_init; + unsigned HOST_WIDE_INT i; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, fld_init) + { + fld =3D next_initializable_field (fld); + if (!fld) + return true; + + tree fldtype =3D TREE_TYPE (fld); + if (!type_initializer_zero_p (fldtype, fld_init)) + return false; + + fld =3D DECL_CHAIN (fld); + if (!fld) + break; + } + + return true; +} +=0C #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >=3D 2007) /* Complain that some language-specific thing hanging off a tree node has been accessed improperly. */ Jakub