This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]