From patchwork Fri Jun 1 16:50:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 162359 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]) by ozlabs.org (Postfix) with SMTP id B639CB7003 for ; Sat, 2 Jun 2012 04:06:36 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1339178798; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=pw+gs/f vKR7yrFFoeFlJ/APw4XU=; b=Erivo/NupMgjGjgF+NJ7zt7bdBBCb182aLHLI0h e3fguVk4jTkfHAtWGsw8ACGVLI5z04VAoE7l2Bqn2dEWOlB2Rv37xYWJeyGA8H3t Q5HqeUz5aCMjuiurOFFZqJsgP3QPKmz/OP1p7NM0ARtbn+mYqHd+2CpjCrG8wIBv 0hzo= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=KQbnGKdqFtQZJ2uT1f+F7WkzhOZi8G0Sjn215remZLxrhDmBknOLvNaxBfR4Pc aYvUSX5t6Yg620JcGRY/QS4NXCECyFiy86jOoCBPxK36CSz1TcOio8wfmDmRx6JU r7JUtrFLYphc8mW+ZFQx99CrjSn/ikb9PPQhHtdzi/EVI=; Received: (qmail 8223 invoked by alias); 1 Jun 2012 18:06:19 -0000 Received: (qmail 8141 invoked by uid 22791); 1 Jun 2012 18:06:17 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 01 Jun 2012 18:05:51 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q51I5WQP023123 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 1 Jun 2012 14:05:51 -0400 Received: from [10.3.112.46] (ovpn-112-46.phx2.redhat.com [10.3.112.46]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q51GopQB004735 for ; Fri, 1 Jun 2012 12:50:52 -0400 Message-ID: <4FC8F2EA.4010001@redhat.com> Date: Fri, 01 Jun 2012 12:50:50 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20120430 Thunderbird/12.0.1 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/53137 (ICE with lambda in template) 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 In 4.7, this is one bug: we are doing a push_to_top_level to instantiate the lambda, and then not pushing back into the function scope that the lambda belongs to. Fixed by following the lead of synthesize_method and only doing push_function_context if we're dealing with a local class. On the trunk, after that issue was fixed I also had to fix our handling of 'this' capture in template lambdas after my work on return type deduction for arbitrary functions. Tested x86_64-pc-linux-gnu, applying to trunk and 4.7. commit 1409620970858e91fc55f90935e724b511f98d6c Author: Jason Merrill Date: Thu May 31 17:25:52 2012 -0400 PR c++/53137 * pt.c (instantiate_class_template_1): Set LAMBDA_EXPR_THIS_CAPTURE. (instantiate_decl): Don't push_to_top_level for local class methods. (instantiate_class_template_1): Or for local classes. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b58dd13..4d4e8ad 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8698,6 +8698,7 @@ instantiate_class_template_1 (tree type) tree pbinfo; tree base_list; unsigned int saved_maximum_field_alignment; + tree fn_context; if (type == error_mark_node) return error_mark_node; @@ -8756,7 +8757,9 @@ instantiate_class_template_1 (tree type) it now. */ push_deferring_access_checks (dk_no_deferred); - push_to_top_level (); + fn_context = decl_function_context (TYPE_MAIN_DECL (type)); + if (!fn_context) + push_to_top_level (); /* Use #pragma pack from the template context. */ saved_maximum_field_alignment = maximum_field_alignment; maximum_field_alignment = TYPE_PRECISION (pattern); @@ -9154,8 +9157,14 @@ instantiate_class_template_1 (tree type) tree decl = lambda_function (type); if (decl) { + tree lam = CLASSTYPE_LAMBDA_EXPR (type); + LAMBDA_EXPR_THIS_CAPTURE (lam) + = lookup_field_1 (type, get_identifier ("__this"), false); + instantiate_decl (decl, false, false); maybe_add_lambda_conv_op (type); + + LAMBDA_EXPR_THIS_CAPTURE (lam) = NULL_TREE; } else gcc_assert (errorcount); @@ -9186,7 +9195,8 @@ instantiate_class_template_1 (tree type) perform_deferred_access_checks (); pop_nested_class (); maximum_field_alignment = saved_maximum_field_alignment; - pop_from_top_level (); + if (!fn_context) + pop_from_top_level (); pop_deferring_access_checks (); pop_tinst_level (); @@ -18435,9 +18445,10 @@ instantiate_decl (tree d, int defer_ok, tree spec; tree gen_tmpl; bool pattern_defined; - int need_push; location_t saved_loc = input_location; bool external_p; + tree fn_context; + bool nested; /* This function should only be used to instantiate templates for functions and static member variables. */ @@ -18672,9 +18683,12 @@ instantiate_decl (tree d, int defer_ok, goto out; } - need_push = !cfun || !global_bindings_p (); - if (need_push) + fn_context = decl_function_context (d); + nested = (current_function_decl != NULL_TREE); + if (!fn_context) push_to_top_level (); + else if (nested) + push_function_context (); /* Mark D as instantiated so that recursive calls to instantiate_decl do not try to instantiate it again. */ @@ -18784,8 +18798,10 @@ instantiate_decl (tree d, int defer_ok, /* We're not deferring instantiation any more. */ TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0; - if (need_push) + if (!fn_context) pop_from_top_level (); + else if (nested) + pop_function_context (); out: input_location = saved_loc; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C new file mode 100644 index 0000000..b91b89f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C @@ -0,0 +1,17 @@ +// PR c++/53137 +// { dg-do compile { target c++11 } } + +struct A +{ + template void f(); + + template void g() + { + [this]{ f(); }(); + } + + void h() + { + g(); + } +};