PR c++/51289 - ICE with alias template for bound template template parm
authorDodji Seketeli <dodji@redhat.com>
Fri, 9 Dec 2011 18:12:45 +0000 (18:12 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Fri, 9 Dec 2011 18:12:45 +0000 (19:12 +0100)
gcc/cp/

PR c++/51289
* cp-tree.h (TYPE_TEMPLATE_INFO): Rewrite this accessor macro to
better support aliased types.
(TYPE_ALIAS_P): Don't crash on TYPE_NAME nodes that are not
TYPE_DECL.
* pt.c (find_parameter_packs_r): Handle types aliases.
(push_template_decl_real): Check for bare parameter packs in the
underlying type of an alias template.

gcc/PR51289/gcc/testsuite/

PR c++/51289
* g++.dg/cpp0x/alias-decl-17.C: New test.

From-SVN: r182170

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C [new file with mode: 0644]

index 14e65c0f7a66252879a7202247c4afdcae010833..3698349c1dd90fe041f1837efe02bd9a9bfd546f 100644 (file)
@@ -1,3 +1,14 @@
+2011-12-09  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/51289
+       * cp-tree.h (TYPE_TEMPLATE_INFO): Rewrite this accessor macro to
+       better support aliased types.
+       (TYPE_ALIAS_P): Don't crash on TYPE_NAME nodes that are not
+       TYPE_DECL.
+       * pt.c (find_parameter_packs_r): Handle types aliases.
+       (push_template_decl_real): Check for bare parameter packs in the
+       underlying type of an alias template.
+
 2011-12-08  Jason Merrill  <jason@redhat.com>
 
        PR c++/51318
index 87cb8b6d04e508136f70a14552062277688d32d4..955d0eb366816da8a0f52337331645a6003c0ed3 100644 (file)
@@ -2555,6 +2555,7 @@ extern void decl_shadowed_for_var_insert (tree, tree);
 #define TYPE_ALIAS_P(NODE)                     \
   (TYPE_P (NODE)                               \
    && TYPE_NAME (NODE)                         \
+   && TREE_CODE (TYPE_NAME (NODE)) == TYPE_DECL        \
    && TYPE_DECL_ALIAS_P (TYPE_NAME (NODE)))
 
 /* For a class type: if this structure has many fields, we'll sort them
@@ -2607,17 +2608,24 @@ extern void decl_shadowed_for_var_insert (tree, tree);
   (LANG_TYPE_CLASS_CHECK (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \
    ->template_info)
 
-/* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
+/* Template information for an ENUMERAL_, RECORD_, UNION_TYPE, or
+   BOUND_TEMPLATE_TEMPLATE_PARM type.  Note that if NODE is a
+   specialization of an alias template, this accessor returns the
+   template info for the alias template, not the one (if any) for the
+   template of the underlying type.  */
 #define TYPE_TEMPLATE_INFO(NODE)                                       \
-  (TREE_CODE (NODE) == ENUMERAL_TYPE                                   \
-   ? ENUM_TEMPLATE_INFO (NODE) :                                       \
-   (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM                   \
-    ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) :                    \
-    ((CLASS_TYPE_P (NODE) && !TYPE_ALIAS_P (NODE))                     \
-     ? CLASSTYPE_TEMPLATE_INFO (NODE)                                  \
-     : ((TYPE_NAME (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE)))    \
-       ? (DECL_TEMPLATE_INFO (TYPE_NAME (NODE)))                       \
-       : NULL_TREE))))
+  (TYPE_ALIAS_P (NODE)                                                 \
+   ? ((TYPE_NAME (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE)))      \
+      ? DECL_TEMPLATE_INFO (TYPE_NAME (NODE))                          \
+      : NULL_TREE)                                                     \
+   : ((TREE_CODE (NODE) == ENUMERAL_TYPE)                              \
+      ? ENUM_TEMPLATE_INFO (NODE)                                      \
+      : ((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM)            \
+        ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE)                  \
+        : (CLASS_TYPE_P (NODE)                                         \
+           ? CLASSTYPE_TEMPLATE_INFO (NODE)                            \
+           : NULL_TREE))))
+
 
 /* Set the template information for an ENUMERAL_, RECORD_, or
    UNION_TYPE to VAL.  */
index 296cd545794d09f90b53c9760a80dba2217177c1..bb5aa0c1484edc04e165f0f6e741838f7960cda5 100644 (file)
@@ -2976,6 +2976,20 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
     (struct find_parameter_pack_data*)data;
   bool parameter_pack_p = false;
 
+  /* Handle type aliases/typedefs.  */
+  if (TYPE_P (t)
+      && TYPE_NAME (t)
+      && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
+      && TYPE_DECL_ALIAS_P (TYPE_NAME (t)))
+    {
+      if (TYPE_TEMPLATE_INFO (t))
+       cp_walk_tree (&TYPE_TI_ARGS (t),
+                     &find_parameter_packs_r,
+                     ppd, ppd->visited);
+      *walk_subtrees = 0;
+      return NULL_TREE;
+    }
+
   /* Identify whether this is a parameter pack or not.  */
   switch (TREE_CODE (t))
     {
@@ -4905,7 +4919,10 @@ push_template_decl_real (tree decl, bool is_friend)
       if (check_for_bare_parameter_packs (TYPE_RAISES_EXCEPTIONS (type)))
        TYPE_RAISES_EXCEPTIONS (type) = NULL_TREE;
     }
-  else if (check_for_bare_parameter_packs (TREE_TYPE (decl)))
+  else if (check_for_bare_parameter_packs ((TREE_CODE (decl) == TYPE_DECL
+                                           && TYPE_DECL_ALIAS_P (decl))
+                                          ? DECL_ORIGINAL_TYPE (decl)
+                                          : TREE_TYPE (decl)))
     {
       TREE_TYPE (decl) = error_mark_node;
       return error_mark_node;
index 3a97bf76a68dda1d5146fb0bf2da101cce746857..2430c7f273d4b602f1455c310633b2fa7751893a 100644 (file)
@@ -1,3 +1,8 @@
+2011-12-09  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/51289
+       * g++.dg/cpp0x/alias-decl-17.C: New test.
+
 2011-12-09  Michael Meissner  <meissner@the-meissners.org>
 
        * gcc.target/powerpc/recip-5.c: Disable running on any system that
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C
new file mode 100644 (file)
index 0000000..41b1c95
--- /dev/null
@@ -0,0 +1,21 @@
+// Origin PR c++/51289
+// { dg-options "-std=c++11" }
+
+template<typename a, template <typename, typename> class b>
+struct foo {
+  template <typename t>
+  using type = b<a, t>;
+  template <typename t>
+  b<a, t> funca() {}
+
+  template <typename t>
+  type<t> funcb() {}
+};
+
+// This is an additional test, to emit an error message when using
+// unexpanded parameter packs in an alias declaration.
+template <class ... T>
+struct S {};
+
+template<class ... T>
+using A = S<T>; // { dg-error "parameter packs not expanded" }