From patchwork Sat May 28 00:52:20 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 97763 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 72C75B6F91 for ; Sat, 28 May 2011 10:52:46 +1000 (EST) Received: (qmail 12535 invoked by alias); 28 May 2011 00:52:43 -0000 Received: (qmail 12524 invoked by uid 22791); 28 May 2011 00:52:41 -0000 X-SWARE-Spam-Status: No, hits=-6.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, 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; Sat, 28 May 2011 00:52:22 +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 p4S0qLC8014416 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 27 May 2011 20:52:21 -0400 Received: from [127.0.0.1] (ovpn-113-23.phx2.redhat.com [10.3.113.23]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p4S0qKLX014760 for ; Fri, 27 May 2011 20:52:21 -0400 Message-ID: <4DE04744.9010605@redhat.com> Date: Fri, 27 May 2011 20:52:20 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Lightning/1.0b2 Thunderbird/3.1.10 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/47049 (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 The problem with this testcase was that we were trying to generate the mangled name of an uninstantiated lambda; we shouldn't ever try to mangle an uninstantiated template. So I changed start_preparsed_function to avoid that. After that was fixed, I found that I also needed to modify maybe_add_lambda_conv_op so that it would get the right comdat group for op() even if it hasn't been instantiated yet. To guard against similar problems in future I added an assert to mangle_decl_string so that we don't try to mangle templates anymore. This revealed an issue with the #pragma interface code, also fixed. Tested x86_64-pc-linux-gnu, applying to trunk. commit acd4876ce7c095f91a4d7a149bc8a7f9bf4ec733 Author: Jason Merrill Date: Fri May 27 16:30:55 2011 -0400 PR c++/47049 * semantics.c (maybe_add_lambda_conv_op): Fix COMDAT sharing. * decl.c (start_preparsed_function): Don't call comdat_linkage for a template. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3cc25bd..8fe3259 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12672,6 +12672,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) DECL_EXTERNAL (decl1) = 0; if (ctx != NULL_TREE && DECL_DECLARED_INLINE_P (ctx) + && !processing_template_decl && TREE_PUBLIC (ctx)) /* This is a function in a local class in an extern inline function. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 557bf4c..854bac7 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8578,7 +8578,7 @@ maybe_add_lambda_conv_op (tree type) { /* Put the thunk in the same comdat group as the call op. */ struct cgraph_node *callop_node, *thunk_node; - DECL_COMDAT_GROUP (statfn) = DECL_COMDAT_GROUP (callop); + DECL_COMDAT_GROUP (statfn) = cxx_comdat_group (callop); callop_node = cgraph_get_create_node (callop); thunk_node = cgraph_get_create_node (statfn); gcc_assert (callop_node->same_comdat_group == NULL); diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template2.C new file mode 100644 index 0000000..12ffde7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template2.C @@ -0,0 +1,20 @@ +// PR c++/47049 +// { dg-options -std=c++0x } + +enum { E = 0, F = 1 }; +template class S {}; +template +struct T +{ + static void + foo (S *p) + { + S u; + [&u] ()->bool {} (); + } +}; + +int main() +{ + T<0>().foo(0); +} commit 32da298d587756e13c43b3a5d2a73babdf9f58bc Author: Jason Merrill Date: Fri May 27 16:31:23 2011 -0400 * mangle.c (mangle_decl_string): Make sure we don't try to mangle templates. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8fe3259..232b5cf 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12664,7 +12664,9 @@ start_preparsed_function (tree decl1, tree attrs, int flags) compiler-generated functions. */ && !DECL_ARTIFICIAL (decl1)); - if (DECL_INTERFACE_KNOWN (decl1)) + if (processing_template_decl) + /* Don't mess with interface flags. */; + else if (DECL_INTERFACE_KNOWN (decl1)) { tree ctx = decl_function_context (decl1); @@ -12672,7 +12674,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags) DECL_EXTERNAL (decl1) = 0; if (ctx != NULL_TREE && DECL_DECLARED_INLINE_P (ctx) - && !processing_template_decl && TREE_PUBLIC (ctx)) /* This is a function in a local class in an extern inline function. */ @@ -12684,8 +12685,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) else if (!finfo->interface_unknown && honor_interface) { if (DECL_DECLARED_INLINE_P (decl1) - || DECL_TEMPLATE_INSTANTIATION (decl1) - || processing_template_decl) + || DECL_TEMPLATE_INSTANTIATION (decl1)) { DECL_EXTERNAL (decl1) = (finfo->interface_only diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 27ef374..7ecfefb 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3095,6 +3095,9 @@ mangle_decl_string (const tree decl) tree saved_fn = NULL_TREE; bool template_p = false; + /* We shouldn't be trying to mangle an uninstantiated template. */ + gcc_assert (!type_dependent_expression_p (decl)); + if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) { struct tinst_level *tl = current_instantiation ();