From patchwork Thu Mar 2 01:58:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 734432 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 3vYb8Y6M9Zz9s7k for ; Thu, 2 Mar 2017 12:59:07 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ta1COAXw"; 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 :mime-version:in-reply-to:references:from:date:message-id :subject:to:content-type; q=dns; s=default; b=d6zcs95Ex87Axj6IC6 ltkSBDdXKA31l3ilKOhmtHVK9LUpk3vbxeJoyS2LTYzey4sXeFN0jP860pg6mOPU hFzeGJT3Nrhn7GPXBIkCDu4bNka7lFrqIWQ7a2x1floWH6EpigHW7NoHz/4xjm4N lO11WLrKVOEkEebtFFwc1t0sA= 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 :mime-version:in-reply-to:references:from:date:message-id :subject:to:content-type; s=default; bh=E+97S+zP4FOosYDG/d+fKg5G Dac=; b=ta1COAXwn0Rq3VIr39tQ19RMLUrbxTq0ldZihjJD4Fazt+RFggMBkloy 2JqCmR0DZHMgP3RO1YUZGFckojU7/dkdf66+6qI3DfCI7QXs5qtTBOyZ0YNNhroU duL56CZwSJWQxQvWEDn2ebZIhks1zMBhNtQdCeBsDNSgMsFDhgY= Received: (qmail 118285 invoked by alias); 2 Mar 2017 01:58:55 -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 117928 invoked by uid 89); 2 Mar 2017 01:58:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.4 required=5.0 tests=AWL, 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= X-HELO: mail-oi0-f49.google.com Received: from mail-oi0-f49.google.com (HELO mail-oi0-f49.google.com) (209.85.218.49) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 02 Mar 2017 01:58:48 +0000 Received: by mail-oi0-f49.google.com with SMTP id 2so32230811oif.0 for ; Wed, 01 Mar 2017 17:58:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=4BkcHFMYvgAD2Dtp4FsOKrqG7xOcgH8+wHkkR2O+tJE=; b=j2bGQ2EQE85fHzLXYoftpiBqgxVkB0Iz4AGk1BtXEol1dgnp/BxzuTTMfL99+cBtIT zF5cj4Uqdlv7O/iXkGkibwQ78dVxVD2NiL3iHrAci5fqjPKQlA5pPwlbU86ZT6qNgo3Y lWLOlmiUb3qRPgVAqCu/RTqseDSLZ60iugyxGHw8J9ksNmKf2ZrcWBPCdpO6jci8oa4Q 7C/jjrR4Eqh/v/zrW7W80mw2JOCOPBhUKCNFmHhvxw5A+mnkIC1o/QMhjd6yCbKK8Ahb p9sAqrPfb34Es8TGf/rXKKqrVUcdkfYdQ7JZN/BUqKav2gFWbwc2u8D4nK47hHEERvgP GgMQ== X-Gm-Message-State: AMke39nsQZhbbd886Zmzcp6pBnX2M8eLUS32LfxVQwHu1jb9YTz8rcFMXhhRjRDCQaWhTG1H+Z8oxOw6+loTF9vl X-Received: by 10.202.58.69 with SMTP id h66mr5371990oia.30.1488419926984; Wed, 01 Mar 2017 17:58:46 -0800 (PST) MIME-Version: 1.0 Received: by 10.182.187.8 with HTTP; Wed, 1 Mar 2017 17:58:26 -0800 (PST) In-Reply-To: References: From: Jason Merrill Date: Wed, 1 Mar 2017 15:58:26 -1000 Message-ID: Subject: Re: C++ PATCH for C++17 class template argument deduction issues To: gcc-patches List X-IsSubscribed: yes On Tue, Feb 28, 2017 at 1:56 PM, Jason Merrill wrote: > This patch implements some proposed resolutions to open issues with > C++17 class template argument deduction. And some more: commit 41e5f38da5699736eb02a5b9c65549799c288714 Author: Jason Merrill Date: Wed Mar 1 13:15:11 2017 -1000 Class template argument deduction in new-expression * init.c (build_new): Handle deduction from no initializer. * parser.c (cp_parser_new_expression): Don't require a single expression for class template deduction. * typeck2.c (cxx_incomplete_type_diagnostic): Fix diagnostic for class template placeholder. * pt.c (tsubst_copy) [TEMPLATE_DECL]: Handle dependent context. (tsubst_copy_and_build) [TEMPLATE_ID_EXPR]: Handle SCOPE_REF. (redeclare_class_template): Set TEMPLATE_TYPE_PARM_FOR_CLASS. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 7ded37e..191fe13 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3478,15 +3478,19 @@ build_new (vec **placement, tree type, tree nelts, if (type == error_mark_node) return error_mark_node; - if (nelts == NULL_TREE && vec_safe_length (*init) == 1 + if (nelts == NULL_TREE /* Don't do auto deduction where it might affect mangling. */ && (!processing_template_decl || at_function_scope_p ())) { tree auto_node = type_uses_auto (type); if (auto_node) { - tree d_init = (**init)[0]; - d_init = resolve_nondeduced_context (d_init, complain); + tree d_init = NULL_TREE; + if (vec_safe_length (*init) == 1) + { + d_init = (**init)[0]; + d_init = resolve_nondeduced_context (d_init, complain); + } type = do_auto_deduction (type, d_init, auto_node); } } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 50528e2..e684870 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -8228,7 +8228,8 @@ cp_parser_new_expression (cp_parser* parser) contain a new-initializer of the form ( assignment-expression )". Additionally, consistently with the spirit of DR 1467, we want to accept 'new auto { 2 }' too. */ - else if (type_uses_auto (type) + else if ((ret = type_uses_auto (type)) + && !CLASS_PLACEHOLDER_TEMPLATE (ret) && (vec_safe_length (initializer) != 1 || (BRACE_ENCLOSED_INITIALIZER_P ((*initializer)[0]) && CONSTRUCTOR_NELTS ((*initializer)[0]) != 1))) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ec9d53a..8144ca6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5732,6 +5732,9 @@ redeclare_class_template (tree type, tree parms, tree cons) gcc_assert (DECL_CONTEXT (parm) == NULL_TREE); DECL_CONTEXT (parm) = tmpl; } + + if (TREE_CODE (parm) == TYPE_DECL) + TEMPLATE_TYPE_PARM_FOR_CLASS (TREE_TYPE (parm)) = true; } // Cannot redeclare a class template with a different set of constraints. @@ -14638,6 +14641,15 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) have to substitute this with one having context `D'. */ tree context = tsubst (DECL_CONTEXT (t), args, complain, in_decl); + if (dependent_scope_p (context)) + { + /* When rewriting a constructor into a deduction guide, a + non-dependent name can become dependent, so memtmpl + becomes context::template memtmpl. */ + tree type = tsubst (TREE_TYPE (t), args, complain, in_decl); + return build_qualified_name (type, context, DECL_NAME (t), + /*template*/true); + } return lookup_field (context, DECL_NAME(t), 0, false); } else @@ -16621,6 +16633,14 @@ tsubst_copy_and_build (tree t, if (targs == error_mark_node) return error_mark_node; + if (TREE_CODE (templ) == SCOPE_REF) + { + tree name = TREE_OPERAND (templ, 1); + tree tid = lookup_template_function (name, targs); + TREE_OPERAND (templ, 1) = tid; + return templ; + } + if (variable_template_p (templ)) RETURN (lookup_and_finish_template_variable (templ, targs, complain)); @@ -25144,7 +25164,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags, type = TREE_TYPE (most_general_template (tmpl)); } - bool saw_default = false; + bool saw_ctor = false; bool saw_copy = false; if (CLASSTYPE_METHOD_VEC (type)) // FIXME cache artificial deduction guides @@ -25154,9 +25174,9 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags, tree guide = build_deduction_guide (fn, outer_args, complain); cands = ovl_cons (guide, cands); + saw_ctor = true; + tree parms = FUNCTION_FIRST_USER_PARMTYPE (fn); - if (sufficient_parms_p (parms)) - saw_default = true; if (parms && sufficient_parms_p (TREE_CHAIN (parms))) { tree pt = TREE_VALUE (parms); @@ -25167,7 +25187,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags, } } - if (!saw_default && args->length() == 0) + if (!saw_ctor && args->length() == 0) { tree guide = build_deduction_guide (type, outer_args, complain); cands = ovl_cons (guide, cands); diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 1e0354d..58a01c9 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -523,8 +523,14 @@ cxx_incomplete_type_diagnostic (location_t loc, const_tree value, case TEMPLATE_TYPE_PARM: if (is_auto (type)) - emit_diagnostic (diag_kind, loc, 0, - "invalid use of %"); + { + if (CLASS_PLACEHOLDER_TEMPLATE (type)) + emit_diagnostic (diag_kind, loc, 0, + "invalid use of placeholder %qT", type); + else + emit_diagnostic (diag_kind, loc, 0, + "invalid use of %qT", type); + } else emit_diagnostic (diag_kind, loc, 0, "invalid use of template type parameter %qT", type); diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction33.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction33.C new file mode 100644 index 0000000..d135031 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction33.C @@ -0,0 +1,13 @@ +// { dg-options -std=c++1z } + +template struct same; +template struct same {}; + +template struct A { }; +template struct B { B(T,T); }; + +int main() +{ + same*>(); + same*>(); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction34.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction34.C new file mode 100644 index 0000000..b035879 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction34.C @@ -0,0 +1,13 @@ +// { dg-options -std=c++1z } + +template +struct A +{ + template + static constexpr bool B = U(); + + template > + A(T, U); +}; + +A a (1,2); diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction35.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction35.C new file mode 100644 index 0000000..b0e53d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction35.C @@ -0,0 +1,10 @@ +// { dg-options -std=c++1z } + +template struct A; + +template struct A { + A(T&&); +}; + +int i; +A a = i; // { dg-error "" }