Commit e0f0935b by Jason Merrill Committed by Jason Merrill

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
parent fd541994
2013-04-02 Jason Merrill <jason@redhat.com> 2013-04-02 Jason Merrill <jason@redhat.com>
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 PR c++/34949
* decl.c (begin_destructor_body): Clobber the object in a cleanup. * decl.c (begin_destructor_body): Clobber the object in a cleanup.
......
...@@ -350,6 +350,7 @@ canonicalize_for_substitution (tree node) ...@@ -350,6 +350,7 @@ canonicalize_for_substitution (tree node)
&& TYPE_CANONICAL (node) != node && TYPE_CANONICAL (node) != node
&& TYPE_MAIN_VARIANT (node) != node) && TYPE_MAIN_VARIANT (node) != node)
{ {
tree orig = node;
/* Here we want to strip the topmost typedef only. /* Here we want to strip the topmost typedef only.
We need to do that so is_std_substitution can do proper We need to do that so is_std_substitution can do proper
name matching. */ name matching. */
...@@ -361,6 +362,9 @@ canonicalize_for_substitution (tree node) ...@@ -361,6 +362,9 @@ canonicalize_for_substitution (tree node)
else else
node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node), node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node),
cp_type_quals (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; return node;
} }
...@@ -904,9 +908,11 @@ write_unscoped_template_name (const tree decl) ...@@ -904,9 +908,11 @@ write_unscoped_template_name (const tree decl)
/* Write the nested name, including CV-qualifiers, of DECL. /* Write the nested name, including CV-qualifiers, of DECL.
<nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
::= N [<CV-qualifiers>] <template-prefix> <template-args> E ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
<ref-qualifier> ::= R # & ref-qualifier
::= O # && ref-qualifier
<CV-qualifiers> ::= [r] [V] [K] */ <CV-qualifiers> ::= [r] [V] [K] */
static void static void
...@@ -926,6 +932,13 @@ write_nested_name (const tree decl) ...@@ -926,6 +932,13 @@ write_nested_name (const tree decl)
write_char ('V'); write_char ('V');
if (DECL_CONST_MEMFUNC_P (decl)) if (DECL_CONST_MEMFUNC_P (decl))
write_char ('K'); 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? */ /* Is this a template instance? */
...@@ -1880,7 +1893,13 @@ write_type (tree type) ...@@ -1880,7 +1893,13 @@ write_type (tree type)
mangle the unqualified type. The recursive call is needed here mangle the unqualified type. The recursive call is needed here
since both the qualified and unqualified types are substitution since both the qualified and unqualified types are substitution
candidates. */ 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) else if (TREE_CODE (type) == ARRAY_TYPE)
/* It is important not to use the TYPE_MAIN_VARIANT of TYPE here /* It is important not to use the TYPE_MAIN_VARIANT of TYPE here
so that the cv-qualification of the element type is available so that the cv-qualification of the element type is available
...@@ -1892,6 +1911,9 @@ write_type (tree type) ...@@ -1892,6 +1911,9 @@ write_type (tree type)
/* See through any typedefs. */ /* See through any typedefs. */
type = TYPE_MAIN_VARIANT (type); 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 /* According to the C++ ABI, some library classes are passed the
same as the scalar type of their single member and use the same same as the scalar type of their single member and use the same
...@@ -2327,7 +2349,7 @@ write_builtin_type (tree type) ...@@ -2327,7 +2349,7 @@ write_builtin_type (tree type)
METHOD_TYPE. The return type is mangled before the parameter METHOD_TYPE. The return type is mangled before the parameter
types. types.
<function-type> ::= F [Y] <bare-function-type> E */ <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E */
static void static void
write_function_type (const tree type) write_function_type (const tree type)
...@@ -2360,6 +2382,13 @@ write_function_type (const tree type) ...@@ -2360,6 +2382,13 @@ write_function_type (const tree type)
See [dcl.link]. */ See [dcl.link]. */
write_bare_function_type (type, /*include_return_type_p=*/1, write_bare_function_type (type, /*include_return_type_p=*/1,
/*decl=*/NULL); /*decl=*/NULL);
if (FUNCTION_REF_QUALIFIED (type))
{
if (FUNCTION_RVALUE_QUALIFIED (type))
write_char ('O');
else
write_char ('R');
}
write_char ('E'); write_char ('E');
} }
......
// 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 <typename T>
void m(T A::*) {}
// { dg-final { scan-assembler "_Z1nIM1AFvvOEEvT_" } }
// { dg-final { scan-assembler "_Z1nIM1AFvvREEvT_" } }
// { dg-final { scan-assembler "_Z1nIM1AKFvvREEvT_" } }
template <typename T>
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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment