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
This commit is contained in:
Nathan Sidwell 2002-01-02 11:32:34 +00:00 committed by Nathan Sidwell
parent 903c623438
commit 4542128ef1
5 changed files with 141 additions and 4 deletions

View file

@ -1,3 +1,11 @@
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

View file

@ -1,6 +1,6 @@
/* Build expressions with type checking for C++ compiler.
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)
This file is part of GNU CC.
@ -4286,9 +4286,15 @@ build_x_unary_op (code, xarg)
if (!ptrmem && !flag_ms_extensions
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
/* A single non-static member, make sure we don't allow a
pointer-to-member. */
xarg = ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE);
{
/* A single non-static member, make sure we don't allow a
pointer-to-member. */
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)
warning ("taking address of temporary");
@ -4849,6 +4855,22 @@ unary_complex_lvalue (code, arg)
error ("taking address of bound pointer-to-member expression");
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_pointer_type (type);

View file

@ -1,3 +1,8 @@
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.

View file

@ -0,0 +1,66 @@
// { 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;
}

View file

@ -0,0 +1,36 @@
// { 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;
}