OSDN Git Service

PR c++/26102
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Sep 2006 01:15:09 +0000 (01:15 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Sep 2006 01:15:09 +0000 (01:15 +0000)
        * name-lookup.c (do_class_using_decl): Try to find the base even
        if bases_dependent_p.
        * pt.c (type_dependent_expression_p): A USING_DECL is dependent.

        PR c++/19809
        * pt.c (tsubst_friend_function): Set DECL_INITIAL before pushdecl.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@116709 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/name-lookup.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/template/friend47.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/using14.C [new file with mode: 0644]

index e794232..3016bb0 100644 (file)
@@ -2824,18 +2824,19 @@ do_class_using_decl (tree scope, tree name)
      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)
+  if (!scope_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_not_base_type (scope, current_class_type);
-         return NULL_TREE;
+         if (!bases_dependent_p)
+           {
+             error_not_base_type (scope, current_class_type);
+             return NULL_TREE;
+           }
        }
-
-      if (!name_dependent_p)
+      else if (!name_dependent_p)
        {
          decl = lookup_member (binfo, name, 0, false);
          if (!decl)
index 79d9de4..d278b00 100644 (file)
@@ -5333,6 +5333,10 @@ tsubst_friend_function (tree decl, tree args)
       else
        new_friend_result_template_info = NULL_TREE;
 
+      /* Make the init_value nonzero so pushdecl knows this is a defn.  */
+      if (new_friend_is_defn)
+       DECL_INITIAL (new_friend) = error_mark_node;
+
       /* Inside pushdecl_namespace_level, we will push into the
         current namespace. However, the friend function should go
         into the namespace of the template.  */
@@ -12862,7 +12866,8 @@ type_dependent_expression_p (tree expression)
     return false;
 
   /* An unresolved name is always dependent.  */
-  if (TREE_CODE (expression) == IDENTIFIER_NODE)
+  if (TREE_CODE (expression) == IDENTIFIER_NODE
+      || TREE_CODE (expression) == USING_DECL)
     return true;
 
   /* Some expression forms are never type-dependent.  */
diff --git a/gcc/testsuite/g++.dg/template/friend47.C b/gcc/testsuite/g++.dg/template/friend47.C
new file mode 100644 (file)
index 0000000..6121739
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/19809
+
+template<int i>
+struct n{
+  friend void foo(){ }         // { dg-error "defin" }
+};
+
+int main(){
+  n<1> n1;
+  n<2> n2;
+}
diff --git a/gcc/testsuite/g++.dg/template/using14.C b/gcc/testsuite/g++.dg/template/using14.C
new file mode 100644 (file)
index 0000000..d104948
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/26102
+
+template <class T> struct B1 { int i(); };
+
+struct B2 { int i(); };
+
+template <class T> struct C : public B1<T>, public B2
+{
+  using B2::i;
+  void f()
+  {
+    i();                       // should be accepted
+    i.i();                     // { dg-error "" }
+  }
+};
+
+int main()
+{
+  C<int> c;
+  c.f();                       // { dg-error "instantiated" }
+}