This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR c++/47172
- From: Dodji Seketeli <dodji at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Jason Merrill <jason at redhat dot com>
- Date: Wed, 09 Feb 2011 15:16:36 +0100
- Subject: [PATCH] Fix PR c++/47172
Hello,
The code snippet below fails to compile in c++0x mode and compiles
fine in c++98.
struct A
{
int f() const;
};
template <class T>
struct B : A { };
template <class T>
struct C : B<T>
{
void g();
};
template <class T>
void C<T>::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.
--
Dodji
>From 52b92a325a3ebe8641b367f9adb3334c6c4adacf Mon Sep 17 00:00:00 2001
From: Dodji Seketeli <dodji@redhat.com>
Date: Tue, 8 Feb 2011 10:05:36 +0100
Subject: [PATCH] Fix PR c++/47172
gcc/cp/
PR c++/47172
* pt.c (type_dependent_expression_p): Try harder to handle CALL_EXPR case.
gcc/testsuite/
* g++.dg/template/inherit6.C: New test.
---
gcc/cp/pt.c | 49 ++++++++++++++++++++++++++++++
gcc/testsuite/g++.dg/template/inherit6.C | 23 ++++++++++++++
2 files changed, 72 insertions(+), 0 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/template/inherit6.C
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 <class T>
+struct B : A { };
+
+template <class T>
+struct C : B<T>
+{
+ void g();
+};
+
+template <class T>
+void C<T>::g()
+{
+ A::f();
+}
--
1.7.3.4