cxx_pretty_printer::type_id do not treat pointer to 
pointer to member correctly. 
this patch handle pointer to pointer to member according to
C++ standard 11.3.3.

I don't have write access to gcc.
 
Bootstrapped/regtested on x86_64-linux
Signed-off-by: Zhouyi Zhou <zhouzho...@gmail.com>

2018-12-04 Zhouyi Zhou <zhouzho...@gmail.com>

        PR c++/88291
        * cxx-pretty-print.c (type_id): treat pointer to pointer 
        to member by strip out the pointee, print the type specifier 
        of pointee, then print the rest by calling pp_cxx_ptr_operator.

        * g++.dg/pr88348.C: New test.  

---
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index b79ff51..106e6af 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -1829,6 +1829,27 @@ cxx_pretty_printer::type_id (tree t)
       pp_cxx_ws_string (this, "...");
       break;
 
+    case POINTER_TYPE:
+      {
+             tree pointee = strip_pointer_operator(TREE_TYPE(t));
+             /* 11.3.3 */
+             if (TREE_CODE(pointee) == RECORD_TYPE &&
+                 TYPE_PTRMEMFUNC_P(pointee)) {
+                     tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (pointee);
+                     pp_cxx_type_specifier_seq (this, TREE_TYPE (TREE_TYPE 
(pfm)));
+                     pp_cxx_whitespace (this);
+                     pp_cxx_ptr_operator(this, t);
+                     break;
+             } else if (TREE_CODE(pointee) == OFFSET_TYPE &&
+                        TYPE_PTRMEM_P(pointee)) {
+                     pp_cxx_type_specifier_seq (this, 
TYPE_PTRMEM_POINTED_TO_TYPE(pointee));
+                     pp_cxx_whitespace (this);
+                     pp_cxx_ptr_operator(this, t);
+                     break;
+             }
+      }
+      /* fall through */
+           
     default:
       c_pretty_printer::type_id (t);
       break;
diff --git a/gcc/testsuite/g++.dg/pr88348.C b/gcc/testsuite/g++.dg/pr88348.C
new file mode 100644
index 0000000..5713f49
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr88348.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++11 } }
+
+void* operator new (__SIZE_TYPE__, void *p) { return p; }
+
+struct Z {
+       void f(int = 0) const;
+       int speed;
+};
+
+template <class T> struct helper {};
+
+typedef void (Z::***QF)(int) const;
+typedef int Z::***pSpeed;
+
+template <class T> void check1( helper<new QF> * ) { } // { dg-error "is not a 
constant expression|type/value mismatch" }
+template <class T> void check2( helper<new pSpeed> * ) { } // { dg-error "is 
not a constant expression|type/value mismatch" }

Reply via email to