From patchwork Wed May 6 02:01:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 468556 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 5AF1B140134 for ; Wed, 6 May 2015 12:01:34 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=AnbuC0dj; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=rKxi1brz/L9Hp36aYPj9pgU+ip1I0xeIKHbumHmy4IwaL+ KXZog7iifYrFf0i7psOvvDqeV1oO6pU1pm483n6Q7LKgOK5UAQuh719NkycM88vm 40ym0ZsppSHJBKnbNZtnZg5encm0KnLyboFcxj/F5RT3IxbweQg3LkMLHn+0U= 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 :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=C8UqPphMW03Geoux6FQDmMj5DIE=; b=AnbuC0dj/NvupphDdeB6 MQn/A98GVxNMJpCp/x0Op0PPX2PyLTJgnMH0JG4UbCh2WrTNo7Y/OgYzp4kT6ghx 2eXP+nPH11dt5VodKCkqiPyJT9D3ZkFi0fT/TFMivMuVW6WyNgBtTJOf7gL6VzK4 yqgvyat3/AgFbCc4F86qOmg= Received: (qmail 112449 invoked by alias); 6 May 2015 02:01:25 -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 112223 invoked by uid 89); 6 May 2015 02:01:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.6 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 06 May 2015 02:01:23 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t4621LVr005903 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 5 May 2015 22:01:21 -0400 Received: from [10.3.112.15] ([10.3.112.15]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t4621Kh6018321 for ; Tue, 5 May 2015 22:01:20 -0400 Message-ID: <554975EF.7000401@redhat.com> Date: Tue, 05 May 2015 21:01:19 -0500 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for DR 1518 (explicit default ctor and copy-list-initialization) I went to draft standardese for DR 1518 this week and realized that it had already been resolved by DR 1630, which clarified that default-initialization can call explicit default constructors even in the context of copy-list-initialization. So this patch adjusts my earlier approximation to reflect that. Tested x86_64-pc-linux-gnu, applying to trunk. commit 733826123adfc74ffb07e423fb8cd9311c8d6a86 Author: Jason Merrill Date: Mon May 4 06:45:03 2015 -0500 DR 1518 DR 1630 PR c++/54835 PR c++/60417 * call.c (convert_like_real): Check value-initialization before explicit. * typeck2.c (process_init_constructor_record): Don't set CONSTRUCTOR_IS_DIRECT_INIT. (process_init_constructor_array): Likewise. * init.c (build_vec_init): Likewise. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7bdf236..b77f69a 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6243,19 +6243,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, tree convfn = cand->fn; unsigned i; - /* When converting from an init list we consider explicit - constructors, but actually trying to call one is an error. */ - if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn) - /* Unless this is for direct-list-initialization. */ - && !DIRECT_LIST_INIT_P (expr)) - { - if (!(complain & tf_error)) - return error_mark_node; - error ("converting to %qT from initializer list would use " - "explicit constructor %qD", totype, convfn); - } - - /* If we're initializing from {}, it's value-initialization. */ + /* If we're initializing from {}, it's value-initialization. Note + that under the resolution of core 1630, value-initialization can + use explicit constructors. */ if (BRACE_ENCLOSED_INITIALIZER_P (expr) && CONSTRUCTOR_NELTS (expr) == 0 && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype)) @@ -6271,6 +6261,18 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, return expr; } + /* When converting from an init list we consider explicit + constructors, but actually trying to call one is an error. */ + if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn) + /* Unless this is for direct-list-initialization. */ + && !DIRECT_LIST_INIT_P (expr)) + { + if (!(complain & tf_error)) + return error_mark_node; + error ("converting to %qT from initializer list would use " + "explicit constructor %qD", totype, convfn); + } + expr = mark_rvalue_use (expr); /* Set user_conv_p on the argument conversions, so rvalue/base diff --git a/gcc/cp/init.c b/gcc/cp/init.c index a4fc9ff..c41e30c 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3720,7 +3720,6 @@ build_vec_init (tree base, tree maxindex, tree init, if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type)) { init = build_constructor (init_list_type_node, NULL); - CONSTRUCTOR_IS_DIRECT_INIT (init) = true; } else { diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index c0df823..6e0c777 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1285,7 +1285,6 @@ process_init_constructor_array (tree type, tree init, we can't rely on the back end to do it for us, so make the initialization explicit by list-initializing from T{}. */ next = build_constructor (init_list_type_node, NULL); - CONSTRUCTOR_IS_DIRECT_INIT (next) = true; next = massage_init_elt (TREE_TYPE (type), next, complain); if (initializer_zerop (next)) /* The default zero-initialization is fine for us; don't @@ -1396,9 +1395,6 @@ process_init_constructor_record (tree type, tree init, for us, so build up TARGET_EXPRs. If the type in question is a class, just build one up; if it's an array, recurse. */ next = build_constructor (init_list_type_node, NULL); - /* Call this direct-initialization pending DR 1518 resolution so - that explicit default ctors don't break valid C++03 code. */ - CONSTRUCTOR_IS_DIRECT_INIT (next) = true; next = massage_init_elt (TREE_TYPE (field), next, complain); /* Warn when some struct elements are implicitly initialized. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-dr1518.C b/gcc/testsuite/g++.dg/cpp0x/initlist-dr1518.C new file mode 100644 index 0000000..9f8ee0b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-dr1518.C @@ -0,0 +1,27 @@ +// DR 1518 +// { dg-do compile { target c++11 } } + +struct A { + explicit A() = default; +}; + +struct B : A { + explicit B() = default; +}; + +struct C { + explicit C(); +}; + +struct D : A { + C c; + explicit D() = default; +}; + +template void f() { + T t = {}; +} +template void g() { + void x(T t); + x({}); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist40.C b/gcc/testsuite/g++.dg/cpp0x/initlist40.C index 6e6a11a..de2e19d 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist40.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist40.C @@ -8,6 +8,6 @@ struct A int main() { - A a1 = { }; // { dg-error "explicit" } + A a1 = { }; A a2 = { 24 }; // { dg-error "explicit" } }