From patchwork Sat Mar 2 00:58:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1907013 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=XX1BGxDt; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TmmnL3J65z23fC for ; Sat, 2 Mar 2024 11:59:18 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5966C385841B for ; Sat, 2 Mar 2024 00:59:16 +0000 (GMT) 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 DC32A3858C66 for ; Sat, 2 Mar 2024 00:58:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DC32A3858C66 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 DC32A3858C66 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=1709341137; cv=none; b=wNEKHO+vXQ41nR4jFJQJd6Dk0oEx1Bx01t5sc8qd1qtDtTGOyDCfVUaF6lJ/mjBROjmdlGRPm90zrtxttdvgraaMrpobAnK0eyofzhdD1i7dsojAk6iSbivm9wXOntQwniqlDnpdTw/ftLzkdYbI3K4N4smurTwtOZ/R+TTZF+U= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709341137; c=relaxed/simple; bh=66a7A4STG6mxPe4OWaM9rpSnNnQ1o6jMfT9XUQ6izwA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=RnLH96af0QMSgqr0YWuqLUeh01VkZUPiZNtIUDOJqwXSvdQLUjcOQ4hD521ZbeFt5R/4bUl91lWTqP+F0AC/cLjJue16nnQaX6KUjP3SIzUV23QW1jqMfOinTqrqRldDyfsj72kj/ztWmJPZya57BGFHg96Ir9vCWMIrHqTfGtM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709341135; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Tye6Dn4yDqAoiIvMVXmba8lvvn2uwYzbbSYCIhFHyBA=; b=XX1BGxDttjDjdUy1T+6pFktqmdS9+n/17oS/dkuOOdJWcZ+7CumRUkU7e9rEk9qxjtcBIh OZjz2cjw1krgMGzsMwIX5FsHGuucllsTe5tlL+XIlNsKkFxzs6FWxf5UPBjQ06Y7FPq5/b 4aD5Vv5U8kLXj0TDoaP/NWoIxoDP2cg= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-179-CUz6a65bNReZI7Nwy2FpJQ-1; Fri, 01 Mar 2024 19:58:53 -0500 X-MC-Unique: CUz6a65bNReZI7Nwy2FpJQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A3597811E79 for ; Sat, 2 Mar 2024 00:58:53 +0000 (UTC) Received: from pdp-11.redhat.com (unknown [10.22.17.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id 81B2DC03380; Sat, 2 Mar 2024 00:58:53 +0000 (UTC) From: Marek Polacek To: GCC Patches , Jason Merrill Subject: [PATCH] c++: direct-init of an array of class type [PR59465] Date: Fri, 1 Mar 2024 19:58:51 -0500 Message-ID: <20240302005851.924184-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? I don't claim that this has to go to 14 though. -- >8 -- ...from another array in a mem-initializer should not be accepted. We already reject struct string {} a[1]; string x[1](a); but struct pair { string s[1]; pair() : s(a) {} }; is wrongly accepted. It started to be accepted with r0-110915-ga034826198b771: which was supposed to be a cleanup, not a deliberate change to start accepting the code. The build_vec_init_expr code was added in r165976: . It appears that we do the magic copy array when we have a defaulted constructor and we generate code for its mem-initializer which initializes an array. I also see that we go that path for compound literals. So when initializing an array member, we can limit building up a VEC_INIT_EXPR to those special cases. PR c++/59465 gcc/cp/ChangeLog: * init.cc (can_init_array_with_p): New. (perform_member_init): Check it. gcc/testsuite/ChangeLog: * g++.dg/init/array62.C: New test. * g++.dg/init/array63.C: New test. * g++.dg/init/array64.C: New test. --- gcc/cp/init.cc | 27 ++++++++++++++++++++++++++- gcc/testsuite/g++.dg/init/array62.C | 19 +++++++++++++++++++ gcc/testsuite/g++.dg/init/array63.C | 13 +++++++++++++ gcc/testsuite/g++.dg/init/array64.C | 22 ++++++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/init/array62.C create mode 100644 gcc/testsuite/g++.dg/init/array63.C create mode 100644 gcc/testsuite/g++.dg/init/array64.C base-commit: 574fd1f17f100c7c355ad26bc525ab5a3386bb2d diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index d2586fad86b..fb8c0e521fb 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -934,6 +934,31 @@ find_uninit_fields (tree *t, hash_set *uninitialized, tree member) } } +/* Return true if it's OK to initialize an array from INIT. Mere mortals + can't copy arrays, but the compiler can do so with a VEC_INIT_EXPR in + certain cases. */ + +static bool +can_init_array_with_p (tree init) +{ + if (!init) + return true; + + /* We're called from synthesize_method, and we're processing the + mem-initializers of a constructor. */ + if (DECL_DEFAULTED_FN (current_function_decl)) + return true; + /* As an extension, we allow copying from a compound literal. */ + else if (TREE_CODE (init) == TARGET_EXPR) + { + init = TARGET_EXPR_INITIAL (init); + if (TREE_CODE (init) == CONSTRUCTOR) + return CONSTRUCTOR_C99_COMPOUND_LITERAL (init); + } + + return false; +} + /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of arguments. If TREE_LIST is void_type_node, an empty initializer list was given; if NULL_TREE no initializer was given. UNINITIALIZED @@ -1085,7 +1110,7 @@ perform_member_init (tree member, tree init, hash_set &uninitialized) else if (type_build_ctor_call (type) || (init && CLASS_TYPE_P (strip_array_types (type)))) { - if (TREE_CODE (type) == ARRAY_TYPE) + if (TREE_CODE (type) == ARRAY_TYPE && can_init_array_with_p (init)) { if (init == NULL_TREE || same_type_ignoring_top_level_qualifiers_p (type, diff --git a/gcc/testsuite/g++.dg/init/array62.C b/gcc/testsuite/g++.dg/init/array62.C new file mode 100644 index 00000000000..6d3935d7a66 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array62.C @@ -0,0 +1,19 @@ +// PR c++/59465 +// { dg-do compile } + +struct string {} a[1]; +struct pair { + string s[1]; + pair() : s(a) {} // { dg-error "array must be initialized" } +}; + +struct S { + char s[10]; + S() : s("aaa") {} +}; + +void +g () +{ + string x[1](a); // { dg-error "array must be initialized" } +} diff --git a/gcc/testsuite/g++.dg/init/array63.C b/gcc/testsuite/g++.dg/init/array63.C new file mode 100644 index 00000000000..96bc9a64b26 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array63.C @@ -0,0 +1,13 @@ +// PR c++/59465 +// { dg-do compile } + +struct I { + const bool b; +}; +struct O { + I a[2]; + static I const data[2]; + O() : a(data){} // { dg-error "array must be initialized" } +}; + +I const O::data[2] = {true, false}; diff --git a/gcc/testsuite/g++.dg/init/array64.C b/gcc/testsuite/g++.dg/init/array64.C new file mode 100644 index 00000000000..bbdd70c6df8 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array64.C @@ -0,0 +1,22 @@ +// PR c++/59465 +// { dg-do compile } + +static const int my_size = 10; + +class UserType +{ +public: + UserType(): f_(){} +private: +int f_; +}; + +typedef UserType Array[my_size]; + +class Foo +{ +public: + Foo(Array& m) : m_(m) {}; // { dg-error "array must be initialized" } +private: + Array m_; +};