Message ID | 20201014195245.1237803-1-polacek@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: Improve printing of pointers-to-members [PR97406, PR85901] | expand |
On 10/14/20 3:52 PM, Marek Polacek wrote: > This PR points out that when printing the parameter mapping for a > pointer-to-member-function, the output was truncated: > > [with T = void (X::*] > > Fixed by printing the abstract declarator for pointers-to-members in > cxx_pretty_printer::type_id. So now we print: > > [with T = void (X::*)()] > > But when I tried a pointer-to-data-member, I got > > [with T = ‘offset_type’ not supported by simple_type_specifier)‘offset_type’ not supported by direct_abstract_declarator] > > so had to fix that too so that we now print: > > [with T = int X::*] > > or > > [with T = int (X::*)[5]] > > when the type is an array type. Which is what PR85901 was about. > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? OK. > gcc/cp/ChangeLog: > > PR c++/97406 > PR c++/85901 > * cxx-pretty-print.c (pp_cxx_type_specifier_seq): Handle OFFSET_TYPE. > (cxx_pretty_printer::abstract_declarator): Fix the printing of ')'. > (cxx_pretty_printer::direct_abstract_declarator): Handle OFFSET_TYPE. > (cxx_pretty_printer::type_id): Likewise. Print the abstract declarator > for pointers-to-members. > > gcc/testsuite/ChangeLog: > > PR c++/97406 > PR c++/85901 > * g++.dg/diagnostic/ptrtomem1.C: New test. > * g++.dg/diagnostic/ptrtomem2.C: New test. > --- > gcc/cp/cxx-pretty-print.c | 33 ++++++++++++++++++++- > gcc/testsuite/g++.dg/diagnostic/ptrtomem1.C | 31 +++++++++++++++++++ > gcc/testsuite/g++.dg/diagnostic/ptrtomem2.C | 14 +++++++++ > 3 files changed, 77 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/diagnostic/ptrtomem1.C > create mode 100644 gcc/testsuite/g++.dg/diagnostic/ptrtomem2.C > > diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c > index 8bea79b93a2..058b9c2f4fc 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 00000000000..bb1327f7af1 > --- /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 00000000000..f3b29a07a99 > --- /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" } > > base-commit: 93103603fd66a9fcf3ea2d8b52657e4b2496f544 >
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index 8bea79b93a2..058b9c2f4fc 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 00000000000..bb1327f7af1 --- /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 00000000000..f3b29a07a99 --- /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" }