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 PR 164


Hi,
this fixes bug 164 where we fail to synthesize copy ctor and assignment
operator due to an ambiguous direct base.  Although the C++ programmer
cannot access that base, I don't think it should prevent those functions
being synthesized.

booted & tested on i686-pc-linux-gnu, ok (for mainline)

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

	PR g++/164
	* init.c (sort_base_init): Allow binfos to be directly specified.
	* method.c (do_build_copy_constructor): Explicitly convert to the
	base instance.
	(do_build_assign_ref): Likewise.

Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.253
diff -c -3 -p -r1.253 init.c
*** init.c	2001/11/29 17:15:55	1.253
--- init.c	2001/11/29 20:29:11
*************** sort_base_init (t, base_init_list, rbase
*** 556,562 ****
    for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x))
      {
        tree basetype = TREE_PURPOSE (x);
!       tree binfo = binfo_or_else (basetype, t);
        
        if (binfo == NULL_TREE)
  	/* BASETYPE might be an inaccessible direct base (because it
--- 556,563 ----
    for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x))
      {
        tree basetype = TREE_PURPOSE (x);
!       tree binfo = (TREE_CODE (basetype) == TREE_VEC
! 		    ? basetype : binfo_or_else (basetype, t));
        
        if (binfo == NULL_TREE)
  	/* BASETYPE might be an inaccessible direct base (because it
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.210
diff -c -3 -p -r1.210 method.c
*** method.c	2001/11/22 02:32:56	1.210
--- method.c	2001/11/29 20:29:20
*************** do_build_copy_constructor (fndecl)
*** 554,578 ****
        int cvquals = cp_type_quals (TREE_TYPE (parm));
        int i;
  
!       /* Initialize all the base-classes with the parameter converted to
!          their type so that we get their copy constructor and not another
!          constructor that takes current_class_type.  */
        for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
  	   t = TREE_CHAIN (t))
  	{
! 	  tree type = BINFO_TYPE (TREE_VALUE (t));
! 	  base_init_list = tree_cons (type, convert_lvalue (type, parm),
  				      base_init_list);
  	}
  
        for (i = 0; i < n_bases; ++i)
  	{
! 	  t = TREE_VEC_ELT (binfos, i);
! 	  if (TREE_VIA_VIRTUAL (t))
  	    continue; 
  
! 	  t = BINFO_TYPE (t);
! 	  base_init_list = tree_cons (t, convert_lvalue (t, parm),
  				      base_init_list);
  	}
  
--- 554,584 ----
        int cvquals = cp_type_quals (TREE_TYPE (parm));
        int i;
  
!       /* Initialize all the base-classes with the parameter converted
! 	 to their type so that we get their copy constructor and not
! 	 another constructor that takes current_class_type.  We must
! 	 deal with the binfo's directly as a direct base might be
! 	 inaccessible due to ambiguity.  */
        for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
  	   t = TREE_CHAIN (t))
  	{
! 	  tree binfo = TREE_VALUE (t);
! 	  
! 	  base_init_list = tree_cons (binfo,
! 				      build_base_path (PLUS_EXPR, parm,
! 						       binfo, 1),
  				      base_init_list);
  	}
  
        for (i = 0; i < n_bases; ++i)
  	{
! 	  tree binfo = TREE_VEC_ELT (binfos, i);
! 	  if (TREE_VIA_VIRTUAL (binfo))
  	    continue; 
  
! 	  base_init_list = tree_cons (binfo,
! 				      build_base_path (PLUS_EXPR, parm,
! 						       binfo, 1),
  				      base_init_list);
  	}
  
*************** do_build_assign_ref (fndecl)
*** 645,655 ****
  
        for (i = 0; i < n_bases; ++i)
  	{
! 	  tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
! 	  tree p = convert_lvalue (basetype, parm);
! 	  p = build_member_call (basetype, ansi_assopname (NOP_EXPR),
! 				 build_tree_list (NULL_TREE, p));
! 	  finish_expr_stmt (p);
  	}
        for (; fields; fields = TREE_CHAIN (fields))
  	{
--- 651,668 ----
  
        for (i = 0; i < n_bases; ++i)
  	{
! 	  /* We must deal with the binfo's directly as a direct base
! 	     might be inaccessible due to ambiguity.  */
! 	  tree binfo = TREE_VEC_ELT (binfos, i);
! 	  tree src = build_base_path (PLUS_EXPR, parm, binfo, 1);
! 	  tree dst = build_base_path (PLUS_EXPR, current_class_ref, binfo, 1);
! 
! 	  tree expr = build_method_call (dst,
! 					 ansi_assopname (NOP_EXPR),
! 					 build_tree_list (NULL_TREE, src),
! 					 NULL,
! 					 LOOKUP_NORMAL | LOOKUP_NONVIRTUAL);
! 	  finish_expr_stmt (expr);
  	}
        for (; fields; fields = TREE_CHAIN (fields))
  	{
// { dg-do compile }
// { dg-options "-pedantic-errors -w" }

// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 29 Nov 2001 <nathan@nathan@codesourcery.com>

// PR 164
// Although a direct base can be inaccessible due to ambiguity, that
// should not blow up synthesized methods.

struct A {int m;};
struct B : A {int m;};
struct C : virtual A, B {int m;};
struct D : B, C {int m;};

void foo2 ()
{
  D d;
  D e (d);

  e = d;
}

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