diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 53b2953320a71e8b1866aee5ac5f7131dc34f96c..5fabf49df71ef90a3c9fbc2c52f3028ec21594f9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2006-01-19  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/22136
+	* name-lookup.c (do_class_using_decl): Don't try to look up base
+	classes in templates with dependent base types.
+
 2006-01-19  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
 	PR c++/25854
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 4a2482f588064994ec615708d576c0492df410d5..190ae24cd94e29b17b81564614d137c0c469652f 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2722,9 +2722,21 @@ push_class_level_binding (tree name, tree x)
 tree
 do_class_using_decl (tree scope, tree name)
 {
-  tree value, decl, binfo;
-  base_kind b_kind;
-  bool dependent_p;
+  /* The USING_DECL returned by this function.  */
+  tree value;
+  /* The declaration (or declarations) name by this using
+     declaration.  NULL if we are in a template and cannot figure out
+     what has been named.  */
+  tree decl;
+  /* True if SCOPE is a dependent type.  */
+  bool scope_dependent_p;
+  /* True if SCOPE::NAME is dependent.  */
+  bool name_dependent_p;
+  /* True if any of the bases of CURRENT_CLASS_TYPE are dependent.  */
+  bool bases_dependent_p;
+  tree binfo;
+  tree base_binfo;
+  int i;
 
   if (!scope || !TYPE_P (scope))
     {
@@ -2732,25 +2744,6 @@ do_class_using_decl (tree scope, tree name)
       return NULL_TREE;
     }
 
-  /* Make sure the scope is a base.  */
-  dependent_p = dependent_type_p (scope);
-  if (!dependent_p)
-    binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
-  else
-    {
-      binfo = NULL;
-      if (same_type_p (current_class_type, scope))
-	b_kind = bk_same_type;
-      else
-	b_kind = bk_proper_base;
-    }
-
-  if (b_kind < bk_proper_base)
-    {
-      error_not_base_type (scope, current_class_type);
-      return NULL_TREE;
-    }
-
   /* Make sure the name is not invalid */
   if (TREE_CODE (name) == BIT_NOT_EXPR)
     {
@@ -2769,32 +2762,64 @@ do_class_using_decl (tree scope, tree name)
       return NULL_TREE;
     }
 
-  if (!dependent_p
-      && IDENTIFIER_OPNAME_P (name) && dependent_type_p (TREE_TYPE (name)))
-    dependent_p = 1;
+  scope_dependent_p = dependent_type_p (scope);
+  name_dependent_p = (scope_dependent_p 
+		      || (IDENTIFIER_OPNAME_P (name)
+			  && dependent_type_p (TREE_TYPE (name))));
+
+  bases_dependent_p = false;
+  if (processing_template_decl)
+    for (binfo = TYPE_BINFO (current_class_type), i = 0;
+	 BINFO_BASE_ITERATE (binfo, i, base_binfo); 
+	 i++)
+      if (dependent_type_p (TREE_TYPE (base_binfo)))
+	{
+	  bases_dependent_p = true;
+	  break;
+	}
 
-  /* See if there are any members of the base. */
-  if (!dependent_p)
-    {
-      decl = lookup_member (binfo, name, 0, false);
+  decl = NULL_TREE;
+
+  /* From [namespace.udecl]:
 
-      if (!decl)
+       A using-declaration used as a member-declaration shall refer to a
+       member of a base class of the class being defined.  
+     
+     In general, we cannot check this constraint in a template because
+     we do not know the entire set of base classes of the current
+     class type.  However, if all of the base classes are
+     non-dependent, then we can avoid delaying the check until
+     instantiation.  */
+  if (!scope_dependent_p && !bases_dependent_p)
+    {
+      base_kind b_kind;
+      tree binfo;
+      binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
+      if (b_kind < bk_proper_base)
 	{
-	  error ("no members matching %<%T::%D%> in %q#T", scope, name, scope);
+	  error_not_base_type (scope, current_class_type);
 	  return NULL_TREE;
 	}
 
-      if (BASELINK_P (decl))
-	/* Ignore base type this came from.  */
-	decl = BASELINK_FUNCTIONS (decl);
+      if (!name_dependent_p)
+	{
+	  decl = lookup_member (binfo, name, 0, false);
+	  if (!decl)
+	    {
+	      error ("no members matching %<%T::%D%> in %q#T", scope, name, 
+		     scope);
+	      return NULL_TREE;
+	    }
+	  /* The binfo from which the functions came does not matter.  */
+	  if (BASELINK_P (decl))
+	    decl = BASELINK_FUNCTIONS (decl);
+	}
    }
-  else
-    decl = NULL_TREE;
 
   value = build_lang_decl (USING_DECL, name, NULL_TREE);
   USING_DECL_DECLS (value) = decl;
   USING_DECL_SCOPE (value) = scope;
-  DECL_DEPENDENT_P (value) = dependent_p;
+  DECL_DEPENDENT_P (value) = !decl;
 
   return value;
 }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cc736693be362834f3220ef916f53ad0ced12e56..b41928e4d82c0762b9b37b01c34a9f268305fa63 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2006-01-19  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/22136
+	* g++.dg/template/using10.C: New test.
+	* g++.dg/temlpate/using11.C: Likewise.
+	* g++.dg/inherit/using5.C: Tweak error messages.
+
 2006-01-20  Alan Modra  <amodra@bigpond.net.au>
 
 	* gcc.target/powerpc/rs6000-ldouble-1.c: Tweak powerpc linux
diff --git a/gcc/testsuite/g++.dg/inherit/using5.C b/gcc/testsuite/g++.dg/inherit/using5.C
index 896c2d461de3632273a76e30d527dd8c5e50bd23..89c7ca03ba69a8e7953642793b7d440d5a41f812 100644
--- a/gcc/testsuite/g++.dg/inherit/using5.C
+++ b/gcc/testsuite/g++.dg/inherit/using5.C
@@ -6,7 +6,7 @@
 
 template<int> struct A
 {
-  A::A; // { dg-error "not a base" }
+  A::A; // { dg-error "constructor" }
 };
 
 struct B
diff --git a/gcc/testsuite/g++.dg/template/using10.C b/gcc/testsuite/g++.dg/template/using10.C
new file mode 100644
index 0000000000000000000000000000000000000000..8f0cbda2a8881f5841a7e339ca5b0c70ef203761
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/using10.C
@@ -0,0 +1,11 @@
+// PR c++/22136
+
+struct B { 
+  void foo(); 
+}; 
+ 
+template <typename T> class I : public B {}; 
+ 
+template <typename T> class D : private I<T> { 
+  I<T>::B::foo; 
+}; 
diff --git a/gcc/testsuite/g++.dg/template/using11.C b/gcc/testsuite/g++.dg/template/using11.C
new file mode 100644
index 0000000000000000000000000000000000000000..21cc5d2ef2da84ac24d99e88189e0011ca1ceda8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/using11.C
@@ -0,0 +1,8 @@
+struct X {
+  void f();
+};
+
+template <typename T> 
+struct S : public T {
+  using X::f;
+};