aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/cxx-pretty-print.c33
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/ptrtomem1.C31
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/ptrtomem2.C14
3 files changed, 77 insertions, 1 deletions
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index 8bea79b..058b9c2 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -1420,6 +1420,16 @@ pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
}
/* 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);
@@ -1753,7 +1763,20 @@ pp_cxx_function_definition (cxx_pretty_printer *pp, tree 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))
{
@@ -1785,6 +1808,11 @@ cxx_pretty_printer::direct_abstract_declarator (tree 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);
@@ -1837,7 +1865,10 @@ cxx_pretty_printer::type_id (tree 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:
diff --git a/gcc/testsuite/g++.dg/diagnostic/ptrtomem1.C b/gcc/testsuite/g++.dg/diagnostic/ptrtomem1.C
new file mode 100644
index 0000000..bb1327f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/ptrtomem1.C
@@ -0,0 +1,31 @@
+// 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" }
+}
diff --git a/gcc/testsuite/g++.dg/diagnostic/ptrtomem2.C b/gcc/testsuite/g++.dg/diagnostic/ptrtomem2.C
new file mode 100644
index 0000000..f3b29a0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/ptrtomem2.C
@@ -0,0 +1,14 @@
+// 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" }