From patchwork Fri Jan 18 20:35:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 1027739 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-494331-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="vjwI5Sq9"; 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 43hCQF45nGz9sD9 for ; Sat, 19 Jan 2019 07:36:03 +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:from :to:subject:date:message-id:mime-version :content-transfer-encoding; q=dns; s=default; b=d63auhiuzidp2U5d ItqSwu6w04k2TAzJoZX6lTk+X8KvT0HfHVyG/Ga2rlt9q0XSwSEL+OhDOtFTJpMf Za83qucNCgTb2nYPXpeZO0y7UGM0tRKHysK7Cm9zkwmyU/N3AZMLvrNvafFoOBB+ 0UawE7Uex6PVZIGYKoZdJe1vOGY= 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:from :to:subject:date:message-id:mime-version :content-transfer-encoding; s=default; bh=U/eH7e3UJ6GUwSsTLPqPHJ Rifh8=; b=vjwI5Sq9PDdyJtNW3ssrJp3x4r0oRCAl9fBuutMgrl3sYpbRownMVJ cHijIoU/fgnsrWU1OxTTL2DTPUfU0dXifwkFsp7XHTWnzIr+ekSMgXb5YRgI98uq Jqk2LTr1oVUxiCtIs7BsT1tvU8lQlHX8gwLlMl1BXUdfEIlmbc+5M= Received: (qmail 77777 invoked by alias); 18 Jan 2019 20:35:56 -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 77716 invoked by uid 89); 18 Jan 2019 20:35:55 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=sk:copyli, sk:maybe_w, sk:copy-li, initializing X-HELO: mail-qt1-f195.google.com Received: from mail-qt1-f195.google.com (HELO mail-qt1-f195.google.com) (209.85.160.195) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Jan 2019 20:35:53 +0000 Received: by mail-qt1-f195.google.com with SMTP id u47so16681439qtj.6 for ; Fri, 18 Jan 2019 12:35:52 -0800 (PST) Received: from orpheus.redhat.com (209-6-216-142.s141.c3-0.smr-cbr1.sbo-smr.ma.cable.rcncustomer.com. [209.6.216.142]) by smtp.gmail.com with ESMTPSA id a185sm49240065qkb.1.2019.01.18.12.35.50 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 Jan 2019 12:35:50 -0800 (PST) From: Jason Merrill To: gcc-patches@gcc.gnu.org Subject: [C++ PATCH] PR c++/88875 - error with explicit list constructor. Date: Fri, 18 Jan 2019 15:35:48 -0500 Message-Id: <20190118203548.29886-1-jason@redhat.com> MIME-Version: 1.0 X-IsSubscribed: yes In my patch for CWG issue 2267, I changed reference_binding to clear CONSTRUCTOR_IS_DIRECT_INIT on the argument init-list. But that breaks if there's another candidate for which CONSTRUCTOR_IS_DIRECT_INIT is correct. So instead, let's encode in the conversion that we want to override the flag. Tested x86_64-pc-linux-gnu, applying to trunk. * call.c (reference_binding): Don't modify EXPR. Set need_temporary_p on the ck_user conversion for a temporary. (convert_like_real): Check it. --- gcc/cp/call.c | 11 +++++++--- .../g++.dg/cpp0x/initlist-explicit2.C | 20 +++++++++++++++++++ gcc/cp/ChangeLog | 7 +++++++ 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-explicit2.C base-commit: 31975c5ea11cee1a66a59e6d941db4c6b3cc602c diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 499894b353f..16c3706cc5c 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -94,7 +94,7 @@ struct conversion { BOOL_BITFIELD bad_p : 1; /* If KIND is ck_ref_bind ck_base_conv, true to indicate that a temporary should be created to hold the result of the - conversion. If KIND is ck_ambig, true if the context is + conversion. If KIND is ck_ambig or ck_user, true means force copy-initialization. */ BOOL_BITFIELD need_temporary_p : 1; /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion @@ -1560,6 +1560,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags, from = TREE_TYPE (expr); } + bool copy_list_init = false; if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr)) { maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); @@ -1582,7 +1583,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags, /* Otherwise, if T is a reference type, a prvalue temporary of the type referenced by T is copy-list-initialized, and the reference is bound to that temporary. */ - CONSTRUCTOR_IS_DIRECT_INIT (expr) = false; + copy_list_init = true; skip:; } @@ -1770,6 +1771,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags, if (conv->user_conv_p) { + if (copy_list_init) + /* Remember this was copy-list-initialization. */ + conv->need_temporary_p = true; + /* If initializing the temporary used a conversion function, recalculate the second conversion sequence. */ for (conversion *t = conv; t; t = next_conversion (t)) @@ -6941,7 +6946,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn) && BRACE_ENCLOSED_INITIALIZER_P (expr) /* Unless this is for direct-list-initialization. */ - && !CONSTRUCTOR_IS_DIRECT_INIT (expr) + && (!CONSTRUCTOR_IS_DIRECT_INIT (expr) || convs->need_temporary_p) /* And in C++98 a default constructor can't be explicit. */ && cxx_dialect >= cxx11) { diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-explicit2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-explicit2.C new file mode 100644 index 00000000000..26a63bf2aa7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-explicit2.C @@ -0,0 +1,20 @@ +// PR c++/88875 +// { dg-do compile { target c++11 } } + +#include + +struct X { + X(); + explicit X(const std::initializer_list& init); +}; + +struct Y +{ + X x { 1, 2 }; // error + + Y (int) + : x {1, 2} // ok + { + } + +}; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d224b72c0bb..4292930daf3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-01-18 Jason Merrill + + PR c++/88875 - error with explicit list constructor. + * call.c (reference_binding): Don't modify EXPR. Set + need_temporary_p on the ck_user conversion for a temporary. + (convert_like_real): Check it. + 2019-01-18 H.J. Lu PR c/51628