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]

[C++ PATCH] More fixes for bug 91


Hi,
My last patch fixed cv qualified bases, I'd not verified the same for members.
It turned out we got that wrong for both the copy ctor and assignment op.
Here's the obvious patch, which I've installed.

built & tested on i686-pc-linux-gnu.

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
2000-11-30  Nathan Sidwell  <nathan@codesourcery.com>

	* method.c (do_build_copy_constructor): Preserve cv
	qualifications when accessing source object members.
	(do_build_assign_ref): Likewise. Remove separate diagnostics for
	unnamed fields.

Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/method.c,v
retrieving revision 1.181
diff -c -3 -p -r1.181 method.c
*** method.c	2000/11/30 16:03:15	1.181
--- method.c	2000/11/30 16:18:41
*************** do_build_copy_constructor (fndecl)
*** 2341,2346 ****
--- 2341,2347 ----
        tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
        tree member_init_list = NULL_TREE;
        tree base_init_list = NULL_TREE;
+       int cvquals = CP_TYPE_QUALS (TREE_TYPE (parm));
        int i;
  
        /* Initialize all the base-classes.  */
*************** do_build_copy_constructor (fndecl)
*** 2387,2393 ****
  	  else
  	    continue;
  
! 	  init = build (COMPONENT_REF, TREE_TYPE (field), init, field);
  	  init = build_tree_list (NULL_TREE, init);
  
  	  member_init_list
--- 2388,2396 ----
  	  else
  	    continue;
  
! 	  init = build (COMPONENT_REF,
! 	                build_qualified_type (TREE_TYPE (field), cvquals),
! 	                init, field);
  	  init = build_tree_list (NULL_TREE, init);
  
  	  member_init_list
*************** do_build_assign_ref (fndecl)
*** 2423,2435 ****
        tree fields = TYPE_FIELDS (current_class_type);
        int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
        tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
        int i;
  
        for (i = 0; i < n_bases; ++i)
  	{
  	  tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
! 	  tree p = build_qualified_type
! 	      (basetype, CP_TYPE_QUALS (TREE_TYPE (parm)));
  
  	  p = convert_to_reference
  	    (build_reference_type (p), parm,
--- 2426,2438 ----
        tree fields = TYPE_FIELDS (current_class_type);
        int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
        tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
+       int cvquals = CP_TYPE_QUALS (TREE_TYPE (parm));
        int i;
  
        for (i = 0; i < n_bases; ++i)
  	{
  	  tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
! 	  tree p = build_qualified_type (basetype, cvquals);
  
  	  p = convert_to_reference
  	    (build_reference_type (p), parm,
*************** do_build_assign_ref (fndecl)
*** 2449,2466 ****
  
  	  if (CP_TYPE_CONST_P (TREE_TYPE (field)))
  	    {
! 	      if (DECL_NAME (field))
! 		cp_error ("non-static const member `%#D', can't use default assignment operator", field);
! 	      else
! 		cp_error ("non-static const member in type `%T', can't use default assignment operator", current_class_type);
  	      continue;
  	    }
  	  else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
  	    {
! 	      if (DECL_NAME (field))
! 		cp_error ("non-static reference member `%#D', can't use default assignment operator", field);
! 	      else
! 		cp_error ("non-static reference member in type `%T', can't use default assignment operator", current_class_type);
  	      continue;
  	    }
  
--- 2452,2463 ----
  
  	  if (CP_TYPE_CONST_P (TREE_TYPE (field)))
  	    {
!               cp_error ("non-static const member `%#D', can't use default assignment operator", field);
  	      continue;
  	    }
  	  else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
  	    {
! 	      cp_error ("non-static reference member `%#D', can't use default assignment operator", field);
  	      continue;
  	    }
  
*************** do_build_assign_ref (fndecl)
*** 2487,2493 ****
  	    continue;
  
  	  comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field);
! 	  init = build (COMPONENT_REF, TREE_TYPE (field), init, field);
  
  	  finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
  	}
--- 2484,2492 ----
  	    continue;
  
  	  comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field);
! 	  init = build (COMPONENT_REF,
! 	                build_qualified_type (TREE_TYPE (field), cvquals),
! 	                init, field);
  
  	  finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
  	}
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 28 Nov 2000 <nathan@codesourcery.com>

// Related to bug 91. We'd not preserve constness accessing a member of the
// source type in copy ctor and assignment op.

#include <stdio.h>

int glob = 0;

struct A
{
  A() {}

  A( A& arg) 
  { printf ("%s\n", __PRETTY_FUNCTION__); glob = 1;}

  A( const A& arg)
  { printf ("%s\n", __PRETTY_FUNCTION__); glob = 2;}

  A& operator=( A& ) 
  { printf ("%s\n", __PRETTY_FUNCTION__); glob = 3; return *this; }

  A& operator=( const A& ) 
  { printf ("%s\n", __PRETTY_FUNCTION__); glob = 4; return *this; }
};

struct B
{
  A a;
  B () {}
};

void foo( A& )
{
  printf ("%s\n", __PRETTY_FUNCTION__); glob = 5;
}

void foo( const A& )
{
 printf ("%s\n", __PRETTY_FUNCTION__); glob = 6;
}

int main()
{
  const A a0;
  glob = 0; printf ("A(cA) : ");  A a1(a0); if (glob != 2) return 1;
  glob = 0; printf ("A(A ) : ");  A a2(a1); if (glob != 1) return 2;
  
  const B b0;
  glob = 0; printf ("B(cB) : ");  B b1(b0); if (glob != 2) return 3;
  glob = 0; printf ("B(B ) : ");  B b2(b1); if (glob != 2) return 4;

  glob = 0; printf ("A= cA : ");  a1 = a0; if (glob != 4) return 5;
  glob = 0; printf ("A= A : ");   a1 = a2; if (glob != 3) return 6;
  glob = 0; printf ("B= cB : ");  b1 = b0; if (glob != 4) return 7;
  glob = 0; printf ("B= B : ");   b1 = b2; if (glob != 4) return 8;

  glob = 0; printf ("foo(cB): "); foo(b0.a); if (glob != 6) return 9;
  glob = 0; printf ("foo(B ): "); foo(b2.a); if (glob != 5) return 10;

  return 0;
}

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