From patchwork Fri Feb 17 18:41:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 729265 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 3vQ21x4ZMYz9s7x for ; Sat, 18 Feb 2017 05:42:12 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="xJS4yoYi"; 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:from:date:message-id:subject:to:content-type; q= dns; s=default; b=Mmq8pSqoVnD1HfDOdxQ8Y0rhZ1Gh9OaL2MFZnGwuybdfYs jhM8EMvnEKSmWVtBjuqKSx0XweIaBoCdPXCzOV0l3mM/QJcQMCHtovDASfHXLbAt +9jJ1pV9FPYbgdUbfIMvDtIFgjrwTFtw6+PM5G5DUrkqRX6Z0zBGjtxwWsstU= 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:from:date:message-id:subject:to:content-type; s= default; bh=43IjjspeZ1ZfCC0YQY1kzJBiz+Q=; b=xJS4yoYiUOE2+tqHSihc hp9PwoVibbolVIEzs1bLua+7QZgZHGQLOR1ByVhXvyYxKRlFDsCYzVq1C1OqcCtF CDjKcrGjHH4A5n10c9z7H/T6lLw6oIiMw9ZeMYAsp9HLU0DR8cf0Tpr/rcupf+xG 6hUjYPpe1cdEFpmO37KE8vQ= Received: (qmail 881 invoked by alias); 17 Feb 2017 18:42:03 -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 870 invoked by uid 89); 17 Feb 2017 18:42:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.2 spammy=tmpl, packing, importantly X-HELO: mail-oi0-f46.google.com Received: from mail-oi0-f46.google.com (HELO mail-oi0-f46.google.com) (209.85.218.46) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 17 Feb 2017 18:42:01 +0000 Received: by mail-oi0-f46.google.com with SMTP id 62so15042138oih.2 for ; Fri, 17 Feb 2017 10:42:01 -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:from:date:message-id:subject:to; bh=edHUCOuaGucSH3/T8I8j/RgvecbN58HrPm5/d1Z/y7M=; b=TTkMMc+yOo3pPjy0j/F7oZYnb/x/JOgfNw6OGh4M63LuHK6FaMiISu3lVCT0Yv3ZhO c/eeSsGeljxvmTz1wWCD4o8iqzqeTKUpSYoXC+ZUh654c4EiPkbjbjX3p0WfURnT8KF8 ZDiYeNrUnMDnn1AiexJCuxbkSPz/U49iaiGhlwa0XqJB/5cD35dSsnELeVMakgA4ucan 71Nhs/VQR0BX8ypT5Ad7jjhXGnBO8wN0gkzNDrdvRn40x1xel+gsdzAVT/3xEBzpDbx/ +DLQMugvkFTQvlO9snYK6o6AZb5EoGU/HyOEZf6sLN6DUEoF+k/us8BXII2PE17TRt5X pU7w== X-Gm-Message-State: AMke39mfCVQF1Bsza1//xm4Q72n4mgL3KqRYC89k++kzFE3Vb6Ez6uUN11SSXFqfzenGL+uTuKBU1z6srAmn8IfP X-Received: by 10.202.58.69 with SMTP id h66mr4522895oia.30.1487356919444; Fri, 17 Feb 2017 10:41:59 -0800 (PST) MIME-Version: 1.0 Received: by 10.182.5.4 with HTTP; Fri, 17 Feb 2017 10:41:38 -0800 (PST) From: Jason Merrill Date: Fri, 17 Feb 2017 13:41:38 -0500 Message-ID: Subject: C++ PATCHes for c++/79549 and 79556 (ICE with auto parameter pack) To: gcc-patches List X-IsSubscribed: yes In 79556, we try to deduce an auto type from a dependent initializer with null TREE_TYPE, which doesn't work; fixed by catching that case in do_auto_deduction. In 79549, we try to tsubst into the type of a NONTYPE_ARGUMENT_PACK, which doesn't make sense for an auto parameter pack; in fact, it doesn't make sense for the argument pack to have a type at all. For GCC 7 I'm fixing this by leaving the auto type in place; for GCC 8 we'll do away with TREE_TYPE on all NONTYPE_ARGUMENT_PACKs. Tested x86_64-pc-linux-gnu, applying to trunk. commit d6e7709acaafa96813a2eed1ca7cb51f7f9847a8 Author: Jason Merrill Date: Thu Feb 16 17:24:19 2017 -0500 PR c++/79556 - C++17 ICE with non-type auto * pt.c (do_auto_deduction): Don't try to deduce from null type. commit 1eeb6fca6149f32f711ab2b404ce442c4a40b550 Author: Jason Merrill Date: Fri Feb 17 12:46:52 2017 -0500 PR c++/79549 - C++17 ICE with non-type auto template parameter pack * pt.c (convert_template_argument): Just return an auto arg pack. (tsubst_template_args): Don't tsubst an auto pack type. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 093c0f9..04479d4 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7612,6 +7612,10 @@ convert_template_argument (tree parm, if (tree a = type_uses_auto (t)) { + if (ARGUMENT_PACK_P (orig_arg)) + /* There's nothing to check for an auto argument pack. */ + return orig_arg; + t = do_auto_deduction (t, arg, a, complain, adc_unify, args); if (t == error_mark_node) return error_mark_node; @@ -11649,8 +11653,11 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) new_arg = error_mark_node; if (TREE_CODE (new_arg) == NONTYPE_ARGUMENT_PACK) { - TREE_TYPE (new_arg) = tsubst (TREE_TYPE (orig_arg), args, - complain, in_decl); + if (type_uses_auto (TREE_TYPE (orig_arg))) + TREE_TYPE (new_arg) = TREE_TYPE (orig_arg); + else + TREE_TYPE (new_arg) = tsubst (TREE_TYPE (orig_arg), args, + complain, in_decl); TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg); if (TREE_TYPE (new_arg) == error_mark_node) diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype-auto8.C b/gcc/testsuite/g++.dg/cpp1z/nontype-auto8.C new file mode 100644 index 0000000..da4c88b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nontype-auto8.C @@ -0,0 +1,10 @@ +// PR c++/79549 +// { dg-options -std=c++1z } + +template +struct meow; + +template +struct meow { }; + +meow<1> m; commit 677e35c07a536344ce8bb74e97a72ab05cdb4da4 Author: Jason Merrill Date: Thu Feb 16 16:31:26 2017 -0500 PR c++/79549 - C++17 ICE with non-type auto template parameter pack * pt.c (convert_template_argument): Just return an argument pack. (coerce_template_parameter_pack, template_parm_to_arg) (extract_fnparm_pack, make_argument_pack, tsubst_template_args) (tsubst_decl, tsubst, type_unification_real, unify_pack_expansion): Don't set the type of a NONTYPE_ARGUMENT_PACK. * parser.c (make_char_string_pack, make_string_pack): Likewise. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 060962d..7cba266 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4150,7 +4150,6 @@ make_char_string_pack (tree value) /* Build the argument packs. */ SET_ARGUMENT_PACK_ARGS (argpack, charvec); - TREE_TYPE (argpack) = char_type_node; TREE_VEC_ELT (argvec, 0) = argpack; @@ -4186,7 +4185,6 @@ make_string_pack (tree value) /* Build the argument packs. */ SET_ARGUMENT_PACK_ARGS (argpack, charvec); - TREE_TYPE (argpack) = str_char_type_node; TREE_VEC_ELT (argvec, 1) = argpack; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 04479d4..d04ebc1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4287,7 +4287,6 @@ template_parm_to_arg (tree t) /* Turn this argument into a NONTYPE_ARGUMENT_PACK with a single element, which expands T. */ tree vec = make_tree_vec (1); - tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t)); if (CHECKING_P) SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec)); @@ -4296,7 +4295,6 @@ template_parm_to_arg (tree t) t = make_node (NONTYPE_ARGUMENT_PACK); SET_ARGUMENT_PACK_ARGS (t, vec); - TREE_TYPE (t) = type; } else t = convert_from_reference (t); @@ -7528,13 +7526,14 @@ convert_template_argument (tree parm, return error_mark_node; } - if (is_type) + if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg)) + /* We already did the appropriate conversion when packing args. */ + val = orig_arg; + else if (is_type) { if (requires_tmpl_type) { - if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg)) - val = orig_arg; - else if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE) + if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE) /* The number of argument required is not known yet. Just accept it for now. */ val = TREE_TYPE (arg); @@ -7612,10 +7611,6 @@ convert_template_argument (tree parm, if (tree a = type_uses_auto (t)) { - if (ARGUMENT_PACK_P (orig_arg)) - /* There's nothing to check for an auto argument pack. */ - return orig_arg; - t = do_auto_deduction (t, arg, a, complain, adc_unify, args); if (t == error_mark_node) return error_mark_node; @@ -7626,20 +7621,8 @@ convert_template_argument (tree parm, if (invalid_nontype_parm_type_p (t, complain)) return error_mark_node; - if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg)) - { - if (same_type_p (t, TREE_TYPE (orig_arg))) - val = orig_arg; - else - { - /* Not sure if this is reachable, but it doesn't hurt - to be robust. */ - error ("type mismatch in nontype parameter pack"); - val = error_mark_node; - } - } - else if (!type_dependent_expression_p (orig_arg) - && !uses_template_parms (t)) + if (!type_dependent_expression_p (orig_arg) + && !uses_template_parms (t)) /* We used to call digest_init here. However, digest_init will report errors, which we don't want when complain is zero. More importantly, digest_init will try too @@ -7820,8 +7803,6 @@ coerce_template_parameter_pack (tree parms, else { argument_pack = make_node (NONTYPE_ARGUMENT_PACK); - TREE_TYPE (argument_pack) - = tsubst (TREE_TYPE (TREE_VALUE (parm)), new_args, complain, in_decl); TREE_CONSTANT (argument_pack) = 1; } @@ -10802,9 +10783,7 @@ extract_fnparm_pack (tree tmpl_parm, tree *spec_p) /* Collect all of the extra "packed" parameters into an argument pack. */ tree parmvec; - tree parmtypevec; tree argpack = make_node (NONTYPE_ARGUMENT_PACK); - tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK); tree spec_parm = *spec_p; int i, len; @@ -10815,18 +10794,12 @@ extract_fnparm_pack (tree tmpl_parm, tree *spec_p) /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ parmvec = make_tree_vec (len); - parmtypevec = make_tree_vec (len); spec_parm = *spec_p; for (i = 0; i < len; i++, spec_parm = DECL_CHAIN (spec_parm)) - { - TREE_VEC_ELT (parmvec, i) = spec_parm; - TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm); - } + TREE_VEC_ELT (parmvec, i) = spec_parm; /* Build the argument packs. */ SET_ARGUMENT_PACK_ARGS (argpack, parmvec); - SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec); - TREE_TYPE (argpack) = argtypepack; *spec_p = spec_parm; return argpack; @@ -11568,7 +11541,6 @@ make_argument_pack (tree vec) else { pack = make_node (NONTYPE_ARGUMENT_PACK); - TREE_TYPE (pack) = TREE_TYPE (elt); TREE_CONSTANT (pack) = 1; } SET_ARGUMENT_PACK_ARGS (pack, vec); @@ -11643,26 +11615,16 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) new_arg = TYPE_P (orig_arg) ? cxx_make_type (TREE_CODE (orig_arg)) : make_node (TREE_CODE (orig_arg)); - - SET_ARGUMENT_PACK_ARGS ( - new_arg, - tsubst_template_args (ARGUMENT_PACK_ARGS (orig_arg), - args, complain, in_decl)); - if (ARGUMENT_PACK_ARGS (new_arg) == error_mark_node) + tree pack_args = tsubst_template_args (ARGUMENT_PACK_ARGS (orig_arg), + args, complain, in_decl); + if (pack_args == error_mark_node) new_arg = error_mark_node; + else + SET_ARGUMENT_PACK_ARGS (new_arg, pack_args); - if (TREE_CODE (new_arg) == NONTYPE_ARGUMENT_PACK) { - if (type_uses_auto (TREE_TYPE (orig_arg))) - TREE_TYPE (new_arg) = TREE_TYPE (orig_arg); - else - TREE_TYPE (new_arg) = tsubst (TREE_TYPE (orig_arg), args, - complain, in_decl); - TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg); - - if (TREE_TYPE (new_arg) == error_mark_node) - new_arg = error_mark_node; - } + if (TREE_CODE (new_arg) == NONTYPE_ARGUMENT_PACK) + TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg); } else new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl); @@ -12606,10 +12568,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) { r = vec; tree pack = make_node (NONTYPE_ARGUMENT_PACK); - tree tpack = cxx_make_type (TYPE_ARGUMENT_PACK); SET_ARGUMENT_PACK_ARGS (pack, vec); - SET_ARGUMENT_PACK_ARGS (tpack, expanded_types); - TREE_TYPE (pack) = tpack; register_specialization (pack, t, args, false, 0); } } @@ -14081,11 +14040,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree r; if (code == NONTYPE_ARGUMENT_PACK) - { - r = make_node (code); - /* Set the already-substituted type. */ - TREE_TYPE (r) = type; - } + r = make_node (code); else r = cxx_make_type (code); @@ -19222,7 +19177,6 @@ type_unification_real (tree tparms, if (TREE_CODE (tparm) == TEMPLATE_PARM_INDEX) { arg = make_node (NONTYPE_ARGUMENT_PACK); - TREE_TYPE (arg) = TREE_TYPE (TEMPLATE_PARM_DECL (tparm)); TREE_CONSTANT (arg) = 1; } else @@ -20019,8 +19973,6 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, if (TREE_CODE (TREE_PURPOSE (pack)) == TEMPLATE_PARM_INDEX) { result = make_node (NONTYPE_ARGUMENT_PACK); - TREE_TYPE (result) = - TREE_TYPE (TEMPLATE_PARM_DECL (TREE_PURPOSE (pack))); TREE_CONSTANT (result) = 1; } else diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 73d6be3..093c0f9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -25191,6 +25191,10 @@ do_auto_deduction (tree type, tree init, tree auto_node, /* C++17 class template argument deduction. */ return do_class_deduction (type, tmpl, init, flags, complain); + if (TREE_TYPE (init) == NULL_TREE) + /* Nothing we can do with this, even in deduction context. */ + return type; + /* [dcl.spec.auto]: Obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list (8.5.4), with diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype-auto9.C b/gcc/testsuite/g++.dg/cpp1z/nontype-auto9.C new file mode 100644 index 0000000..2daa346 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nontype-auto9.C @@ -0,0 +1,8 @@ +// PR c++/79556 +// { dg-options -std=c++1z } + +template struct A; +template struct B; +template struct B { + static auto a = A::value>::value; +};