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