]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/22136 (Rejects old-style using declaration)
authorMark Mitchell <mark@codesourcery.com>
Fri, 20 Jan 2006 03:07:58 +0000 (03:07 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 20 Jan 2006 03:07:58 +0000 (03:07 +0000)
PR c++/22136
* name-lookup.c (do_class_using_decl): Don't try to look up base
classes in templates with dependent base types.
PR c++/22136
* g++.dg/template/using10.C: New test.
* g++.dg/temlpate/using11.C: Likewise.
* g++.dg/inherit/using5.C: Tweak error messages.

From-SVN: r110017

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/using5.C
gcc/testsuite/g++.dg/template/using10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/using11.C [new file with mode: 0644]

index 53b2953320a71e8b1866aee5ac5f7131dc34f96c..5fabf49df71ef90a3c9fbc2c52f3028ec21594f9 100644 (file)
@@ -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
index 4a2482f588064994ec615708d576c0492df410d5..190ae24cd94e29b17b81564614d137c0c469652f 100644 (file)
@@ -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;
 }
index cc736693be362834f3220ef916f53ad0ced12e56..b41928e4d82c0762b9b37b01c34a9f268305fa63 100644 (file)
@@ -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
index 896c2d461de3632273a76e30d527dd8c5e50bd23..89c7ca03ba69a8e7953642793b7d440d5a41f812 100644 (file)
@@ -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 (file)
index 0000000..8f0cbda
--- /dev/null
@@ -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 (file)
index 0000000..21cc5d2
--- /dev/null
@@ -0,0 +1,8 @@
+struct X {
+  void f();
+};
+
+template <typename T> 
+struct S : public T {
+  using X::f;
+};