@@ -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);
new file mode 100644
@@ -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();
+}