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>
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
* decl2.c (reparse_absdcl_as_casts): Don't digest_init if we
are processing a template decl.
......
/* 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);
......
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.
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