From patchwork Sun Mar 17 01:48:45 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 228263 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 5D5EA2C00AA for ; Sun, 17 Mar 2013 12:49:03 +1100 (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=1364089744; 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=iZirfaE xQP+zsZvQa3szIUjlAdI=; b=p8vDgo3Notx9qPTC0Wg/NXG8NUomX273oPYraHf MPTe8udVcWxJFMks/btCQWHOhpzweIT8qSVppKbcs6+fLsO22NyIB+K/4oGRj3d9 P+3jsvpIjPSDqUwcen8XeHwVV5E1W2OF8ySwdhGGIoB47TLROu2T3GbzJwriO+iG ZloQ= 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=iIt2VjVBXNZXPxWQRyBC98wantqqU3CKARhXSDjzz2xho3SmR81Rom0vkeriT5 du9ZxP+5Fdi/GLAOBY1UpEpdOCUVeKW0NxOuldU4jrBXYmHgDaBwgbf5r/5380PH mSGXKOOFwc0cP1hWbo5bgFvKIhv8ZV8YvKnhcgWSLE8Oc=; Received: (qmail 29633 invoked by alias); 17 Mar 2013 01:48:56 -0000 Received: (qmail 29623 invoked by uid 22791); 17 Mar 2013 01:48:54 -0000 X-SWARE-Spam-Status: No, hits=-7.6 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS 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; Sun, 17 Mar 2013 01:48:46 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2H1mjFh015557 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sat, 16 Mar 2013 21:48:46 -0400 Received: from [10.3.113.56] (ovpn-113-56.phx2.redhat.com [10.3.113.56]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r2H1mjVp029301 for ; Sat, 16 Mar 2013 21:48:45 -0400 Message-ID: <514520FD.2020807@redhat.com> Date: Sat, 16 Mar 2013 21:48:45 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:21.0) Gecko/20100101 Thunderbird/21.0a2 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/54764, 55972 (lambda in class but non-function context) 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 Previously when we encountered a lambda in a class but outside a function we treated it as being in the enclosing namespace scope, which led to access errors in 55972. Fixing that meant properly giving it the class scope, which meant marking it as a lambda type sooner, which made it straightforward to fix 54764 as well. Tested x86_64-pc-linux-gnu, applying to trunk. commit 7fc0aaaac7919a9e92540f308e4d570208a67212 Author: Jason Merrill Date: Mon Mar 11 16:47:16 2013 -0400 PR c++/54764 PR c++/55972 * name-lookup.h (tag_scope): Add ts_lambda. * semantics.c (begin_lambda_type): Use it. * decl.c (xref_tag_1): Set CLASSTYPE_LAMBDA_EXPR. * pt.c (check_default_tmpl_args): Ignore lambdas. (push_template_decl_real): Handle lambdas. * tree.c (no_linkage_check): Adjust lambda check. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index fed101f..af8b0da 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11887,11 +11887,12 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, static tree xref_tag_1 (enum tag_types tag_code, tree name, - tag_scope scope, bool template_header_p) + tag_scope orig_scope, bool template_header_p) { enum tree_code code; tree t; tree context = NULL_TREE; + tag_scope scope; gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); @@ -11911,6 +11912,11 @@ xref_tag_1 (enum tag_types tag_code, tree name, gcc_unreachable (); } + if (orig_scope == ts_lambda) + scope = ts_current; + else + scope = orig_scope; + /* In case of anonymous name, xref_tag is only called to make type node and push name. Name lookup is not required. */ if (ANON_AGGRNAME_P (name)) @@ -11984,6 +11990,10 @@ xref_tag_1 (enum tag_types tag_code, tree name, { t = make_class_type (code); TYPE_CONTEXT (t) = context; + if (orig_scope == ts_lambda) + /* Remember that we're declaring a lambda to avoid bogus errors + in push_template_decl. */ + CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node; t = pushtag (name, t, scope); } } diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index f9a0fbe..b88ada3 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -132,10 +132,11 @@ typedef enum tag_scope { ts_global = 1, /* All scopes. This is the 3.4.1 [basic.lookup.unqual] lookup mentioned in [basic.lookup.elab]/2. */ - ts_within_enclosing_non_class = 2 /* Search within enclosing non-class + ts_within_enclosing_non_class = 2, /* Search within enclosing non-class only, for friend class lookup according to [namespace.memdef]/3 and [class.friend]/9. */ + ts_lambda = 3 /* Declaring a lambda closure. */ } tag_scope; typedef struct GTY(()) cp_class_binding { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4ffc353..1bbcba2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4306,6 +4306,13 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary, local scope. */ return true; + if (TREE_CODE (decl) == TYPE_DECL + && TREE_TYPE (decl) + && LAMBDA_TYPE_P (TREE_TYPE (decl))) + /* A lambda doesn't have an explicit declaration; don't complain + about the parms of the enclosing class. */ + return true; + if (current_class_type && !TYPE_BEING_DEFINED (current_class_type) && DECL_LANG_SPECIFIC (decl) @@ -4674,6 +4681,8 @@ push_template_decl_real (tree decl, bool is_friend) if (!ctx || TREE_CODE (ctx) == FUNCTION_DECL || (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx)) + || (TREE_CODE (decl) == TYPE_DECL + && LAMBDA_TYPE_P (TREE_TYPE (decl))) || (is_friend && !DECL_TEMPLATE_INFO (decl))) { if (DECL_LANG_SPECIFIC (decl) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index d39469d..841f1f7 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8984,7 +8984,7 @@ begin_lambda_type (tree lambda) /* Create the new RECORD_TYPE for this lambda. */ type = xref_tag (/*tag_code=*/record_type, name, - /*scope=*/ts_within_enclosing_non_class, + /*scope=*/ts_lambda, /*template_header_p=*/false); } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 713ec86..6407a0b 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2028,11 +2028,12 @@ no_linkage_check (tree t, bool relaxed_p) if (TYPE_PTRMEMFUNC_P (t)) goto ptrmem; /* Lambda types that don't have mangling scope have no linkage. We - check CLASSTYPE_LAMBDA_EXPR here rather than LAMBDA_TYPE_P because + check CLASSTYPE_LAMBDA_EXPR for error_mark_node because when we get here from pushtag none of the lambda information is set up yet, so we want to assume that the lambda has linkage and fix it up later if not. */ if (CLASSTYPE_LAMBDA_EXPR (t) + && CLASSTYPE_LAMBDA_EXPR (t) != error_mark_node && LAMBDA_TYPE_EXTRA_SCOPE (t) == NULL_TREE) return t; /* Fall through. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg4.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg4.C new file mode 100644 index 0000000..2217954 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg4.C @@ -0,0 +1,8 @@ +// PR c++/54764 +// { dg-require-effective-target c++11 } + +template +struct c +{ + int (*f)(int) = [](int i){return i + i;}; +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi3.C new file mode 100644 index 0000000..da7e0bf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi3.C @@ -0,0 +1,9 @@ +// PR c++/55972 +// { dg-do compile { target c++11 } } + +class C +{ + void f(); + int j = 10; + int i = [this]() { return this->j; }(); +};