From patchwork Thu Sep 7 01:01:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 810835 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-461651-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="rK9QDI9h"; 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 3xnhy06Hv4z9sCZ for ; Thu, 7 Sep 2017 11:02:31 +1000 (AEST) 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=tjxuWXsFdRtkxMuug47zRqRskMcwR53Bnp6zLZ8E1n4qwy Z7G1QEgNbW/10ZAPVhGimoksE9I92+Uw/fRvgRZgYRT8K95ldB2XZlAcgsq8QHJN uivZ68jHcsDy7QqWFvkac87oiPVzmb4UpHHsyNPI2Sn7Ad0rNYYDIUz5SKzfU= 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=nzjRUKF00SWTf/vhBnqHbRaoVTY=; b=rK9QDI9hwx2vXi9v5Qhb L01eEjj85vs/5mAqHzRKzGALdzNzsHjlXu+KroRApyFvGuPJFyeR7gC3huopekJ9 sCQ6bT1Z27n5VAmk3c0ab0Lwikz2QvtFniGZo5HCzEdii69JhCojE5JTHBGsugOz 2i5ZxM9ZnAAvapTHIw5qCOs= Received: (qmail 115200 invoked by alias); 7 Sep 2017 01:02:23 -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 115188 invoked by uid 89); 7 Sep 2017 01:02:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.2 spammy=lam, 119316 X-HELO: mail-it0-f52.google.com Received: from mail-it0-f52.google.com (HELO mail-it0-f52.google.com) (209.85.214.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 07 Sep 2017 01:02:21 +0000 Received: by mail-it0-f52.google.com with SMTP id o200so531087itg.0 for ; Wed, 06 Sep 2017 18:02:21 -0700 (PDT) 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=M2Y/qHb72ccZsB9+WIcRFa12fXBcYX1dCt2BCpwibag=; b=YAcdEpcuHLg9JgXUXoSR1P5U1SimwoaUy2+HQxVd/7y7Z3s3tOv0+f+ujV4g08Jd0n LnhqRTHLKLdkDOfxPzignQIoSCORdG9Q25yuPMN9EiyydRHqFL9Zx+AzwwRi2yGNTgFG ogf6xt4gUNfJWL3JRl5NmiRRg30KG1BxRwg+KRRRRDh1GO0hYglG1iIpkyDA8KTSSEQQ 7o3TZjV54pjKLfr5jhxqlAvLCoWOyBYt7o75drBz3C730z4P3HRho9UWFTjv7UMc+JwW uLTsNDKsYiqmJQYzDEnY4EJDI2dPCzEao5qmnUyGPd/+f2Hub91A7TcynZKh9NikWRTg 6dFg== X-Gm-Message-State: AHPjjUj3RYC3YB0UbBE4yfr/kTbxLgWafaW6JGDnOy5ARDz8oF/hoZSm 4dJ8yU21I6ON7hDn45l5MIIB/LEQ/QZ6SJw= X-Google-Smtp-Source: ADKCNb7PGlvTPlRNkxakXNNUuRrZCzlbchzTinar9VGQ23RBR8E/K3JdjrlkagHaqRpd2UNCXybUu/K9EojbwUUMhsY= X-Received: by 10.36.216.8 with SMTP id b8mr2097733itg.55.1504746139257; Wed, 06 Sep 2017 18:02:19 -0700 (PDT) MIME-Version: 1.0 Received: by 10.107.181.23 with HTTP; Wed, 6 Sep 2017 18:01:58 -0700 (PDT) From: Jason Merrill Date: Wed, 6 Sep 2017 21:01:58 -0400 Message-ID: Subject: C++ PATCH for c++/82053, ICE with default argument in lambda in template To: gcc-patches List X-IsSubscribed: yes When we regenerate a lambda, the resulting op() doesn't have any template information, so we can't delay instantiating default arguments like we do for a normal template function. I believe this is also the direction of the core working group for default arguments in local extern function declarations, so I don't think we need to invent a mechanism to remember those template arguments for later use. Tested x86_64-pc-linux-gnu, applying to trunk. commit 17d672e6eaf10f96174b00207c60b5467693877f Author: Jason Merrill Date: Thu Aug 31 13:03:31 2017 -0400 PR c++/82053 - ICE with default argument in lambda in template * pt.c (tsubst_arg_types): Substitute default arguments for lambdas in templates. (retrieve_specialization): Use lambda_fn_in_template_p. * cp-tree.h: Declare it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 20fa039..a0e31d3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6821,6 +6821,7 @@ extern tree current_nonlambda_function (void); extern tree nonlambda_method_basetype (void); extern tree current_nonlambda_scope (void); extern bool generic_lambda_fn_p (tree); +extern bool lambda_fn_in_template_p (tree); extern void maybe_add_lambda_conv_op (tree); extern bool is_lambda_ignored_entity (tree); extern bool lambda_static_thunk_p (tree); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4a65e31..ec7bbc8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1193,16 +1193,8 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash) /* Lambda functions in templates aren't instantiated normally, but through tsubst_lambda_expr. */ - if (LAMBDA_FUNCTION_P (tmpl)) - { - bool generic = PRIMARY_TEMPLATE_P (tmpl); - if (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)) > generic) - return NULL_TREE; - - /* But generic lambda functions are instantiated normally, once their - containing context is fully instantiated. */ - gcc_assert (generic); - } + if (lambda_fn_in_template_p (tmpl)) + return NULL_TREE; if (optimize_specialization_lookup_p (tmpl)) { @@ -12579,7 +12571,7 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain, bool lambda_fn_in_template_p (tree fn) { - if (!LAMBDA_FUNCTION_P (fn)) + if (!fn || !LAMBDA_FUNCTION_P (fn)) return false; tree closure = DECL_CONTEXT (fn); return CLASSTYPE_TEMPLATE_INFO (closure) != NULL_TREE; @@ -13248,6 +13240,13 @@ tsubst_arg_types (tree arg_types, done in build_over_call. */ default_arg = TREE_PURPOSE (arg_types); + /* Except that we do substitute default arguments under tsubst_lambda_expr, + since the new op() won't have any associated template arguments for us + to refer to later. */ + if (lambda_fn_in_template_p (in_decl)) + default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl, + false/*fn*/, false/*constexpr*/); + if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG) { /* We've instantiated a template before its default arguments diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-defarg7.C b/gcc/testsuite/g++.dg/cpp1y/lambda-defarg7.C new file mode 100644 index 0000000..f67dfee --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-defarg7.C @@ -0,0 +1,13 @@ +// PR c++/82053 +// { dg-do compile { target c++14 } } + +template +int fn() { return 42; } + +template +auto lam = [](int = fn()){}; + +int main() +{ + lam(); +}