From 8de8fdb45603c76ad268c9eb5135f736c1ac84c4 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 10 Jul 2015 17:35:04 -0400 Subject: [PATCH] pt.c (find_parameter_packs_r): Handle variable templates. * pt.c (find_parameter_packs_r): Handle variable templates. (variable_template_specialization_p): New. * cp-tree.h: Declare it. From-SVN: r225692 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/cp-tree.h | 1 + gcc/cp/pt.c | 18 ++++++++++++++++++ gcc/testsuite/g++.dg/cpp1y/var-templ33.C | 20 ++++++++++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1y/var-templ33.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cf9f838a1c1..130e35863fc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2015-07-10 Jason Merrill + * pt.c (find_parameter_packs_r): Handle variable templates. + (variable_template_specialization_p): New. + * cp-tree.h: Declare it. + * parser.c (cp_parser_template_id): SET_EXPR_LOCATION. 2015-07-10 Eric Botcazou diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d3836123643..8450e9b31c1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5771,6 +5771,7 @@ extern bool reregister_specialization (tree, tree, tree); extern tree instantiate_non_dependent_expr (tree); extern tree instantiate_non_dependent_expr_sfinae (tree, tsubst_flags_t); extern tree instantiate_non_dependent_expr_internal (tree, tsubst_flags_t); +extern bool variable_template_specialization_p (tree); extern bool alias_type_or_template_p (tree); extern bool alias_template_specialization_p (const_tree); extern bool dependent_alias_template_spec_p (const_tree); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 63907ce165b..8c72a6194e2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3245,6 +3245,13 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) ppd, ppd->visited); *walk_subtrees = 0; } + else if (variable_template_specialization_p (t)) + { + cp_walk_tree (&DECL_TI_ARGS (t), + find_parameter_packs_r, + ppd, ppd->visited); + *walk_subtrees = 0; + } break; case BASES: @@ -5351,6 +5358,17 @@ instantiate_non_dependent_expr (tree expr) return instantiate_non_dependent_expr_sfinae (expr, tf_error); } +/* True iff T is a specialization of a variable template. */ + +bool +variable_template_specialization_p (tree t) +{ + if (!VAR_P (t) || !DECL_LANG_SPECIFIC (t) || !DECL_TEMPLATE_INFO (t)) + return false; + tree tmpl = DECL_TI_TEMPLATE (t); + return variable_template_p (tmpl); +} + /* Return TRUE iff T is a type alias, a TEMPLATE_DECL for an alias template declaration, or a TYPE_DECL for an alias declaration. */ diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ33.C b/gcc/testsuite/g++.dg/cpp1y/var-templ33.C new file mode 100644 index 00000000000..53c6db2b974 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ33.C @@ -0,0 +1,20 @@ +// Test for variable templates in pack expansion +// { dg-do compile { target c++14 } } + +template const int Val = I; + +constexpr int f () { return 0; } +template +constexpr int f(T t, Ts... ts) +{ + return t + f(ts...); +} + +template +constexpr int g() +{ + return f(Val...); +} + +#define SA(X) static_assert((X),#X) +SA((g<1,2,3,4>() == 1+2+3+4));