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]: Using declarations


Hi,
This patch fixes some faults with using declarations, used to inject
base class members. In particlar, we'd reject

struct B : A {
	struct Foo {};
	using A::Foo; // A::Foo is a member fn of A
};
but accept
struct B : A {
	struct Foo {};
	void Foo ();	// declare local member fn
	using A::Foo; // A::Foo is a member fn of A
};


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-01-03  Nathan Sidwell  <nathan@codesourcery.com>

	* class.c (handle_using_decl): Reject using of constructor name
	of sourcing class. Allow injecting of a method with same name as
	nested class. Fixup error messages.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.346
diff -c -3 -p -r1.346 class.c
*** class.c	2000/12/07 14:26:37	1.346
--- class.c	2000/12/11 10:15:33
*************** handle_using_decl (using_decl, t)
*** 1527,1535 ****
    if (name == constructor_name (ctype)
        || name == constructor_name_full (ctype))
      {
!       cp_error_at ("using-declaration for constructor", using_decl);
        return;
      }
  
    fdecl = lookup_member (binfo, name, 0, 0);
    
--- 1527,1541 ----
    if (name == constructor_name (ctype)
        || name == constructor_name_full (ctype))
      {
!       cp_error_at ("`%D' names constructor", using_decl);
        return;
      }
+   if (name == constructor_name (t)
+       || name == constructor_name_full (t))
+     {
+       cp_error_at ("`%D' invalid in `%T'", using_decl, t);
+       return;
+     }
  
    fdecl = lookup_member (binfo, name, 0, 0);
    
*************** handle_using_decl (using_decl, t)
*** 1567,1582 ****
  	   the same name already present in the current class.  */;
        else
  	{
! 	  cp_error ("`%D' invalid in `%#T'", using_decl, t);
  	  cp_error_at ("  because of local method `%#D' with same name",
  		       OVL_CURRENT (old_value));
  	  return;
  	}
      }
!   else
      {
!       cp_error ("`%D' invalid in `%#T'", using_decl, t);
!       cp_error_at ("  because of local field `%#D' with same name", old_value);
        return;
      }
    
--- 1573,1588 ----
  	   the same name already present in the current class.  */;
        else
  	{
! 	  cp_error_at ("`%D' invalid in `%#T'", using_decl, t);
  	  cp_error_at ("  because of local method `%#D' with same name",
  		       OVL_CURRENT (old_value));
  	  return;
  	}
      }
!   else if (!DECL_ARTIFICIAL (old_value))
      {
!       cp_error_at ("`%D' invalid in `%#T'", using_decl, t);
!       cp_error_at ("  because of local member `%#D' with same name", old_value);
        return;
      }
    
// Build don't link:

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

// We rejected using decls bringing in functions from a base which would hide a
// nested class of the same name, but only if we had no functions by that name
// already. Also, we failed to find that using declaration during lookup. Also
// we failed to reject using declarations which matched the constructor name.

struct A
{
  int f ();
  void D ();
};

struct A2 {
  typedef int f;
};

struct B : A 
{
  using A::f;
  struct f {};
};

struct C : A 
{
  using A::f;
  int f (int);
  struct f {};
};

void foo (B *bp, C* cp)
{
  bp->f ();
  cp->f ();
}

struct D : A
{
  using A::D;   // ERROR - names constructor
};

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