Fix ICE in pp_cxx_unqualified_id (PR c++/88348)

Zhouyi Zhou zhouzhouyi@gmail.com
Tue Dec 4 08:31:00 GMT 2018


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 <zhouzhouyi@gmail.com>

2018-12-04 Zhouyi Zhou <zhouzhouyi@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" }



More information about the Gcc-patches mailing list