From patchwork Fri Feb 15 04:09:32 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 220621 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 EE2FF2C0079 for ; Fri, 15 Feb 2013 15:09:52 +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=1361506193; 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=I1GRp3s 3uOXaqNTOlC+2b1XzC4o=; b=CkQ7cpCgrCe8QWcpUk20DeLejWP8cj0OyggUeWf dK3IDS1TGEsBWmjg2esPhOKQitas/VrEKr9u+V1xEUy9C6RCOQtpvo2WkGI3G9z7 zKDCFqGXJ3KyYKvSj82HOhT1N794N5U+HbzPhe3fCGPe9WjapWsdV7dMeZNcSf3S eIoA= 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=HnO7I12PbgxJrbEfXqMLx281hwUfD747kwrxa7eK18QXs9H7An0E53D1o8jTVR acevVC6e9sMzaxXBKVJhhPCBzGH4F/nCNXso04k9jvPCX6Dcdsa+7w8WgHbVi130 NV3Al+cYA3St6PEiL2R7eLKlg1sijGY8meN3plZy9g5hY=; Received: (qmail 20406 invoked by alias); 15 Feb 2013 04:09:45 -0000 Received: (qmail 20395 invoked by uid 22791); 15 Feb 2013 04:09:44 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_SPAMHAUS_DROP, 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; Fri, 15 Feb 2013 04:09:35 +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 r1F49YQu003231 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 14 Feb 2013 23:09:35 -0500 Received: from [10.3.113.52] (ovpn-113-52.phx2.redhat.com [10.3.113.52]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r1F49WW6019840 for ; Thu, 14 Feb 2013 23:09:34 -0500 Message-ID: <511DB4FC.9050600@redhat.com> Date: Thu, 14 Feb 2013 23:09:32 -0500 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:21.0) Gecko/20100101 Thunderbird/21.0a1 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/52026 (use of enclosing constant var 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 In this testcase, we see a use of a constant variable in a lambda (though the same thing can happen with a local class member function). We try to pull out the constant value in finish_id_expression, but because the initializer isn't a reduced constant yet, that fails and we end up just returning the variable. At instantiation time tsubst instantiates the use of the variable by creating a new one in the lambda context, which is obviously broken. A better solution is to defer deciding how to handle the variable until instantiation time, at which point we will know. Since the logic for this is in finish_id_expression, it's easy to just return the name and look it up again at that point. Tested x86_64-pc-linux-gnu, applying to trunk and 4.7. commit 38e1d69672c4028124637e3b78430f4c45dff6a8 Author: Jason Merrill Date: Thu Feb 14 22:11:56 2013 -0500 PR c++/52026 * semantics.c (finish_id_expression): In a template, return the identifier for a constant variable. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 28b4b79..0e09d04 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3015,7 +3015,14 @@ finish_id_expression (tree id_expression, FIXME update for final resolution of core issue 696. */ if (decl_constant_var_p (decl)) - return integral_constant_value (decl); + { + if (processing_template_decl) + /* In a template, the constant value may not be in a usable + form, so look it up again at instantiation time. */ + return id_expression; + else + return integral_constant_value (decl); + } /* If we are in a lambda function, we can move out until we hit 1. the context, diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const2.C new file mode 100644 index 0000000..d2457d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const2.C @@ -0,0 +1,15 @@ +// PR c++/52026 +// { dg-options "-std=c++11 -O" } +// { dg-do run } + +template +int func() { + const int constVal1 = B ? 100 : -100; + const int constVal = constVal1; + return [] { return constVal; }(); +} + +int main() { + if (func() != 100) + __builtin_abort (); +}