diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6ef6e6e..06b0b3e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5346,7 +5346,7 @@ extern tree baselink_for_fns                    (tree);
 extern void finish_static_assert                (tree, tree, location_t,
                                                  bool);
 extern tree describable_type			(tree);
-extern tree finish_decltype_type                (tree, bool);
+extern tree finish_decltype_type                (tree, bool, tsubst_flags_t);
 extern tree finish_trait_expr			(enum cp_trait_kind, tree, tree);
 extern tree build_lambda_expr                   (void);
 extern tree build_lambda_object			(tree);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 9ed3a1f..607e9b8 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10197,7 +10197,8 @@ cp_parser_decltype (cp_parser *parser)
       return error_mark_node;
     }
 
-  return finish_decltype_type (expr, id_expression_or_member_access_p);
+  return finish_decltype_type (expr, id_expression_or_member_access_p,
+			       tf_warning_or_error);
 }
 
 /* Special member functions [gram.special] */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5960e46..66db880 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11025,7 +11025,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	  type = lambda_return_type (type);
 	else
 	  type = finish_decltype_type
-	    (type, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t));
+	    (type, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t), complain);
 	return cp_build_qualified_type_real (type,
 					     cp_type_quals (t)
 					     | cp_type_quals (type),
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index a15740a..80ec028 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4785,7 +4785,8 @@ describable_type (tree expr)
    a full expression.  */
 
 tree
-finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
+finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
+		      tsubst_flags_t complain)
 {
   tree orig_expr = expr;
   tree type = NULL_TREE;
@@ -4798,7 +4799,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
       || (TREE_CODE (expr) == BIT_NOT_EXPR
 	  && TYPE_P (TREE_OPERAND (expr, 0))))
     {
-      error ("argument to decltype must be an expression");
+      if (complain & tf_error)
+	error ("argument to decltype must be an expression");
       return error_mark_node;
     }
 
@@ -4864,7 +4866,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
           if (OVL_CHAIN (expr)
 	      || TREE_CODE (OVL_FUNCTION (expr)) == TEMPLATE_DECL)
             {
-              error ("%qE refers to a set of overloaded functions", orig_expr);
+	      if (complain & tf_error)
+		error ("%qE refers to a set of overloaded functions",
+		       orig_expr);
               return error_mark_node;
             }
           else
@@ -4916,7 +4920,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
         default:
 	  gcc_assert (TYPE_P (expr) || DECL_P (expr)
 		      || TREE_CODE (expr) == SCOPE_REF);
-          error ("argument to decltype must be an expression");
+	  if (complain & tf_error)
+	    error ("argument to decltype must be an expression");
           return error_mark_node;
         }
     }
@@ -4954,7 +4959,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
 
   if (!type || type == unknown_type_node)
     {
-      error ("type of %qE is unknown", expr);
+      if (complain & tf_error)
+	error ("type of %qE is unknown", expr);
       return error_mark_node;
     }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae7.C b/gcc/testsuite/g++.dg/cpp0x/sfinae7.C
new file mode 100644
index 0000000..0a95a96
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae7.C
@@ -0,0 +1,20 @@
+// { dg-options -std=c++0x }
+
+struct A
+{
+  void f();
+  void f(int);
+  typedef int g;
+};
+
+template <class T> decltype (T::f) f();
+template <class T> void f();
+
+template <class T> decltype (T::g) g();
+template <class T> void g();
+
+int main()
+{
+  f<A>();
+  g<A>();
+}
