From patchwork Fri Mar 25 16:10:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 88394 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 781501007D1 for ; Sat, 26 Mar 2011 03:10:50 +1100 (EST) Received: (qmail 31424 invoked by alias); 25 Mar 2011 16:10:43 -0000 Received: (qmail 31403 invoked by uid 22791); 25 Mar 2011 16:10:41 -0000 X-SWARE-Spam-Status: No, hits=-6.3 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; Fri, 25 Mar 2011 16:10:31 +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 p2PGAVGZ010548 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 25 Mar 2011 12:10:31 -0400 Received: from [127.0.0.1] (ovpn-113-150.phx2.redhat.com [10.3.113.150]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p2PGAUNt032284 for ; Fri, 25 Mar 2011 12:10:31 -0400 Message-ID: <4D8CBE75.4050700@redhat.com> Date: Fri, 25 Mar 2011 17:10:29 +0100 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.15) Gecko/20110307 Fedora/3.1.9-0.39.b3pre.fc14 Lightning/1.0b2 Thunderbird/3.1.9 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/48289 (-pedantic breaks std::move) 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 here was that we were improperly treating static_cast::type&&>(x) as an lvalue because the dereference was inside a NON_DEPENDENT_EXPR, which we always treat as an lvalue. That seems like a bad assumption, but we can fix this bug simply by moving the dereference outside. Tested x86_64-pc-linux-gnu, applied to trunk and 4.5, will apply to 4.6 after 4.6.0. commit 91300f260ac2bb684e62e28a1e63b8646d1d49cc Author: Jason Merrill Date: Fri Mar 25 11:16:54 2011 +0100 PR c++/48289 * pt.c (build_non_dependent_expr): Keep dereferences outside the NON_DEPENDENT_EXPR. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c8c1010..9032dd9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -18846,24 +18846,17 @@ build_non_dependent_expr (tree expr) TREE_OPERAND (expr, 0), build_non_dependent_expr (TREE_OPERAND (expr, 1))); + /* Keep dereferences outside the NON_DEPENDENT_EXPR so lvalue_kind + doesn't need to look inside. */ + if (TREE_CODE (expr) == INDIRECT_REF && REFERENCE_REF_P (expr)) + return convert_from_reference (build_non_dependent_expr + (TREE_OPERAND (expr, 0))); + /* If the type is unknown, it can't really be non-dependent */ gcc_assert (TREE_TYPE (expr) != unknown_type_node); - /* Otherwise, build a NON_DEPENDENT_EXPR. - - REFERENCE_TYPEs are not stripped for expressions in templates - because doing so would play havoc with mangling. Consider, for - example: - - template void f() { g(); } - - In the body of "f", the expression for "g" will have - REFERENCE_TYPE, even though the standard says that it should - not. The reason is that we must preserve the syntactic form of - the expression so that mangling (say) "f" inside the body of - "f" works out correctly. Therefore, the REFERENCE_TYPE is - stripped here. */ - return build1 (NON_DEPENDENT_EXPR, non_reference (TREE_TYPE (expr)), expr); + /* Otherwise, build a NON_DEPENDENT_EXPR. */ + return build1 (NON_DEPENDENT_EXPR, TREE_TYPE (expr), expr); } /* ARGS is a vector of expressions as arguments to a function call. diff --git a/gcc/testsuite/g++.dg/cpp0x/move1.C b/gcc/testsuite/g++.dg/cpp0x/move1.C new file mode 100644 index 0000000..12e363a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/move1.C @@ -0,0 +1,15 @@ +// { dg-options "-std=c++0x -pedantic-errors" } + +#include + +class A { }; + +static void g ( A && ) { } + +template < class T > class B { +public: + void f ( ) { + A a; + g ( std :: move ( a ) ); + } +};