}
       /* fall through */
 
+    case OFFSET_TYPE:
+      if (TYPE_PTRDATAMEM_P (t))
+       {
+         pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
+         pp_cxx_whitespace (pp);
+         pp_cxx_ptr_operator (pp, t);
+         break;
+       }
+      /* fall through */
+
     default:
       if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
        pp_c_specifier_qualifier_list (pp, t);
 void
 cxx_pretty_printer::abstract_declarator (tree t)
 {
-  if (TYPE_PTRMEM_P (t))
+  /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
+     or a pointer-to-data-member of array type:
+
+       void (X::*)()
+       int (X::*)[5]
+
+     but not for a pointer-to-data-member of non-array type:
+
+       int X::*
+
+     so be mindful of that.  */
+  if (TYPE_PTRMEMFUNC_P (t)
+      || (TYPE_PTRDATAMEM_P (t)
+         && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE))
     pp_cxx_right_paren (this);
   else if (INDIRECT_TYPE_P (t))
     {
        direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
       break;
 
+    case OFFSET_TYPE:
+      if (TYPE_PTRDATAMEM_P (t))
+       direct_abstract_declarator (TREE_TYPE (t));
+      break;
+
     case METHOD_TYPE:
     case FUNCTION_TYPE:
       pp_cxx_parameter_declaration_clause (this, t);
     case UNDERLYING_TYPE:
     case DECLTYPE_TYPE:
     case TEMPLATE_ID_EXPR:
+    case OFFSET_TYPE:
       pp_cxx_type_specifier_seq (this, t);
+      if (TYPE_PTRMEM_P (t))
+       abstract_declarator (t);
       break;
 
     case TYPE_PACK_EXPANSION:
 
--- /dev/null
+// PR c++/97406
+// { dg-do compile { target c++20 } }
+
+struct X {
+  void f() { }
+  int a;
+  int arr[5];
+};
+
+// Duplicated so that I can check dg-message.
+template<typename T>
+requires (sizeof(T)==1) // { dg-message {\[with T = void \(X::\*\)\(\)\]} }
+void f1(T)
+{ }
+
+template<typename T>
+requires (sizeof(T)==1) // { dg-message {\[with T = int X::\*\]} }
+void f2(T)
+{ }
+
+template<typename T>
+requires (sizeof(T)==1) // dg-message {\[with T = int \(X::\*\)\[5\]\]} }
+void f3(T)
+{ }
+
+int main()
+{
+  f1(&X::f); // { dg-error "no matching function for call" }
+  f2(&X::a); // { dg-error "no matching function for call" }
+  f3(&X::arr); // { dg-error "no matching function for call" }
+}
 
--- /dev/null
+// PR c++/85901
+// { dg-do compile { target c++11 } }
+
+template<class> struct A;
+
+template<class U>
+struct A<int U::*> {
+    template<class TT>
+    static auto c(int U::*p, TT o) -> decltype(o.*p); // { dg-message {A<int U::\*>} }
+};
+
+struct X {};
+
+int x = A<int X::*>::c(); // { dg-error "no matching function for call" }