This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH]: Fix bug 4379
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: mark at codesourcery dot com
- Date: Mon, 31 Dec 2001 13:51:16 +0000
- Subject: [C++ PATCH]: Fix bug 4379
- Organization: Codesourcery LLC
Hi,
this fixes bug 4379, and a few other pointer to member data problems.
We were creating pointer to members for data members with reference
type. Also, we'd create pointers to data member on things like
&(C::m), which isn't one. If m is static, that is a plain pointer,
if m is non-static and we are in a member function of C, that is a pointer
to this->C::m, otherwise it is ill-formed.
built & tested on i686-pc-linux-gnu, ok?
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-12-31 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.
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.379
diff -c -3 -p -r1.379 typeck.c
*** typeck.c 2001/12/29 17:10:07 1.379
--- typeck.c 2001/12/31 13:39:00
*************** build_x_unary_op (code, xarg)
*** 4286,4294 ****
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);
}
else if (TREE_CODE (xarg) == TARGET_EXPR)
warning ("taking address of temporary");
--- 4286,4300 ----
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 = 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");
*************** unary_complex_lvalue (code, arg)
*** 4847,4852 ****
--- 4853,4874 ----
&& TREE_CODE (t) != FIELD_DECL)
{
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;
}
// { 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;
}