From patchwork Tue Oct 22 15:03:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1181440 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511510-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="hA0CLhmT"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="TfvsBh9c"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46yGyB6LQlz9sNx for ; Wed, 23 Oct 2019 02:04:49 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type:content-transfer-encoding; q=dns; s=default; b=wsM ANHfOvOJ5VlxVpM8UeUSwgPgoYWi1uvlIxwRKEfmCyrP1b74I6v0ThZz2wNwJtKm urfz/nhSC0+lcRGa0byZKa+2BaYoKq5ACMaT+NHDn3sNX2FZz3UFtEfQf04V0HVm uUyduQn0cWiBcbNmw5TffSUbx9bK032qAzcAhel4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type:content-transfer-encoding; s=default; bh=c016PUaE7 mcCL3NfooULngHa8Dw=; b=hA0CLhmTIO4clW7EuEnBQZH+NKBs4sS9RyvtG73DB FyQPHfppKxshmpoWv2vxGm/WkNgjRnuWRjTeIQXO3dBF76SGbqMKPrX5Z8TyR1Vl /LQCTFwLz99LtbA3wmNZQG7AixP+Lu7TvEysyp2l4M2YcUZOipgbUtnwo6+6/tNZ b4= 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-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@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 17:03:45 +0200 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-Disposition: inline X-IsSubscribed: yes 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. Jakub --- 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 * = NULL); extern bool initializer_each_zero_or_onep (const_tree); -/* 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); --- 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 } } -/* 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 == error_mark_node || init == error_mark_node) - return false; - - STRIP_NOPS (init); - - if (POINTER_TYPE_P (type)) - return TREE_CODE (init) != STRING_CST && initializer_zerop (init); - - if (TREE_CODE (init) != CONSTRUCTOR) - return initializer_zerop (init); - - if (TREE_CODE (type) == ARRAY_TYPE) - { - tree elt_type = TREE_TYPE (type); - elt_type = TYPE_MAIN_VARIANT (elt_type); - if (elt_type == 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) != RECORD_TYPE) - return initializer_zerop (init); - - tree fld = 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) != FIELD_DECL - || DECL_ARTIFICIAL (fld) - || (DECL_BIT_FIELD (fld) && !DECL_NAME (fld))) - { - fld = DECL_CHAIN (fld); - if (!fld) - return true; - continue; - } - - tree fldtype = TREE_TYPE (fld); - if (!type_initializer_zero_p (fldtype, fld_init)) - return false; - - fld = 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 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); /* 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 = TREE_TYPE (elt_init); - if ((POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type))) - last_nonzero = index; - else if (!type_initializer_zero_p (elt_type, elt_init)) + if (POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type) + || !type_initializer_zero_p (elt_type, elt_init)) last_nonzero = index; /* 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; } +/* 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 == error_mark_node || init == error_mark_node) + return false; + + STRIP_NOPS (init); + + if (POINTER_TYPE_P (type)) + return TREE_CODE (init) != STRING_CST && initializer_zerop (init); + + if (TREE_CODE (init) != CONSTRUCTOR) + return initializer_zerop (init); + + if (TREE_CODE (type) == ARRAY_TYPE) + { + tree elt_type = TREE_TYPE (type); + elt_type = TYPE_MAIN_VARIANT (elt_type); + if (elt_type == 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) != RECORD_TYPE) + return initializer_zerop (init); + + tree fld = TYPE_FIELDS (type); + + tree fld_init; + unsigned HOST_WIDE_INT i; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, fld_init) + { + fld = next_initializable_field (fld); + if (!fld) + return true; + + tree fldtype = TREE_TYPE (fld); + if (!type_initializer_zero_p (fldtype, fld_init)) + return false; + + fld = DECL_CHAIN (fld); + if (!fld) + break; + } + + return true; +} + #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) /* Complain that some language-specific thing hanging off a tree node has been accessed improperly. */