From patchwork Wed Feb 9 14:16:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 82469 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 70E01B70E3 for ; Thu, 10 Feb 2011 01:16:58 +1100 (EST) Received: (qmail 22445 invoked by alias); 9 Feb 2011 14:16:47 -0000 Received: (qmail 22306 invoked by uid 22791); 9 Feb 2011 14:16:45 -0000 X-SWARE-Spam-Status: No, hits=-5.6 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; Wed, 09 Feb 2011 14:16:40 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p19EGd2o018940 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 9 Feb 2011 09:16:39 -0500 Received: from adjoa.redhat.com (ovpn-113-77.phx2.redhat.com [10.3.113.77]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p19EGap6006114; Wed, 9 Feb 2011 09:16:37 -0500 From: Dodji Seketeli To: GCC Patches Cc: Jason Merrill Subject: [PATCH] Fix PR c++/47172 X-URL: http://www.redhat.com Date: Wed, 09 Feb 2011 15:16:36 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes 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 Hello, The code snippet below fails to compile in c++0x mode and compiles fine in c++98. struct A { int f() const; }; template struct B : A { }; template struct C : B { void g(); }; template void C::g() { A::f(); //#0 } finish_expr_stmt fails on the call expression "A::f()" because it doesn't notice that A::f() in #0 is type dependent [as its implicit 'this' is type dependent] and so it tries to fold it; and fails. The patch below teaches type_dependent_expression_p to try harder to look for type dependency in call expressions. Tested on x86_64-unknown-linux-gnu against trunk. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d59f32a..5a70968 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -18241,6 +18241,55 @@ type_dependent_expression_p (tree expression) return dependent_type_p (type); } + if (TREE_CODE (expression) == CALL_EXPR) + { + int nargs, i; + tree fn; + + if (dependent_type_p (TREE_TYPE (expression))) + return true; + + fn = CALL_EXPR_FN (expression); + + if (TREE_CODE (fn) == BASELINK) + { + /* So this is a reference to a member function from a base. */ + + /* If the implicit "*this" is dependent then this reference + to a member function is dependent. */ + if (current_class_ref + && dependent_type_p (TREE_TYPE (current_class_ref))) + return true; + + /* If the qualifying scope is dependant then the expression + is dependent. */ + if (dependent_type_p (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)))) + return true; + } + else if (TREE_CODE (fn) == COMPONENT_REF + || TREE_CODE (fn) == OFFSET_REF) + { + tree instance = TREE_OPERAND (fn, 0); + tree method = TREE_OPERAND (fn, 1); + + if (type_dependent_expression_p (instance)) + return true; + + if (TREE_CODE (method) == IDENTIFIER_NODE) + return false; + + if (type_dependent_expression_p (method)) + return true; + } + + nargs = call_expr_nargs (expression); + for (i = 0; i < nargs; ++i) + if (type_dependent_expression_p (CALL_EXPR_ARG (expression, i))) + return true; + + expression = fn; + } + if (TREE_CODE (expression) == SCOPE_REF) { tree scope = TREE_OPERAND (expression, 0); diff --git a/gcc/testsuite/g++.dg/template/inherit6.C b/gcc/testsuite/g++.dg/template/inherit6.C new file mode 100644 index 0000000..241a68e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/inherit6.C @@ -0,0 +1,23 @@ +// Origin PR c++/47172 +// { dg-options "-std=c++0x" } +// { dg-do compile } + +struct A +{ + int f() const; +}; + +template +struct B : A { }; + +template +struct C : B +{ + void g(); +}; + +template +void C::g() +{ + A::f(); +}