From patchwork Tue Feb 13 14:07:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 872859 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-473156-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="M+xLkL5S"; 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 3zgkrl4rGKz9t5w for ; Wed, 14 Feb 2018 01:07:50 +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 :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=U3J2By53NflVKRDfyjUXZdItkn0hUqukedTpzyJGjs4IFb pCluHeKnLuIK1cq/XccxA8RLuVZE/y/eFW5q4hyNL8ZR3oh7JYsSZcWPZ/hs8Wmh MbU+QSMzZ4UlHkqKLdu4qPcr76p+yCzUkyoTTmEXHg7m2V3ONMOgX3hFm2S/I= 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=khaaiXujyTjka3qZBgMyGU2qux0=; b=M+xLkL5S/dIOeNO7dwM0 ohfE+oumUs5BtmUemwWL0cbbDAWJCpqg0QyeMXbAw8UIkxyPJTmeZIQ0fjSBbQXp FcHSZchIDVY5K22DrJTMhXuCsQ2Br4ISHKv3fJMAXJXKcLozuysZvQOY7wk82DNy K0qRsMf4cNxCbB6bj8a69P4= Received: (qmail 16961 invoked by alias); 13 Feb 2018 14:07:42 -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 16949 invoked by uid 89); 13 Feb 2018 14:07:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.3 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=consisting X-HELO: mail-io0-f169.google.com Received: from mail-io0-f169.google.com (HELO mail-io0-f169.google.com) (209.85.223.169) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Feb 2018 14:07:40 +0000 Received: by mail-io0-f169.google.com with SMTP id p188so21368916ioe.12 for ; Tue, 13 Feb 2018 06:07:40 -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=OdP/6FoS8tbwer2RC4zGwsl1IwVkuWFPUSeEyMJ4MeU=; b=DeQuDJXgk+Ql+Zh+kl3RKxurPVNhibSQ/n3+ntTnhJUAoZWxBze+PuzqcNdlIUThPY Q8y9I3b7Yfk1xvE9E0SR8zeC2O8QwHqHFFnBOyhmeAXWygXJgHXvRebDyAvuJ8e7RBDL m7v0jiLkT32uf/grTxFwrNnuokbLIcZohTwqHAewfApiP6CrlykoO7S8SelUO1HVGJxr 3GAq3CRtyRza+F1CxVHRFheigSpeMhT3zYuGAL4VEG7WlV88Dn8S0TSRCbCuf4u6iwtz lv1ZvEHgGE+Dl7U9+wfkUsisYkHYHQE2jk8mnqhiT8LRC10izkl1ewDuNz2vXwyd5oZk Uf8w== X-Gm-Message-State: APf1xPD2loHnhz4kLPsl6smYeKoLC+oerLEWCWMktHzgO7H2iFzl4rz8 m/iVQG83MhpFP7CmT3PBHbRpKgIa9VEvYHldvo3+IiIj X-Google-Smtp-Source: AH8x226v7j3+5fP5jSlFuC+c5CfI7KlL4W06YmnaBX/2ASCfHYuCyW5VQul7lj36vUTnyDmEQ4Xk/LO5ShSdJr9I4fk= X-Received: by 10.107.175.77 with SMTP id y74mr1427548ioe.37.1518530858286; Tue, 13 Feb 2018 06:07:38 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.17.206 with HTTP; Tue, 13 Feb 2018 06:07:17 -0800 (PST) From: Jason Merrill Date: Tue, 13 Feb 2018 09:07:17 -0500 Message-ID: Subject: C++ PATCH for c++/84338, wrong variadic sizeof To: gcc-patches List X-IsSubscribed: yes Here sizeof... was improperly being resolved early on an argument pack consisting of a single pack expansion, when the sizeof... is still dependent. This turned out to be because of our handling of partial instantiation of a function parameter pack: I had previously changed extract_fnparm_pack to wrap such a partially instantiated pack in an EXPR_PACK_EXPANSION, but later reverted that because it was breaking things. That breakage turns out to have been because the uses of ARGUMENT_PACK_EXTRACT_ARG for PARM_DECL and VAR_DECL were missing the code to strip a pack expansion that we had for template parameters; moving all of that into a function rather than a macro fixed that, and so now we can wrap the parameter pack again, which fixes the testcase. Tested x86_64-pc-linux-gnu, applying to trunk. commit 0978de34113258d973e3a78dad466c3d602a9130 Author: Jason Merrill Date: Mon Feb 12 17:04:56 2018 -0500 PR c++/84338 - wrong variadic sizeof. * pt.c (argument_pack_select_arg): Like the macro, but look through a pack expansion. (tsubst, tsubst_copy, dependent_template_arg_p): Use it. (extract_fnparm_pack): Do make_pack_expansion. (extract_locals_r): Do strip a pack expansion. * cp-tree.h (ARGUMENT_PACK_SELECT_ARG): Remove. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a6c75aed33d..9a9e9f0bbcb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3558,12 +3558,6 @@ extern void decl_shadowed_for_var_insert (tree, tree); #define ARGUMENT_PACK_SELECT_INDEX(NODE) \ (((struct tree_argument_pack_select *)ARGUMENT_PACK_SELECT_CHECK (NODE))->index) -/* In an ARGUMENT_PACK_SELECT, the actual underlying argument that the - ARGUMENT_PACK_SELECT represents. */ -#define ARGUMENT_PACK_SELECT_ARG(NODE) \ - TREE_VEC_ELT (ARGUMENT_PACK_ARGS (ARGUMENT_PACK_SELECT_FROM_PACK (NODE)), \ - ARGUMENT_PACK_SELECT_INDEX (NODE)) - #define FOLD_EXPR_CHECK(NODE) \ TREE_CHECK4 (NODE, UNARY_LEFT_FOLD_EXPR, UNARY_RIGHT_FOLD_EXPR, \ BINARY_LEFT_FOLD_EXPR, BINARY_RIGHT_FOLD_EXPR) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b58c60f0dcb..a83b7073d20 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3394,6 +3394,34 @@ get_template_argument_pack_elems (const_tree t) return ARGUMENT_PACK_ARGS (t); } +/* In an ARGUMENT_PACK_SELECT, the actual underlying argument that the + ARGUMENT_PACK_SELECT represents. */ + +static tree +argument_pack_select_arg (tree t) +{ + tree args = ARGUMENT_PACK_ARGS (ARGUMENT_PACK_SELECT_FROM_PACK (t)); + tree arg = TREE_VEC_ELT (args, ARGUMENT_PACK_SELECT_INDEX (t)); + + /* If the selected argument is an expansion E, that most likely means we were + called from gen_elem_of_pack_expansion_instantiation during the + substituting of an argument pack (of which the Ith element is a pack + expansion, where I is ARGUMENT_PACK_SELECT_INDEX) into a pack expansion. + In this case, the Ith element resulting from this substituting is going to + be a pack expansion, which pattern is the pattern of E. Let's return the + pattern of E, and gen_elem_of_pack_expansion_instantiation will build the + resulting pack expansion from it. */ + if (PACK_EXPANSION_P (arg)) + { + /* Make sure we aren't throwing away arg info. */ + gcc_assert (!PACK_EXPANSION_EXTRA_ARGS (arg)); + arg = PACK_EXPANSION_PATTERN (arg); + } + + return arg; +} + + /* True iff FN is a function representing a built-in variadic parameter pack. */ @@ -10933,7 +10961,12 @@ extract_fnparm_pack (tree tmpl_parm, tree *spec_p) parmvec = 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 elt = spec_parm; + if (DECL_PACK_P (elt)) + elt = make_pack_expansion (elt); + TREE_VEC_ELT (parmvec, i) = elt; + } /* Build the argument packs. */ SET_ARGUMENT_PACK_ARGS (argpack, parmvec); @@ -11388,7 +11421,8 @@ extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data) /* Pull out the actual PARM_DECL for the partial instantiation. */ tree args = ARGUMENT_PACK_ARGS (spec); gcc_assert (TREE_VEC_LENGTH (args) == 1); - spec = TREE_VEC_ELT (args, 0); + tree arg = TREE_VEC_ELT (args, 0); + spec = PACK_EXPANSION_PATTERN (arg); } *extra = tree_cons (*tp, spec, *extra); } @@ -13747,29 +13781,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { arg = TMPL_ARG (args, level, idx); + /* See through ARGUMENT_PACK_SELECT arguments. */ if (arg && TREE_CODE (arg) == ARGUMENT_PACK_SELECT) - { - /* See through ARGUMENT_PACK_SELECT arguments. */ - arg = ARGUMENT_PACK_SELECT_ARG (arg); - /* If the selected argument is an expansion E, that most - likely means we were called from - gen_elem_of_pack_expansion_instantiation during the - substituting of pack an argument pack (which Ith - element is a pack expansion, where I is - ARGUMENT_PACK_SELECT_INDEX) into a pack expansion. - In this case, the Ith element resulting from this - substituting is going to be a pack expansion, which - pattern is the pattern of E. Let's return the - pattern of E, and - gen_elem_of_pack_expansion_instantiation will - build the resulting pack expansion from it. */ - if (PACK_EXPANSION_P (arg)) - { - /* Make sure we aren't throwing away arg info. */ - gcc_assert (!PACK_EXPANSION_EXTRA_ARGS (arg)); - arg = PACK_EXPANSION_PATTERN (arg); - } - } + arg = argument_pack_select_arg (arg); } if (arg == error_mark_node) @@ -14734,7 +14748,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) } if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) - r = ARGUMENT_PACK_SELECT_ARG (r); + r = argument_pack_select_arg (r); if (!mark_used (r, complain) && !(complain & tf_error)) return error_mark_node; return r; @@ -14866,7 +14880,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) register_local_specialization (r, t); } if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) - r = ARGUMENT_PACK_SELECT_ARG (r); + r = argument_pack_select_arg (r); } else r = t; @@ -24701,7 +24715,7 @@ dependent_template_arg_p (tree arg) return true; if (TREE_CODE (arg) == ARGUMENT_PACK_SELECT) - arg = ARGUMENT_PACK_SELECT_ARG (arg); + arg = argument_pack_select_arg (arg); if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) return true; diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic13.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic13.C new file mode 100644 index 00000000000..92fd34cb268 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic13.C @@ -0,0 +1,15 @@ +// PR c++/84338 +// { dg-do compile { target c++14 } } + +template < typename ... T > +auto f(T ... i){ + [](auto ... i){ + // // wrongly true in current trunk + // static_assert(sizeof...(i) == 1, ""); + static_assert(sizeof...(i) == 2, ""); + }(i ...); +} + +int main(){ + f(0, 1); +}