From e0f0935b9dbe8028ba426c6b1051dff96d043f2e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 2 Apr 2013 23:11:02 -0400 Subject: [PATCH] re PR c++/56821 (Unable to overload with references to 'this'.) PR c++/56821 * mangle.c (write_function_type): Mangle ref-qualifier. (write_nested_name): Likewise. (canonicalize_for_substitution): Preserve ref-qualifier. (write_type): Likewise. From-SVN: r197386 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/mangle.c | 37 +++++++++++++++++-- gcc/testsuite/g++.dg/cpp0x/ref-qual-mangle1.C | 37 +++++++++++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/ref-qual-mangle1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1b847a9acc0..68bc51195cc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2013-04-02 Jason Merrill + PR c++/56821 + * mangle.c (write_function_type): Mangle ref-qualifier. + (write_nested_name): Likewise. + (canonicalize_for_substitution): Preserve ref-qualifier. + (write_type): Likewise. + PR c++/34949 * decl.c (begin_destructor_body): Clobber the object in a cleanup. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 5fe3bf5dfda..4e68c51e136 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -350,6 +350,7 @@ canonicalize_for_substitution (tree node) && TYPE_CANONICAL (node) != node && TYPE_MAIN_VARIANT (node) != node) { + tree orig = node; /* Here we want to strip the topmost typedef only. We need to do that so is_std_substitution can do proper name matching. */ @@ -361,6 +362,9 @@ canonicalize_for_substitution (tree node) else node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node), cp_type_quals (node)); + if (TREE_CODE (node) == FUNCTION_TYPE + || TREE_CODE (node) == METHOD_TYPE) + node = build_ref_qualified_type (node, type_memfn_rqual (orig)); } return node; } @@ -904,9 +908,11 @@ write_unscoped_template_name (const tree decl) /* Write the nested name, including CV-qualifiers, of DECL. - ::= N [] E - ::= N [] E + ::= N [] [] E + ::= N [] [] E + ::= R # & ref-qualifier + ::= O # && ref-qualifier ::= [r] [V] [K] */ static void @@ -926,6 +932,13 @@ write_nested_name (const tree decl) write_char ('V'); if (DECL_CONST_MEMFUNC_P (decl)) write_char ('K'); + if (FUNCTION_REF_QUALIFIED (TREE_TYPE (decl))) + { + if (FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl))) + write_char ('O'); + else + write_char ('R'); + } } /* Is this a template instance? */ @@ -1880,7 +1893,13 @@ write_type (tree type) mangle the unqualified type. The recursive call is needed here since both the qualified and unqualified types are substitution candidates. */ - write_type (TYPE_MAIN_VARIANT (type)); + { + tree t = TYPE_MAIN_VARIANT (type); + if (TREE_CODE (t) == FUNCTION_TYPE + || TREE_CODE (t) == METHOD_TYPE) + t = build_ref_qualified_type (t, type_memfn_rqual (type)); + write_type (t); + } else if (TREE_CODE (type) == ARRAY_TYPE) /* It is important not to use the TYPE_MAIN_VARIANT of TYPE here so that the cv-qualification of the element type is available @@ -1892,6 +1911,9 @@ write_type (tree type) /* See through any typedefs. */ type = TYPE_MAIN_VARIANT (type); + if (TREE_CODE (type) == FUNCTION_TYPE + || TREE_CODE (type) == METHOD_TYPE) + type = build_ref_qualified_type (type, type_memfn_rqual (type_orig)); /* According to the C++ ABI, some library classes are passed the same as the scalar type of their single member and use the same @@ -2327,7 +2349,7 @@ write_builtin_type (tree type) METHOD_TYPE. The return type is mangled before the parameter types. - ::= F [Y] E */ + ::= F [Y] [] E */ static void write_function_type (const tree type) @@ -2360,6 +2382,13 @@ write_function_type (const tree type) See [dcl.link]. */ write_bare_function_type (type, /*include_return_type_p=*/1, /*decl=*/NULL); + if (FUNCTION_REF_QUALIFIED (type)) + { + if (FUNCTION_RVALUE_QUALIFIED (type)) + write_char ('O'); + else + write_char ('R'); + } write_char ('E'); } diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual-mangle1.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual-mangle1.C new file mode 100644 index 00000000000..c6ef0792b50 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/ref-qual-mangle1.C @@ -0,0 +1,37 @@ +// PR c++/56821 +// { dg-require-effective-target c++11 } + +struct A { + // { dg-final { scan-assembler "_ZNR1A1fEv" } } + void f() & {} + // { dg-final { scan-assembler "_ZNO1A1gEv" } } + void g() && {} + // { dg-final { scan-assembler "_ZNKR1A1hEv" } } + void h() const & {} +}; + +// { dg-final { scan-assembler "_Z1jM1AFvvRE" } } +void j(void (A::*)() &) { } +// { dg-final { scan-assembler "_Z1kM1AFvvOE" } } +void k(void (A::*)() &&) { } +// { dg-final { scan-assembler "_Z1lM1AKFvvRE" } } +void l(void (A::*)() const &) { } + +// { dg-final { scan-assembler "_Z1mIFvvOEEvM1AT_" } } +// { dg-final { scan-assembler "_Z1mIFvvREEvM1AT_" } } +// { dg-final { scan-assembler "_Z1mIKFvvREEvM1AT_" } } +template +void m(T A::*) {} + +// { dg-final { scan-assembler "_Z1nIM1AFvvOEEvT_" } } +// { dg-final { scan-assembler "_Z1nIM1AFvvREEvT_" } } +// { dg-final { scan-assembler "_Z1nIM1AKFvvREEvT_" } } +template +void n(T) {} + +int main() +{ + j(&A::f); k(&A::g); l(&A::h); + m(&A::f); m(&A::g); m(&A::h); + n(&A::f); n(&A::g); n(&A::h); +} -- 2.30.2