This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH]: Fix bug 4379


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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]