re PR c++/22139 (Segfault with templates and friend functions)
authorMark Mitchell <mark@codesourcery.com>
Sun, 17 Jul 2005 22:02:09 +0000 (22:02 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sun, 17 Jul 2005 22:02:09 +0000 (22:02 +0000)
PR c++/22139
* cp-tree.h (DECL_TEMPLATE_INFO): Improve documentation.
* decl.c (duplicate_decls): Re-register template specializations
for functions that have DECL_TEMLPLATE_INFO, even if they do not
have DECL_TEMPLATE_INSTANTIATION set.

PR c++/22139
* g++.dg/template/friend36.C: New test.

From-SVN: r102118

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/friend36.C [new file with mode: 0644]

index 6ebdca9..4c048cf 100644 (file)
@@ -1,3 +1,11 @@
+2005-07-17  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/22139
+       * cp-tree.h (DECL_TEMPLATE_INFO): Improve documentation.
+       * decl.c (duplicate_decls): Re-register template specializations
+       for functions that have DECL_TEMLPLATE_INFO, even if they do not
+       have DECL_TEMPLATE_INSTANTIATION set.
+
 2005-07-16  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * call.c (diagnostic_fn_t): New.
index 440bdff..2d5e5f1 100644 (file)
@@ -2056,8 +2056,24 @@ extern void decl_shadowed_for_var_insert (tree, tree);
 #define DECL_DEFERRED_FN(DECL) \
   (DECL_LANG_SPECIFIC (DECL)->decl_flags.deferred)
 
-/* For a VAR_DECL, FUNCTION_DECL, TYPE_DECL or TEMPLATE_DECL:
-   template-specific information.  */
+/* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or
+   TEMPLATE_DECL, the entity is a template specialization.  In that
+   case, DECL_TEMPLATE_INFO is a TREE_LIST, whose TREE_PURPOSE is the
+   TEMPLATE_DECL of which this entity is a specialization.  The TREE_
+   TREE_VALUE is the template arguments used to specialize the
+   template.  
+
+   In general, DECL_TEMPLATE_INFO is non-NULL only if
+   DECL_USE_TEMPLATE is non-zero.  However, for friends, we sometimes
+   have DECL_TEMPLATE_INFO even when DECL_USE_TEMPLATE is zero.
+   Consider:
+
+      template <typename T> struct S { friend void f(T) {} };
+
+   In this case, S<int>::f is, from the point of view of the compiler,
+   an instantiation of a template -- but, from the point of view of
+   the language, each instantiation of S results in a wholly unrelated
+   global function f.  */ 
 #define DECL_TEMPLATE_INFO(NODE) \
   (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
    ->decl_flags.u.template_info)
index ee6a89b..855906a 100644 (file)
@@ -1838,7 +1838,7 @@ duplicate_decls (tree newdecl, tree olddecl)
       memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
              (char *) newdecl + sizeof (struct tree_decl_common),
              sizeof (struct tree_function_decl) - sizeof (struct tree_decl_common));
-      if (DECL_TEMPLATE_INSTANTIATION (newdecl))
+      if (DECL_TEMPLATE_INFO (newdecl))
        /* If newdecl is a template instantiation, it is possible that
           the following sequence of events has occurred:
 
index db07da5..2f18605 100644 (file)
@@ -1,3 +1,8 @@
+2005-07-17  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/22139
+       * g++.dg/template/friend36.C: New test.
+
 2005-07-16  David Edelsohn  <edelsohn@gnu.org>
 
        PR fortran/21730
diff --git a/gcc/testsuite/g++.dg/template/friend36.C b/gcc/testsuite/g++.dg/template/friend36.C
new file mode 100644 (file)
index 0000000..5f07db4
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/22139
+// { dg-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" }
+template <int rank, int dim> class Tensor;
+template <int rank, int dim> struct SymmetricTensor {     
+  SymmetricTensor (const Tensor<2,dim> &t);
+  friend void foo(); 
+};
+template <> SymmetricTensor<2,2>::SymmetricTensor (const Tensor<2,2> &t) {}
+template <> SymmetricTensor<2,3>::SymmetricTensor (const Tensor<2,3> &t) {}