re PR c++/20734 (rejects valid pointer to member)

PR c++/20734
	* cp-tree.def (OFFSET_REF): Correct comments.
	* init.c (build_offset_ref): Remove misleading comment.
	* typeck.c (build_unary_op): Handle pointer-to-member creation
	here, rather than ...
	(unary_complex_lvalue): ... here.

	PR c++/20734
	* g++.dg/template/ptrmem13.C: New test.

From-SVN: r97696
This commit is contained in:
Mark Mitchell 2005-04-06 05:38:34 +00:00 committed by Mark Mitchell
parent 05b205e830
commit 6d05585b75
5 changed files with 42 additions and 53 deletions

View File

@ -31,10 +31,8 @@ Boston, MA 02111-1307, USA. */
BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m').
The expression is a pointer-to-member if its address is taken,
but simply denotes a member of the object if its address isnot
taken. In the latter case, resolve_offset_ref is used to
convert it to a representation of the member referred to by the
OFFSET_REF.
but simply denotes a member of the object if its address is not
taken.
This form is only used during the parsing phase; once semantic
analysis has taken place they are eliminated.

View File

@ -1551,9 +1551,6 @@ build_offset_ref (tree type, tree name, bool address_p)
return member;
}
/* In member functions, the form `type::name' is no longer
equivalent to `this->type::name', at least not until
resolve_offset_ref. */
member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member);
PTRMEM_OK_P (member) = 1;
return member;

View File

@ -4026,6 +4026,29 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
arg = OVL_CURRENT (arg);
break;
case OFFSET_REF:
/* Turn a reference to a non-static data member into a
pointer-to-member. */
{
tree type;
tree t;
if (!PTRMEM_OK_P (arg))
return build_unary_op (code, arg, 0);
t = TREE_OPERAND (arg, 1);
if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
{
error ("cannot create pointer to reference member %qD", t);
return error_mark_node;
}
type = build_ptrmem_type (context_for_name_lookup (t),
TREE_TYPE (t));
t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
return t;
}
default:
break;
}
@ -4182,52 +4205,7 @@ unary_complex_lvalue (enum tree_code code, tree arg)
if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (arg)) == METHOD_TYPE
|| TREE_CODE (arg) == OFFSET_REF)
{
tree t;
gcc_assert (TREE_CODE (arg) != SCOPE_REF);
if (TREE_CODE (arg) != OFFSET_REF)
return 0;
t = TREE_OPERAND (arg, 1);
/* Check all this code for right semantics. */
if (TREE_CODE (t) == FUNCTION_DECL)
{
if (DECL_DESTRUCTOR_P (t))
error ("taking address of destructor");
return build_unary_op (ADDR_EXPR, t, 0);
}
if (TREE_CODE (t) == VAR_DECL)
return build_unary_op (ADDR_EXPR, t, 0);
else
{
tree type;
if (TREE_OPERAND (arg, 0)
&& ! is_dummy_object (TREE_OPERAND (arg, 0))
&& TREE_CODE (t) != FIELD_DECL)
{
error ("taking address of bound pointer-to-member expression");
return error_mark_node;
}
if (!PTRMEM_OK_P (arg))
return build_unary_op (code, arg, 0);
if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
{
error ("cannot create pointer to reference member %qD", t);
return error_mark_node;
}
type = build_ptrmem_type (context_for_name_lookup (t),
TREE_TYPE (t));
t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
return t;
}
}
return NULL_TREE;
/* We permit compiler to make function calls returning
objects of aggregate type look like lvalues. */

View File

@ -1,3 +1,8 @@
2005-04-05 Mark Mitchell <mark@codesourcery.com>
PR c++/20734
* g++.dg/template/ptrmem13.C: New test.
2005-04-05 Per Bothner <per@bothner.com>
* lib/gcc.exp: Always add -fno-show-column, for now.

View File

@ -0,0 +1,11 @@
// PR c++/20734
struct A;
void blah(int A::*);
struct A{
int a;
};
template<typename T>
void hoho(){
blah(&A::a);
}