From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 52940 invoked by alias); 17 Jan 2020 03:22:26 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 52833 invoked by uid 89); 17 Jan 2020 03:22:19 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.2 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.1 spammy=fn1 X-HELO: us-smtp-delivery-1.mimecast.com Received: from us-smtp-1.mimecast.com (HELO us-smtp-delivery-1.mimecast.com) (205.139.110.61) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 17 Jan 2020 03:22:17 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1579231335; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=reNZBg0CnlpBKLkOlkW82XfDy7yvDQ37p94AyZmT9/0=; b=dXtouXaTdcDxy/t+dqbQPPr2zaSm1ByMPiy2LbCP4cZlbAYNbLRa7dPr/mECqmiCJvmvIU UUH8ogSDEPqpqYsbIy6QNHPk7tyCU342WPncz9bD/B9IMn7/VXWmRsTnZ959Bmcu4ewGDX 6eGPcqok1BWiZNBM7bkJEZ0g9uy5ALA= Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-142-dd1ln1JsPGyJLdvNLmNuMQ-1; Thu, 16 Jan 2020 22:22:13 -0500 Received: by mail-qk1-f198.google.com with SMTP id f124so14495584qkb.22 for ; Thu, 16 Jan 2020 19:22:13 -0800 (PST) Return-Path: Received: from barrymore.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 l184sm11266631qkc.107.2020.01.16.19.22.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jan 2020 19:22:10 -0800 (PST) From: Jason Merrill To: gcc-patches@gcc.gnu.org Subject: [C++ PATCH] PR c++/93286 - ICE with __is_constructible and variadic template. Date: Fri, 17 Jan 2020 07:03:00 -0000 Message-Id: <20200117032209.3077-1-jason@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2020-01/txt/msg01010.txt.bz2 Here we had been recursing in tsubst_copy_and_build if type2 was a TREE_LIST because that function knew how to deal with pack expansions, and tsubst didn't. But tsubst_copy_and_build expects to be dealing with expressions, so we crash when trying to convert_from_reference a type. Tested x86_64-pc-linux-gnu, applying to trunk. * pt.c (tsubst) [TREE_LIST]: Handle pack expansion. (tsubst_copy_and_build) [TRAIT_EXPR]: Always use tsubst for type2. --- gcc/cp/pt.c | 74 ++++++++++++++++++-- gcc/testsuite/g++.dg/ext/is_constructible4.C | 18 +++++ 2 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/is_constructible4.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9bb8cc13e5f..872f8ff8f52 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -15350,6 +15350,71 @@ tsubst (tree t, tree args, tsubst_flags_t complain= , tree in_decl) if (t =3D=3D void_list_node) return t; =20 + if ((TREE_PURPOSE (t) && PACK_EXPANSION_P (TREE_PURPOSE (t))) + || (TREE_VALUE (t) && PACK_EXPANSION_P (TREE_VALUE (t)))) + { + /* We have pack expansions, so expand those and + create a new list out of it. */ + + /* Expand the argument expressions. */ + tree purposevec =3D NULL_TREE; + if (TREE_PURPOSE (t)) + purposevec =3D tsubst_pack_expansion (TREE_PURPOSE (t), args, + complain, in_decl); + if (purposevec =3D=3D error_mark_node) + return error_mark_node; + + tree valuevec =3D NULL_TREE; + if (TREE_VALUE (t)) + valuevec =3D tsubst_pack_expansion (TREE_VALUE (t), args, + complain, in_decl); + if (valuevec =3D=3D error_mark_node) + return error_mark_node; + + /* Build the rest of the list. */ + tree chain =3D TREE_CHAIN (t); + if (chain && chain !=3D void_type_node) + chain =3D tsubst (chain, args, complain, in_decl); + if (chain =3D=3D error_mark_node) + return error_mark_node; + + /* Determine the number of arguments. */ + int len =3D -1; + if (purposevec && TREE_CODE (purposevec) =3D=3D TREE_VEC) + { + len =3D TREE_VEC_LENGTH (purposevec); + gcc_assert (!valuevec || len =3D=3D TREE_VEC_LENGTH (valuevec)); + } + else if (TREE_CODE (valuevec) =3D=3D TREE_VEC) + len =3D TREE_VEC_LENGTH (valuevec); + else + { + /* Since we only performed a partial substitution into + the argument pack, we only RETURN (a single list + node. */ + if (purposevec =3D=3D TREE_PURPOSE (t) + && valuevec =3D=3D TREE_VALUE (t) + && chain =3D=3D TREE_CHAIN (t)) + return t; + + return tree_cons (purposevec, valuevec, chain); + } + + /* Convert the argument vectors into a TREE_LIST. */ + for (int i =3D len; i-- > 0; ) + { + purpose =3D (purposevec ? TREE_VEC_ELT (purposevec, i) + : NULL_TREE); + value =3D (valuevec ? TREE_VEC_ELT (valuevec, i) + : NULL_TREE); + + /* Build the list (backwards). */ + chain =3D hash_tree_cons (purpose, value, chain); + } + + return chain; + } + purpose =3D TREE_PURPOSE (t); if (purpose) { @@ -20158,13 +20223,8 @@ tsubst_copy_and_build (tree t, { tree type1 =3D tsubst (TRAIT_EXPR_TYPE1 (t), args, complain, in_decl); - - tree type2 =3D TRAIT_EXPR_TYPE2 (t); - if (type2 && TREE_CODE (type2) =3D=3D TREE_LIST) - type2 =3D RECUR (type2); - else if (type2) - type2 =3D tsubst (type2, args, complain, in_decl); - + tree type2 =3D tsubst (TRAIT_EXPR_TYPE2 (t), args, + complain, in_decl); RETURN (finish_trait_expr (TRAIT_EXPR_LOCATION (t), TRAIT_EXPR_KIND (t), type1, type2)); } diff --git a/gcc/testsuite/g++.dg/ext/is_constructible4.C b/gcc/testsuite/g= ++.dg/ext/is_constructible4.C new file mode 100644 index 00000000000..6dfe3c01661 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_constructible4.C @@ -0,0 +1,18 @@ +// PR c++/93286 +// { dg-do compile { target c++14 } } + +struct A { static const bool value =3D true; }; +template using __bool_constant =3D A; +template +struct B : __bool_constant<__is_constructible(int, _Args...)> {}; +template using enable_if_t =3D int; +template bool is_constructible_v =3D B<_Args...>::valu= e; +class C { + template = >> + C(_Tp &&); +}; +using Effect_t =3D C; +void fn1(Effect_t effect) { + int i; + [](int &effect) {}(i); +} base-commit: 801f5b96775288e55193a66a746caab1ddd56f4a --=20 2.18.1