With the infrastructure of the previous patch in place, this patch
easily uses TEMPLATE_ID_TYPE to represent unbound specializations of
alias templates, thus fixing PR c++/51239.
A new function introduced to fix that bug is also used to address PR
c++/51180 by fixing the representation of template specializations
where the arguments contain a pack expansion.
Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.
gcc/cp/
PR c++/51239
PR c++/51180
* cp-tree.h (any_pack_expansion_template_argument_p): Declare new
function.
* pt.c (any_pack_expansion_template_argument_p): Define it.
(coerce_template_parms, lookup_template_class_1): Use it.
gcc/testsuite/
PR c++/51239
PR c++/51180
* g++.dg/cpp0x/alias-decl-18.C: New test.
* g++.dg/cpp0x/alias-decl-19.C: Likewise.
* g++.dg/cpp0x/alias-decl-15.C: This was wrongly expected
to fail before. Adjust accordingly.
---
gcc/cp/cp-tree.h | 1 +
gcc/cp/pt.c | 32 +++++++++++++++++++++++++++-
gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C | 8 +++---
gcc/testsuite/g++.dg/cpp0x/alias-decl-18.C | 29 +++++++++++++++++++++++++
gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C | 19 ++++++++++++++++
5 files changed, 84 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-18.C
create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fa5bf7f..ef0ef1b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5333,6 +5333,7 @@ extern int processing_template_parmlist;
extern bool dependent_type_p (tree);
extern bool dependent_scope_p (tree);
extern bool any_dependent_template_arguments_p (const_tree);
+extern bool any_pack_expansion_template_argument_p (tree);
extern bool dependent_template_p (tree);
extern bool dependent_template_id_p (tree, tree);
extern bool type_dependent_expression_p (tree);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7d00770..634e7e0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6787,7 +6787,8 @@ coerce_template_parms (tree parms,
&& require_all_args
&& (!use_default_args
|| (TREE_VEC_ELT (parms, nargs) != error_mark_node
- && !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))))
+ && !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))
+ && !any_pack_expansion_template_argument_p (inner_args)))
{
if (complain & tf_error)
{
@@ -7484,6 +7485,14 @@ lookup_template_class_1 (tree d1, tree arglist, tree
in_decl, tree context,
}
else if (DECL_ALIAS_TEMPLATE_P (gen_tmpl))
{
+ if (any_pack_expansion_template_argument_p (arglist))
+ /* So we don't yet know the number of arguments the
+ alias template specialization has. Let's build a
+ representation that keeps the arguments "unapplied"
+ to the alias template for now, so that we can apply
+ the them later when they are fully known. */
+ return build_template_id_type (gen_tmpl, arglist);
+
/* The user referred to a specialization of an alias
template represented by GEN_TMPL.
@@ -19894,6 +19903,27 @@ any_dependent_template_arguments_p (const_tree args)
return false;
}
+/* Return true if ARGS (a TREE_VEC of template arguments) contains
+ any pack expansion. */
+
+bool
+any_pack_expansion_template_argument_p (tree args)
+{
+ int i;
+
+ if (args == NULL_TREE || TREE_CODE (args) != TREE_VEC)
+ return false;
+
+ for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
+ {
+ tree elt = TREE_VEC_ELT (args, i);
+ if (elt != NULL_TREE && PACK_EXPANSION_P (elt))
+ return true;
+ }
+
+ return false;
+}
+
/* Returns TRUE if the template TMPL is dependent. */
bool
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C
b/gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C
index 2bc9b11..19f1a8d 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C
@@ -1,8 +1,8 @@
// Origin PR c++/51194
// { dg-options "-std=c++0x" }
-template<class U, class V> //#1
-struct foo {}; // { dg-error "provided for|foo" }
+template<class U, class V>
+struct foo {};
template<class U, class V=char>
struct P {};
@@ -10,8 +10,8 @@ struct P {};
template<template<class... U> class... TT>
struct bar {
template<class... Args>
- using mem = P<TT<Args...>...>;//#2 { dg-error "wrong number of|arguments" }
+ using mem = P<TT<Args...>...>;
};
-bar<foo>::mem<int, char> b;//#3 { dg-error "invalid type" }
+bar<foo>::mem<int, char> b;
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-18.C
b/gcc/testsuite/g++.dg/cpp0x/alias-decl-18.C
new file mode 100644
index 0000000..311ab58
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-18.C
@@ -0,0 +1,29 @@
+// Origin PR c++/51239
+// { dg-options "-std=c++11" }
+
+struct S {};
+
+template<typename T, typename...>
+using head = T;
+
+template<typename... Ts>
+using x = head<Ts...>;
+
+x<int, char> i0;
+x<char> i1;
+x<unsigned, int, int> i2;
+x<S, char>i3;
+
+void f0(int);
+void f1(char);
+void f2(unsigned);
+void f3(S);
+
+void
+g()
+{
+ f0(i0);
+ f1(i1);
+ f2(i2);
+ f3(i3);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C
b/gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C
new file mode 100644
index 0000000..ff7b822
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C
@@ -0,0 +1,19 @@
+// Origin PR c++/51180
+// { dg-options "-std=c++11" }
+
+template<class, class>
+struct t2 // { dg-error "provided for" }
+{
+};
+
+template<template<class...> class M>
+struct m
+{
+ template<class... B>
+ using inner = M<B...>; // { dg-error "wrong number of template arg" }
+};
+
+m<t2> sta1; // <-- this one is valid
+m<t2>::inner<int, int> sta2; // <-- and this one as well
+m<t2>::inner<char> sta3;// { dg-error "invalid" }
+m<t2>::inner<char, int, int> sta4;// { dg-error "invalid" }
--
1.7.6.4
--
Dodji