diff mbox

PR c++/26256

Message ID CAFH4-dhuF8akEZFAWaNVHVFOG=RmTFWwQi5N8qvJm-WyeK9whA@mail.gmail.com
State New
Headers show

Commit Message

Fabien ChĂȘne Sept. 25, 2011, 8:24 p.m. UTC
2011/9/25 Paolo Carlini <pcarlini@gmail.com>:
> ... nitpicking, of course, but in the testcases you have many blank trailing lines (and also some gratuitus, imho, blank lines in the middle)

Indeed, I've removed the blank trailing lines, and some in the middle,
not all though, I like it readable as well ;-)

Comments

Paolo Carlini Sept. 25, 2011, 8:28 p.m. UTC | #1
Hi,

> Indeed, I've removed the blank trailing lines, and some in the middle,
> not all though, I like it readable as well ;-)

Thanks!

Paolo
diff mbox

Patch

Index: gcc/testsuite/g++.old-deja/g++.other/using1.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/using1.C	(revision 178088)
+++ gcc/testsuite/g++.old-deja/g++.other/using1.C	(working copy)
@@ -16,12 +16,12 @@  public:
   using B::b;
 };
 
-class D2 : public B { // { dg-error "" } conflicting access specifications
+class D2 : public B {
 public:
   using B::a;
-  using B::b;
+  using B::b; // { dg-message "" } conflicting declaration
 
 private:
-  using B::b; 
+  using B::b; // { dg-error "" } conflicts
 };
  
Index: gcc/testsuite/g++.dg/debug/using4.C
===================================================================
--- gcc/testsuite/g++.dg/debug/using4.C	(revision 0)
+++ gcc/testsuite/g++.dg/debug/using4.C	(revision 0)
@@ -0,0 +1,24 @@ 
+// PR c++/26256
+// { dg-do compile }
+
+struct A
+{
+    typedef char type;
+};
+
+struct B
+{
+    typedef int type;
+};
+
+struct C : A, B
+{
+    using A::type;
+    type f (type);
+};
+
+C::type C::f( type ) 
+{
+    type c = 'e';
+    return c;
+}
Index: gcc/testsuite/g++.dg/debug/using5.C
===================================================================
--- gcc/testsuite/g++.dg/debug/using5.C	(revision 0)
+++ gcc/testsuite/g++.dg/debug/using5.C	(revision 0)
@@ -0,0 +1,23 @@ 
+// PR c++/26256
+// { dg-do compile }
+
+struct A
+{
+    int i;
+};
+
+struct B
+{
+    int i;
+};
+
+struct C : A, B
+{
+    using B::i;
+    int f ();
+};
+
+int C::f() 
+{
+    return i;
+}
Index: gcc/testsuite/g++.dg/lookup/using36.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using36.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using36.C	(revision 0)
@@ -0,0 +1,31 @@ 
+// PR c++/25994
+// { dg-do run }
+
+struct B1
+{
+  void f (char) {}
+  void f (double) { __builtin_abort(); }
+};
+
+struct B2
+{
+  void f (double) { __builtin_abort(); }
+  void f (int) {}
+};
+
+struct D : public B1, public B2
+{
+  using B1::f;
+  using B2::f;
+  void g ()
+  {
+    f ('a');           // should call B1::f(char)
+    f (33);            // should call B2::f(int)
+  }
+};
+
+int main()
+{
+  D d;
+  d.g();
+}
Index: gcc/testsuite/g++.dg/lookup/using24.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using24.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using24.C	(revision 0)
@@ -0,0 +1,12 @@ 
+// PR c++/26256
+// { dg-do compile }
+
+struct A { int next; };
+struct B { int next; };
+struct C : B { using B::next; };
+
+struct D : A, C
+{
+   using C::next;
+   void f() { next = 1; }
+};
Index: gcc/testsuite/g++.dg/lookup/using28.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using28.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using28.C	(revision 0)
@@ -0,0 +1,11 @@ 
+// PR c++/26256
+// { dg-do compile }
+
+struct A { int f; };
+struct B { int f; };
+struct C : A, B { using B::f; };
+
+struct D : C
+{
+    void g() { f = 1; }
+};
Index: gcc/testsuite/g++.dg/lookup/using33.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using33.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using33.C	(revision 0)
@@ -0,0 +1,26 @@ 
+// { dg-do run }
+
+template <class T>
+struct Foo 
+{
+  int k (float) {return 0;}
+};
+
+template <class T>
+struct Baz 
+{
+  int k (int) {return 1;}
+};
+
+template <class T>
+struct Bar : Foo<T> , Baz<T>
+{
+  using Foo<T>::k;
+  using Baz<T>::k;
+};
+
+int main()
+{
+  Bar<int> bar;
+  return bar.k( 1.0f );
+}
Index: gcc/testsuite/g++.dg/lookup/using25.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using25.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using25.C	(revision 0)
@@ -0,0 +1,28 @@ 
+// PR c++/26256
+// { dg-do run }
+
+struct A 
+{
+    int next; 
+};
+
+struct B 
+{
+    int next; 
+};
+
+struct C : public A, public B 
+{
+    using A::next; 
+};
+
+void foo(C& c) { c.next = 42; }
+
+int main()
+{
+    C c;
+    foo (c);
+    c.B::next = 12;
+    if (c.next != 42 || c.A::next != 42 || c.B::next != 12)
+    	__builtin_abort();
+}
Index: gcc/testsuite/g++.dg/lookup/using29.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using29.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using29.C	(revision 0)
@@ -0,0 +1,81 @@ 
+// { dg-do compile }
+
+struct A 
+{
+  int i;
+};
+
+struct B
+{
+  int i;
+};
+
+struct C : A, B
+{
+  using A::i; // { dg-error "conflicts with previous" }
+  using B::i; // { dg-error "declaration" }
+};
+
+struct E
+{
+  typedef int type;
+};
+
+struct F
+{
+  typedef int type;
+};
+
+struct G : E, F
+{
+  using E::type; // { dg-error "conflicts with previous" }
+  using F::type; // { dg-error "declaration" }
+};
+
+struct H
+{
+  typedef int type;
+};
+
+struct I : H
+{
+  typedef int type; // { dg-error "conflicts with previous" }
+  using H::type; // { dg-error "declaration" }
+};
+
+struct I2 : H
+{
+  using H::type; // { dg-error "conflicts with previous" }
+  typedef int type; // { dg-error "declaration" }
+};
+
+struct J
+{
+  struct type {};
+};
+
+struct K : J
+{
+  struct type {}; // { dg-error "conflicts with previous" }
+  using J::type; // { dg-error "declaration" }
+};
+
+struct L : J
+{
+  using J::type; // { dg-error "conflicts with previous" }
+  struct type {}; // { dg-error "declaration" }
+};
+
+struct M
+{
+  typedef int type;
+  struct type2 {};
+};
+
+struct N : M
+{
+  using M::type; // { dg-error "conflicts with previous" }
+  using M::type; // { dg-error "declaration" }
+  using M::type2; // { dg-error "conflicts with previous" }
+  using M::type2; // { dg-error "declaration" }
+};
Index: gcc/testsuite/g++.dg/lookup/using30.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using30.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using30.C	(revision 0)
@@ -0,0 +1,8 @@ 
+// { dg-do compile }
+
+struct H { typedef int type; };
+struct J : H
+{
+  struct type {}; // { dg-error "conflicts with previous" }
+  using H::type; // { dg-error "declaration" }
+};
Index: gcc/testsuite/g++.dg/lookup/using34.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using34.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using34.C	(revision 0)
@@ -0,0 +1,10 @@ 
+// { dg-do compile }
+
+struct A { int f (); };
+struct B : A 
+{
+  using A::f;
+  struct f {};
+  void g() { f(); struct f ff; }
+  struct f ff;
+};
Index: gcc/testsuite/g++.dg/lookup/using26.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using26.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using26.C	(revision 0)
@@ -0,0 +1,27 @@ 
+// PR c++/26256
+// { dg-do compile }
+
+struct A 
+{
+    double next; 
+};
+
+struct B 
+{
+private:
+    int next; // { dg-error "private" }
+};
+
+struct C
+{
+    int next;
+};
+
+struct D : A, B, C // { dg-error "context" }
+{
+    using B::next;
+    void f()
+    {
+	next = 12;
+    }
+};
Index: gcc/testsuite/g++.dg/lookup/using31.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using31.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using31.C	(revision 0)
@@ -0,0 +1,8 @@ 
+// { dg-do compile }
+
+struct H2 { int f (); };
+struct J2 : H2
+{
+  struct f {};
+  using H2::f;
+};
Index: gcc/testsuite/g++.dg/lookup/using35.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using35.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using35.C	(revision 0)
@@ -0,0 +1,11 @@ 
+// { dg-do compile }
+
+struct A { typedef int type; };
+struct B { typedef int type; };
+struct C : B { using B::type; };
+
+struct D : A, C
+{
+  using C::type;
+  void f() { type t = 0;}
+};
Index: gcc/testsuite/g++.dg/lookup/using23.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using23.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using23.C	(revision 0)
@@ -0,0 +1,19 @@ 
+// PR c++/26256
+// { dg-do compile }
+
+struct A
+{
+private:
+    typedef int type; // { dg-error "private" }
+};
+
+struct B
+{
+    typedef double type;
+};
+
+struct C : A, B // { dg-error "context" }
+{
+    using A::type; 
+    type d;
+};
Index: gcc/testsuite/g++.dg/lookup/using27.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using27.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using27.C	(revision 0)
@@ -0,0 +1,48 @@ 
+// PR c++/26256
+// { dg-do run }
+
+struct A
+{
+    typedef int type;
+};
+
+struct B
+{
+    typedef double type;
+};
+
+struct C : A, B
+{
+    using A::type;
+    type d;
+
+    void f()
+    {
+    	type e;
+    	if (sizeof (type) != sizeof (A::type))
+    	    __builtin_abort();
+    }
+
+    void g();
+};
+
+void C::g()
+{
+    type x;
+    if (sizeof (type) != sizeof (A::type))
+    	__builtin_abort();
+}
+
+int main ()
+{
+    if (sizeof (C::type) != sizeof (A::type))
+    	__builtin_abort();
+
+    if (sizeof (C::d) != sizeof (A::type))
+    	__builtin_abort();
+
+    C::type x;
+    C c;
+    c.f();
+    c.g();
+}
Index: gcc/testsuite/g++.dg/lookup/using32.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using32.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using32.C	(revision 0)
@@ -0,0 +1,9 @@ 
+// { dg-do compile }
+
+struct T { struct type {}; };
+struct T2 : T { using T::type; };
+struct T3 : T2
+{
+  struct type {};
+  type t;
+};
Index: gcc/testsuite/g++.dg/cpp0x/forw_enum10.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/forw_enum10.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/forw_enum10.C	(revision 0)
@@ -0,0 +1,32 @@ 
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+//This error is diagnosed at instantiation time
+template<typename T> struct S1
+{
+    enum E : T;   // { dg-error "previous definition" }
+    enum E : int;     // { dg-error "different underlying type" }
+};
+template struct S1<short>; // { dg-message "required from here" }
+
+template<typename T> struct S2
+{
+    enum E : T;
+    enum E : T;
+};
+template struct S2<short>;
+
+template<typename T1, typename T2> struct S3
+{
+    enum E : T1;
+    enum E : T2;
+};
+template struct S3<short,short>;
+
+template<typename T1, typename T2> struct S4
+{
+    enum E : T1; // { dg-error "previous definition" }
+    enum E : T2; // { dg-error "different underlying type" }
+};
+template struct S4<short,char>; // { dg-message "required from here" }
+
Index: gcc/testsuite/g++.dg/template/using2.C
===================================================================
--- gcc/testsuite/g++.dg/template/using2.C	(revision 178088)
+++ gcc/testsuite/g++.dg/template/using2.C	(working copy)
@@ -7,24 +7,25 @@ 
 
 template <class T>
 struct Foo {
-  int i; // { dg-error "Foo" }
+  int i;
 };
 
 struct Baz 
 {
-  int i; // { dg-error "Baz" }
+  int i;
 };
 
 template <class T>
-struct Bar : public Foo<T>, Baz {
-  using Foo<T>::i;
-  using Baz::i;
+struct Bar : public Foo<T>, Baz 
+{
+  using Foo<T>::i; // { dg-message "conflicts with previous" } 
+  using Baz::i; // { dg-error "declaration" } 
 
-  int foo () { return i; } // { dg-error "request for member" }
+  int foo () { return i; }
 };
 
 void foo (Bar<int> &bar)
 {
-  bar.foo(); // { dg-message "required" }
+  bar.foo();
 }
 
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 178088)
+++ gcc/cp/typeck.c	(working copy)
@@ -2109,6 +2109,7 @@  build_class_member_access_expr (tree obj
   tree object_type;
   tree member_scope;
   tree result = NULL_TREE;
+  tree using_decl = NULL_TREE;
 
   if (error_operand_p (object) || error_operand_p (member))
     return error_mark_node;
@@ -2329,6 +2330,11 @@  build_class_member_access_expr (tree obj
 	result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
 			 object, result);
     }
+  else if ((using_decl = strip_using_decl (member)) != member)
+    result = build_class_member_access_expr (object,
+  					     using_decl,
+  					     access_path, preserve_reference,
+  					     complain);
   else
     {
       if (complain & tf_error)
Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c	(revision 178088)
+++ gcc/cp/class.c	(working copy)
@@ -1053,9 +1053,6 @@  add_method (tree type, tree method, tree
 		return false;
 	      if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
 		error ("repeated using declaration %q+D", using_decl);
-	      else
-		error ("using declaration %q+D conflicts with a previous using declaration",
-		       using_decl);
 	    }
 	  else
 	    {
@@ -3016,15 +3013,8 @@  check_field_decls (tree t, tree *access_
 
       if (TREE_CODE (x) == USING_DECL)
 	{
-	  /* Prune the access declaration from the list of fields.  */
-	  *field = DECL_CHAIN (x);
-
 	  /* Save the access declarations for our caller.  */
 	  *access_decls = tree_cons (NULL_TREE, x, *access_decls);
-
-	  /* Since we've reset *FIELD there's no reason to skip to the
-	     next field.  */
-	  next = field;
 	  continue;
 	}
 
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 178088)
+++ gcc/cp/decl.c	(working copy)
@@ -11937,8 +11937,20 @@  start_enum (tree name, tree enumtype, tr
 	    *is_new = true;
 	}
       prevtype = enumtype;
-      enumtype = cxx_make_type (ENUMERAL_TYPE);
-      enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
+
+      /* do not push the decl more than once */
+      if (!enumtype
+	  || (underlying_type
+	      && dependent_type_p (underlying_type))
+	  || (ENUM_UNDERLYING_TYPE (enumtype)
+	      && dependent_type_p (ENUM_UNDERLYING_TYPE (enumtype))))
+	{
+	  enumtype = cxx_make_type (ENUMERAL_TYPE);
+      	  enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
+	}
+      else
+	  enumtype = xref_tag (enum_type, name, /*tag_scope=*/ts_current, false);
+
       if (enumtype == error_mark_node)
 	return error_mark_node;
 
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 178088)
+++ gcc/cp/semantics.c	(working copy)
@@ -2670,8 +2670,7 @@  finish_member_declaration (tree decl)
 	}
     }
   /* Enter the DECL into the scope of the class.  */
-  else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
-	   || pushdecl_class_level (decl))
+  else if (pushdecl_class_level (decl))
     {
       /* All TYPE_DECLs go at the end of TYPE_FIELDS.  Ordinary fields
 	 go at the beginning.  The reason is that lookup_field_1
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 178088)
+++ gcc/cp/parser.c	(working copy)
@@ -13046,6 +13046,9 @@  cp_parser_nonclass_name (cp_parser* pars
   /* Look up the type-name.  */
   type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
 
+  /* If it is a using decl, use its underlying decl.  */
+  type_decl = strip_using_decl (type_decl);
+
   if (TREE_CODE (type_decl) != TYPE_DECL
       && (objc_is_id (identifier) || objc_is_class_name (identifier)))
     {
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 178088)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -5776,7 +5776,8 @@  extern void cxx_omp_finish_clause		(tree
 extern bool cxx_omp_privatize_by_reference	(const_tree);
 
 /* in name-lookup.c */
-extern void suggest_alternatives_for (location_t, tree);
+extern void suggest_alternatives_for            (location_t, tree);
+extern tree strip_using_decl                    (tree);
 
 /* -- end of C++ */
 
Index: gcc/cp/search.c
===================================================================
--- gcc/cp/search.c	(revision 178088)
+++ gcc/cp/search.c	(working copy)
@@ -1,7 +1,7 @@ 
 /* Breadth-first and depth-first routines for
    searching multiple-inheritance lattice for GNU C++.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+   1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -449,6 +449,8 @@  lookup_field_1 (tree type, tree name, bo
 #endif /* GATHER_STATISTICS */
   for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
     {
+      tree decl = field;
+
 #ifdef GATHER_STATISTICS
       n_fields_searched++;
 #endif /* GATHER_STATISTICS */
@@ -460,26 +462,19 @@  lookup_field_1 (tree type, tree name, bo
 	  if (temp)
 	    return temp;
 	}
-      if (TREE_CODE (field) == USING_DECL)
+      
+      if (TREE_CODE (decl) == USING_DECL)
 	{
-	  /* We generally treat class-scope using-declarations as
-	     ARM-style access specifications, because support for the
-	     ISO semantics has not been implemented.  So, in general,
-	     there's no reason to return a USING_DECL, and the rest of
-	     the compiler cannot handle that.  Once the class is
-	     defined, USING_DECLs are purged from TYPE_FIELDS; see
-	     handle_using_decl.  However, we make special efforts to
-	     make using-declarations in class templates and class
-	     template partial specializations work correctly.  */
-	  if (!DECL_DEPENDENT_P (field))
+	  decl = strip_using_decl (decl);
+	  if (is_overloaded_fn (decl))
 	    continue;
 	}
 
-      if (DECL_NAME (field) == name
+      if (DECL_NAME (decl) == name
 	  && (!want_type
-	      || TREE_CODE (field) == TYPE_DECL
-	      || DECL_CLASS_TEMPLATE_P (field)))
-	return field;
+	      || TREE_CODE (decl) == TYPE_DECL
+	      || DECL_CLASS_TEMPLATE_P (decl)))
+	return decl;
     }
   /* Not found.  */
   if (name == vptr_identifier)
@@ -1423,7 +1418,7 @@  lookup_fnfields_1 (tree type, tree name)
 #endif /* GATHER_STATISTICS */
 
 	  tmp = VEC_index (tree, method_vec, i);
-	  tmp = DECL_NAME (OVL_CURRENT (tmp));
+	  tmp = DECL_NAME (strip_using_decl (OVL_CURRENT (tmp)));
 	  if (tmp > name)
 	    hi = i;
 	  else if (tmp < name)
@@ -1438,7 +1433,7 @@  lookup_fnfields_1 (tree type, tree name)
 #ifdef GATHER_STATISTICS
 	n_outer_fields_searched++;
 #endif /* GATHER_STATISTICS */
-	if (DECL_NAME (OVL_CURRENT (fn)) == name)
+	if (DECL_NAME (strip_using_decl (OVL_CURRENT (fn))) == name)
 	  return i;
       }
 
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 178088)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -394,6 +394,16 @@  pop_binding (tree id, tree decl)
     }
 }
 
+/* Strip non dependent using declarations.  */
+
+tree
+strip_using_decl (tree decl)
+{
+  while (TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
+    decl = USING_DECL_DECLS (decl);
+  return decl;
+}
+
 /* BINDING records an existing declaration for a name in the current scope.
    But, DECL is another declaration for that same identifier in the
    same scope.  This is the `struct stat' hack whereby a non-typedef
@@ -417,29 +427,45 @@  supplement_binding_1 (cxx_binding *bindi
 {
   tree bval = binding->value;
   bool ok = true;
+  tree target_bval = strip_using_decl (bval);
+  tree target_decl = strip_using_decl (decl);
 
-  if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
+  if (TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL (target_decl)
+      && target_decl != target_bval
+      && (TREE_CODE (target_bval) != TYPE_DECL
+	  /* We allow pushing an enum multiple times in a class
+	   * template in order to handle late matching of underlying
+	   * type on an opaque-enum-declaration followed by an
+	   * enum-specifier.  */
+	  || (TREE_CODE (TREE_TYPE (target_decl)) == ENUMERAL_TYPE
+	      && TREE_CODE (TREE_TYPE (target_bval)) == ENUMERAL_TYPE
+	      && (dependent_type_p (ENUM_UNDERLYING_TYPE
+	      	 		    (TREE_TYPE (target_decl)))
+	      	  || dependent_type_p (ENUM_UNDERLYING_TYPE
+	      	 		       (TREE_TYPE (target_bval))))
+	       )))
     /* The new name is the type name.  */
     binding->type = decl;
-  else if (/* BVAL is null when push_class_level_binding moves an
+  else if (/* TARGET_BVAL is null when push_class_level_binding moves an
 	      inherited type-binding out of the way to make room for a
 	      new value binding.  */
-	   !bval
-	   /* BVAL is error_mark_node when DECL's name has been used
+	   !target_bval
+	   /* TARGET_BVAL is error_mark_node when TARGET_DECL's name has been used
 	      in a non-class scope prior declaration.  In that case,
 	      we should have already issued a diagnostic; for graceful
 	      error recovery purpose, pretend this was the intended
 	      declaration for that name.  */
-	   || bval == error_mark_node
-	   /* If BVAL is anticipated but has not yet been declared,
+	   || target_bval == error_mark_node
+	   /* If TARGET_BVAL is anticipated but has not yet been declared,
 	      pretend it is not there at all.  */
-	   || (TREE_CODE (bval) == FUNCTION_DECL
-	       && DECL_ANTICIPATED (bval)
-	       && !DECL_HIDDEN_FRIEND_P (bval)))
+	   || (TREE_CODE (target_bval) == FUNCTION_DECL
+	       && DECL_ANTICIPATED (target_bval)
+	       && !DECL_HIDDEN_FRIEND_P (target_bval)))
     binding->value = decl;
-  else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
-	   && (TREE_CODE (decl) != TYPE_DECL
-	       || same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))))
+  else if (TREE_CODE (target_bval) == TYPE_DECL && DECL_ARTIFICIAL (target_bval)
+    	   && target_decl != target_bval
+	   && (TREE_CODE (target_decl) != TYPE_DECL
+	       || same_type_p (TREE_TYPE (target_decl), TREE_TYPE (target_bval))))
     {
       /* The old binding was a type name.  It was placed in
 	 VALUE field because it was thought, at the point it was
@@ -450,15 +476,15 @@  supplement_binding_1 (cxx_binding *bindi
       binding->value = decl;
       binding->value_is_inherited = false;
     }
-  else if (TREE_CODE (bval) == TYPE_DECL
-	   && TREE_CODE (decl) == TYPE_DECL
-	   && DECL_NAME (decl) == DECL_NAME (bval)
+  else if (TREE_CODE (target_bval) == TYPE_DECL
+	   && TREE_CODE (target_decl) == TYPE_DECL
+	   && DECL_NAME (target_decl) == DECL_NAME (target_bval)
 	   && binding->scope->kind != sk_class
-	   && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))
+	   && (same_type_p (TREE_TYPE (target_decl), TREE_TYPE (target_bval))
 	       /* If either type involves template parameters, we must
 		  wait until instantiation.  */
-	       || uses_template_parms (TREE_TYPE (decl))
-	       || uses_template_parms (TREE_TYPE (bval))))
+	       || uses_template_parms (TREE_TYPE (target_decl))
+	       || uses_template_parms (TREE_TYPE (target_bval))))
     /* We have two typedef-names, both naming the same type to have
        the same name.  In general, this is OK because of:
 
@@ -480,9 +506,9 @@  supplement_binding_1 (cxx_binding *bindi
 
        A member shall not be declared twice in the
        member-specification.  */
-  else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (bval) == VAR_DECL
-	   && DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval)
-	   && !DECL_CLASS_SCOPE_P (decl))
+  else if (TREE_CODE (target_decl) == VAR_DECL && TREE_CODE (target_bval) == VAR_DECL
+	   && DECL_EXTERNAL (target_decl) && DECL_EXTERNAL (target_bval)
+	   && !DECL_CLASS_SCOPE_P (target_decl))
     {
       duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
       ok = false;
@@ -3018,6 +3044,8 @@  push_class_level_binding_1 (tree name, t
     {
       tree bval = binding->value;
       tree old_decl = NULL_TREE;
+      tree target_decl = strip_using_decl (decl);
+      tree target_bval = strip_using_decl (bval);
 
       if (INHERITED_VALUE_BINDING_P (binding))
 	{
@@ -3025,8 +3053,8 @@  push_class_level_binding_1 (tree name, t
 	     tag name, slide it over to make room for the new binding.
 	     The old binding is still visible if explicitly qualified
 	     with a class-key.  */
-	  if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
-	      && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
+	  if (TREE_CODE (target_bval) == TYPE_DECL && DECL_ARTIFICIAL (target_bval)
+	      && !(TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL (target_decl)))
 	    {
 	      old_decl = binding->type;
 	      binding->type = bval;
@@ -3038,18 +3066,21 @@  push_class_level_binding_1 (tree name, t
 	      old_decl = bval;
 	      /* Any inherited type declaration is hidden by the type
 		 declaration in the derived class.  */
-	      if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
+	      if (TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL (target_decl))
 		binding->type = NULL_TREE;
 	    }
 	}
-      else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
-	old_decl = bval;
-      else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL)
-	return true;
-      else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval))
+      else if (TREE_CODE (target_decl) == OVERLOAD && is_overloaded_fn (target_bval))
 	old_decl = bval;
-      else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
+      else if (TREE_CODE (decl) == USING_DECL
+	       && DECL_DEPENDENT_P (decl)
+	       && TREE_CODE (bval) == USING_DECL
+	       && DECL_DEPENDENT_P (bval))
 	return true;
+      else if (TREE_CODE (decl) == USING_DECL && is_overloaded_fn (target_bval))
+      	old_decl = bval;
+      else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (target_decl))
+      	return true;
 
       if (old_decl && binding->scope == class_binding_level)
 	{
Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c	(revision 178088)
+++ gcc/dbxout.c	(working copy)
@@ -1518,6 +1518,8 @@  dbxout_type_fields (tree type)
       if (TREE_CODE (tem) == TYPE_DECL
 	  /* Omit here the nameless fields that are used to skip bits.  */
 	  || DECL_IGNORED_P (tem)
+	  /* Omit USING_DECL */
+	  || TREE_CODE (tem) >= LAST_AND_UNUSED_TREE_CODE
 	  /* Omit fields whose position or size are variable or too large to
 	     represent.  */
 	  || (TREE_CODE (tem) == FIELD_DECL