From patchwork Tue Jul 3 05:00:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 168684 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 9B7D42C00B2 for ; Tue, 3 Jul 2012 15:01:22 +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=1341896483; 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=tximrjs zrV7rbDFqNYYtTet/EdU=; b=nRW+cLmRXDm6/p8NmiFuAf4iFxWqb+K40Nv+5CO dJRZjUnN+oSRPNv5yBT0kNXyQ+2wnhw25TeXdELrOws3p4Yncr0humENEB3RMjT+ 6vgtT1QsSWgK9SzbKC3aXRf99H0rQ2Ke4VPLlQrYJJ5+TuJ8jUQE0V8QpALC+Cub 8MPQ= 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=elx39zXgbKAJFCd8n6EiI/2bCvKegtNmKxSLtp+veqkSLGDjIsy6GYp4d2I0Ug EYHn8bKEA/VxIOc/DaS+PxWYltNbzH4bsIuEzm9/z8AFsXIklP2TKPmYi4CCHtcC aTIlEKH1ibW6Bk8KIJZi98dcVA1cx7edF/R2dNQICQ8JI=; Received: (qmail 22754 invoked by alias); 3 Jul 2012 05:01:13 -0000 Received: (qmail 22743 invoked by uid 22791); 3 Jul 2012 05:01:12 -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; Tue, 03 Jul 2012 05:00:50 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q6350pts008403 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 3 Jul 2012 01:00:51 -0400 Received: from [10.3.113.9] ([10.3.113.9]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q6350nHq017111 for ; Tue, 3 Jul 2012 01:00:50 -0400 Message-ID: <4FF27C80.3020904@redhat.com> Date: Tue, 03 Jul 2012 01:00:48 -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++/53619 (wrong base conversion in lambda) 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 My change in 4.8 to use 'auto' for the return type of a lambda caused uses_template_parms (current_function_decl) to return true, causing us to skip the real adjustment to the base address. Fixed by looking at DECL_TI_ARGS instead. Tested x86_64-pc-linux-gnu, applying to trunk. commit 7b3981302f5c25d7e800adc884690850585cb756 Author: Jason Merrill Date: Tue Jul 3 00:00:40 2012 -0400 PR c++/53619 * pt.c (in_template_function): New. * cp-tree.h: Declare it. * class.c (build_base_path, resolves_to_fixed_type_p): Use it. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e70e674..0d4a40d 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -325,8 +325,7 @@ build_base_path (enum tree_code code, up properly yet, and the value doesn't matter there either; we're just interested in the result of overload resolution. */ if (cp_unevaluated_operand != 0 - || (current_function_decl - && uses_template_parms (current_function_decl))) + || in_template_function ()) { expr = build_nop (ptr_target_type, expr); if (!want_pointer) @@ -6523,8 +6522,7 @@ resolves_to_fixed_type_p (tree instance, int* nonnull) /* processing_template_decl can be false in a template if we're in fold_non_dependent_expr, but we still want to suppress this check. */ - if (current_function_decl - && uses_template_parms (current_function_decl)) + if (in_template_function ()) { /* In a template we only care about the type of the result. */ if (nonnull) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a4b7ae3..41ca83c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5330,6 +5330,7 @@ extern tree lookup_template_class (tree, tree, tree, tree, extern tree lookup_template_function (tree, tree); extern int uses_template_parms (tree); extern int uses_template_parms_level (tree, int); +extern bool in_template_function (void); extern tree instantiate_class_template (tree); extern tree instantiate_template (tree, tree, tsubst_flags_t); extern int fn_type_unification (tree, tree, tree, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d385ea7..f618fa5 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8027,6 +8027,23 @@ uses_template_parms (tree t) return dependent_p; } +/* Returns true iff current_function_decl is an incompletely instantiated + template. Useful instead of processing_template_decl because the latter + is set to 0 during fold_non_dependent_expr. */ + +bool +in_template_function (void) +{ + tree fn = current_function_decl; + bool ret; + ++processing_template_decl; + ret = (fn && DECL_LANG_SPECIFIC (fn) + && DECL_TEMPLATE_INFO (fn) + && any_dependent_template_arguments_p (DECL_TI_ARGS (fn))); + --processing_template_decl; + return ret; +} + /* Returns true if T depends on any template parameter with level LEVEL. */ int diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this5.C new file mode 100644 index 0000000..8974641 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this5.C @@ -0,0 +1,22 @@ +// PR c++/53619 +// { dg-do run { target c++11 } } + +struct C { + int x; +}; +struct B { + int q; +}; +struct A : public B , C { + void foo(); +}; + +void A::foo() { + auto k = [this]() {return (void *)(&x);}; + if (k() != (void*)&x) + __builtin_abort(); +} + +int main(int l, char **) { + A a; a.foo(); +}