Jason Merrill <ja...@redhat.com> writes:

> On 11/28/2011 11:54 AM, Dodji Seketeli wrote:
>> @@ -3028,10 +3028,12 @@ find_parameter_packs_r (tree*tp, int *walk_subtrees, 
>> void*  data)
>>
>>       case BOUND_TEMPLATE_TEMPLATE_PARM:
>>         /* Check the template itself.  */
>> -      cp_walk_tree (&TREE_TYPE (TYPE_TI_TEMPLATE (t)),
>> +      cp_walk_tree (&TREE_TYPE (TI_TEMPLATE
>> +                            (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))),
>>              &find_parameter_packs_r, ppd, ppd->visited);
>>         /* Check the template arguments.  */
>> -      cp_walk_tree (&TYPE_TI_ARGS (t),&find_parameter_packs_r, ppd,
>> +      cp_walk_tree (&TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)),
>> +            &find_parameter_packs_r, ppd,
>>                  ppd->visited);
>>         *walk_subtrees = 0;
>>         return NULL_TREE;
>
> Instead of this change, I think we should handle typedefs/aliases at
> the top of the function.  We shouldn't need to look into the
> underlying type for packs.

Thus, I have bootstrapped and tested the below on
x86_64-unknown-linux-gnu against trunk.  I had to make TYPE_ALIAS_P more
robust so that it doesn't crash on TEMPLATE_TEMPLATE_PARMs which
TYPE_NAME are TEMPLATE_DECL nodes, unlike the other types that use
TYPE_DECL nodes that.


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 typedef variant types.

gcc/testsuite/

        PR c++/51289
        * g++.dg/cpp0x/alias-decl-17.C: New test.
---
 gcc/cp/cp-tree.h                           |   28 ++++++++++++++++++----------
 gcc/cp/pt.c                                |   14 ++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C |   13 +++++++++++++
 3 files changed, 45 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3f4f408..b821928 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2553,6 +2553,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
@@ -2605,17 +2606,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.  */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 4725080..5bc6f23 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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) && typedef_variant_p (t))
+    {
+      if (TYPE_TEMPLATE_INFO (t))
+       cp_walk_tree (&TYPE_TI_ARGS (t),
+                     &find_parameter_packs_r,
+                     ppd, ppd->visited);
+      cp_walk_tree (&DECL_ORIGINAL_TYPE (TYPE_NAME (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))
     {
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
index 0000000..a7b2d37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-17.C
@@ -0,0 +1,13 @@
+// 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() {}
+};
-- 
1.7.6.4



-- 
                Dodji

Reply via email to