Commit 4542128e by Nathan Sidwell Committed by Nathan Sidwell

re PR c++/4379 (Member pointer to member reference not allowed when declared…

re PR c++/4379 (Member pointer to member reference not allowed when declared directly, but allowed as template parameter.)

cp:
	PR c++/4379
	* typeck.c (build_x_unary_op): Don't destroy the OFFSET_REF on a
	single non-static member.
	(unary_complex_lvalue): If it cannot be a pointer to member, don't
	make it so. Check it is not pointer to reference.
testsuite:
	* g++.dg/other/ptrmem1.C: New test.
	* g++.dg/other/ptrmem2.C: New test.

From-SVN: r48465
parent 903c6234
2002-01-02 Nathan Sidwell <nathan@codesourcery.com> 2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
PR c++/4379
* typeck.c (build_x_unary_op): Don't destroy the OFFSET_REF on a
single non-static member.
(unary_complex_lvalue): If it cannot be a pointer to member, don't
make it so. Check it is not pointer to reference.
2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
PR c++/5132 PR c++/5132
* decl2.c (reparse_absdcl_as_casts): Don't digest_init if we * decl2.c (reparse_absdcl_as_casts): Don't digest_init if we
are processing a template decl. are processing a template decl.
......
/* Build expressions with type checking for C++ compiler. /* Build expressions with type checking for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001 Free Software Foundation, Inc. 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com) Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC. This file is part of GNU CC.
...@@ -4286,9 +4286,15 @@ build_x_unary_op (code, xarg) ...@@ -4286,9 +4286,15 @@ build_x_unary_op (code, xarg)
if (!ptrmem && !flag_ms_extensions if (!ptrmem && !flag_ms_extensions
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE) && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
{
/* A single non-static member, make sure we don't allow a /* A single non-static member, make sure we don't allow a
pointer-to-member. */ pointer-to-member. */
xarg = ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE); xarg = build (OFFSET_REF, TREE_TYPE (xarg),
TREE_OPERAND (xarg, 0),
ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE));
PTRMEM_OK_P (xarg) = ptrmem;
}
} }
else if (TREE_CODE (xarg) == TARGET_EXPR) else if (TREE_CODE (xarg) == TARGET_EXPR)
warning ("taking address of temporary"); warning ("taking address of temporary");
...@@ -4849,6 +4855,22 @@ unary_complex_lvalue (code, arg) ...@@ -4849,6 +4855,22 @@ unary_complex_lvalue (code, arg)
error ("taking address of bound pointer-to-member expression"); error ("taking address of bound pointer-to-member expression");
return error_mark_node; return error_mark_node;
} }
if (!PTRMEM_OK_P (arg))
{
/* This cannot form a pointer to method, so we must
resolve the offset ref, and take the address of the
result. For instance,
&(C::m) */
arg = resolve_offset_ref (arg);
return build_unary_op (code, arg, 0);
}
if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
{
error ("cannot create pointer to reference member `%D'", t);
return error_mark_node;
}
type = build_offset_type (DECL_FIELD_CONTEXT (t), TREE_TYPE (t)); type = build_offset_type (DECL_FIELD_CONTEXT (t), TREE_TYPE (t));
type = build_pointer_type (type); type = build_pointer_type (type);
......
2002-01-02 Nathan Sidwell <nathan@codesourcery.com> 2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/other/ptrmem1.C: New test.
* g++.dg/other/ptrmem2.C: New test.
2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/template/ctor1.C: New test. * g++.dg/template/ctor1.C: New test.
2002-01-02 Nathan Sidwell <nathan@codesourcery.com> 2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
......
// { dg-do run }
// Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 31 Dec 2001 <nathan@codesourcery.com>
// PR 4379. We created pointers to member references and pointers to
// member fields when we shouldn't have.
int gs;
int gm;
struct D {
D () :m (gm) {}
int &m;
static int &s;
int Foo ();
};
int &D::s = gs;
template<class T> int f1(T x)
{
return x != &gm;
}
template<class T> int f2(T x)
{
return x != &gs;
}
int D::Foo ()
{
int r;
if (f1( &(D::m)))
return 3;
if (f2( &D::s))
return 1;
if (f2( &(D::s)))
return 2;
return 0;
}
int Foo ()
{
if (f2( &D::s))
return 4;
if (f2( &(D::s)))
return 5;
return 0;
}
int main ()
{
D d;
int r = d.Foo ();
if (r)
return r;
r = Foo ();
if (r)
return r;
return 0;
}
// { dg-do compile }
// Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 31 Dec 2001 <nathan@codesourcery.com>
// PR 4379. We created pointers to member references and pointers to
// member fields when we shouldn't have.
struct D {
int &m; // { dg-error "member `D::m' is non-static" "" }
static int &s;
int Foo ();
};
template<class T> int f1(T x);
template<class T> int f2(T x);
int D::Foo ()
{
f1( &D::m); // { dg-error "cannot create pointer to ref" "" }
f1( &(D::m)); // ok
f2( &D::s); // ok
f2( &(D::s)); // ok
return 0;
}
int Foo ()
{
f1( &D::m); // { dg-error "cannot create pointer to ref" "" }
f1( &(D::m)); // { dg-error "at this point" "" }
f2( &D::s); // ok
f2( &(D::s)); // ok
return 0;
}
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