From patchwork Fri Jan 31 03:46:59 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 315505 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 729542C009F for ; Fri, 31 Jan 2014 14:47:11 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:references :in-reply-to:content-type; q=dns; s=default; b=iH38G/BiM9vo+LInB nyWVXlk0+iX2gPKeDNH8CYsLEh/xlBZM+7APc4UT50y+fFF3TjFf0wV6JuMYAi6q AMA1NkDipWgRo9ddjaRxVCE+EvQduaX9k/stfc/TVLd9UTctUODY6kdttCF5Sdog w4RPFOZONtlk98XtrgxMivtIfA= 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 :message-id:date:from:mime-version:to:subject:references :in-reply-to:content-type; s=default; bh=ZUkswokjPucfYy+azZWlvxK aR3c=; b=e1W1oCANV/VCIMjvaVFRKqA/ZkpkpBvsH6BZWUM/1USA0clrX+QtOWh GOEnQ7aZ1TX7zKdc2Rp0P9i9m3hsL4yq7N2lKNgZV7FFzqTK1icw4TOmmluslGmf xajfNXd4fPxYTYCD9SXKr8zLG3vbSaOABFUmvBcDKWZxJ0gy2ukc= Received: (qmail 22600 invoked by alias); 31 Jan 2014 03:47:04 -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 22590 invoked by uid 89); 31 Jan 2014 03:47:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.2 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 31 Jan 2014 03:47:02 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s0V3l1HJ012283 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 30 Jan 2014 22:47:01 -0500 Received: from [10.10.116.19] ([10.10.116.19]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s0V3l01E028190 for ; Thu, 30 Jan 2014 22:47:00 -0500 Message-ID: <52EB1CB3.9040601@redhat.com> Date: Thu, 30 Jan 2014 22:46:59 -0500 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: gcc-patches List Subject: Re: RFA (pointer-set): PATCH for c++/57899 (infinite recursion with std::bind) References: <52EABD69.1020705@redhat.com> In-Reply-To: <52EABD69.1020705@redhat.com> On 01/30/2014 04:00 PM, Jason Merrill wrote: > Also, in the past we've had issues with nested functions in templates > being able to refer to static/const variables from the enclosing > context; we've dealt with that by forcing repeated lookup, but it would > be better to keep the local_specializations from the enclosing function > around so we can find them the usual way. To that end, I've added a > pointer_map_copy. It occurs to me that I don't really need to do this to fix the bug, and perhaps this sort of change should wait for stage 1. So I'm checking in this subset of the patch. The second patch is the version I'm applying to 4.8, which has more limited effect (and works with 4.8, which the trunk patch does not). commit 1ef391f60fd02b7698cb8adaa606c4c9d37d245d Author: Jason Merrill Date: Thu Jan 30 13:13:55 2014 -0500 PR c++/57899 * pt.c (instantiate_template_1): Save/restore local_specializations. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e47c2a4..f07b935 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14784,6 +14784,8 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) /* Instantiation of the function happens in the context of the function template, not the context of the overload resolution we're doing. */ push_to_top_level (); + struct pointer_map_t *saved_local_specializations = local_specializations; + local_specializations = NULL; /* If there are dependent arguments, e.g. because we're doing partial ordering, make sure processing_template_decl stays set. */ if (uses_template_parms (targ_ptr)) @@ -14799,6 +14801,7 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) targ_ptr, complain, gen_tmpl); if (DECL_CLASS_SCOPE_P (gen_tmpl)) pop_nested_class (); + local_specializations = saved_local_specializations; pop_from_top_level (); if (fndecl == error_mark_node) diff --git a/libstdc++-v3/testsuite/20_util/bind/57899.cc b/libstdc++-v3/testsuite/20_util/bind/57899.cc new file mode 100644 index 0000000..d46d53e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/bind/57899.cc @@ -0,0 +1,48 @@ +// Copyright (C) 2010-2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 20.7.11 Function template bind + +// PR c++/57899 +// { dg-do compile } +// { dg-options -std=c++11 } + +#include +using std::bind; +using std::placeholders::_1; + +struct S { int i; }; + +struct P { S s; }; + +struct get_s +{ + const S& operator()(const P& p) const { return p.s; } +} gs; + +int gi(const S& s) { return s.i; } + +bool cmp(int, int) { return true; } + +int main() +{ + P p{}; + auto f1 = bind(gs, _1); + auto f2 = bind(gi, f1); + auto f3 = bind(cmp, f2, 5); + f3(p); +}