OSDN Git Service

cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Jan 2002 12:44:44 +0000 (12:44 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Jan 2002 12:44:44 +0000 (12:44 +0000)
PR c++/5213
* pt.c (convert_template_argument): Be more careful determining
when RECORD_TYPE templates are or are not templates.
testsuite:
* g++.dg/template/ttp3.C: New test.

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

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/ttp3.C [new file with mode: 0644]

index 3f05cb7..145f5be 100644 (file)
@@ -1,5 +1,11 @@
 2002-01-02  Nathan Sidwell  <nathan@codesourcery.com>
 
+       PR c++/5213
+       * pt.c (convert_template_argument): Be more careful determining
+       when RECORD_TYPE templates are or are not templates.
+
+2002-01-02  Nathan Sidwell  <nathan@codesourcery.com>
+
        PR c++/775
        * cp-tree.h (handle_class_head): Adjust prototype.
        * decl2.c (handle_class_head): Add DEFN_P and NEW_TYPE_P
index 139076e..3a0921f 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle parameterized types (templates) for GNU C++.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001  Free Software Foundation, Inc.
+   2001, 2002  Free Software Foundation, Inc.
    Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
    Rewritten by Jason Merrill (jason@cygnus.com).
 
@@ -3291,23 +3291,27 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
   requires_type = (TREE_CODE (parm) == TYPE_DECL
                   || requires_tmpl_type);
 
-  /* Check if it is a class template.  If REQUIRES_TMPL_TYPE is true,
-     we also accept implicitly created TYPE_DECL as a valid argument.
-     This is necessary to handle the case where we pass a template name
-     to a template template parameter in a scope where we've derived from
-     in instantiation of that template, so the template name refers to that
-     instantiation.  We really ought to handle this better.  */
-  is_tmpl_type 
-    = ((TREE_CODE (arg) == TEMPLATE_DECL
-       && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
-       || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
-       || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE
-       || (TREE_CODE (arg) == RECORD_TYPE
-          && CLASSTYPE_TEMPLATE_INFO (arg)
-          && TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
-          && DECL_ARTIFICIAL (TYPE_NAME (arg))
-          && requires_tmpl_type
-          && is_base_of_enclosing_class (arg, current_class_type)));
+  if (TREE_CODE (arg) != RECORD_TYPE)
+    is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
+                    && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+                   || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+                   || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
+  else if (CLASSTYPE_TEMPLATE_INFO (arg) && !CLASSTYPE_USE_TEMPLATE (arg)
+          && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg)))
+    {
+      if (is_base_of_enclosing_class (arg, current_class_type))
+       /* This is a template name used within the scope of the
+          template. It could be the template, or it could be the
+          instantiation. Choose whichever makes sense.  */
+       is_tmpl_type = requires_tmpl_type;
+      else
+       is_tmpl_type = 1;
+    }
+  else
+    /* It is a non-template class, or a specialization of a template
+       class, or a non-template member of a template class.  */
+    is_tmpl_type = 0;
+  
   if (is_tmpl_type
       && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
          || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE))
index 96c503d..fc18102 100644 (file)
@@ -1,5 +1,7 @@
 2002-01-02  Nathan Sidwell  <nathan@codesourcery.com>
 
+       * g++.dg/template/ttp3.C: New test.
+
        * g++.dg/template/friend2.C: New test.
        * g++.old-deja/g++/brendan/crash8.C: Adjust location of error.
 
diff --git a/gcc/testsuite/g++.dg/template/ttp3.C b/gcc/testsuite/g++.dg/template/ttp3.C
new file mode 100644 (file)
index 0000000..05bd44a
--- /dev/null
@@ -0,0 +1,26 @@
+// { dg-do compile }
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 29 Dec 2001 <nathan@codesourcery.com>
+
+// PR 5213. We failed to spot that class List was a template, rather
+// than a non-template or specialization
+
+
+template <class T> class vector { };
+
+class OUTER {
+  public:
+  template <class T>
+  class List { };
+  
+  vector<class List> data; // { dg-error "type/value mismatch|expected a type|ISO C" "" }
+};
+
+template <class T>
+class List { };                        // { dg-bogus "previous declaration" "" { xfail *-*-* } }
+
+// This next line should just do a lookup of 'class List', and then
+// get a type/value mismatch. Instead we try and push 'class List'
+// into the global namespace and get a redeclaration error.
+vector<class List > data;      // { dg-bogus "`struct List' redeclared|type/value mismatch" "" { xfail *-*-* } }