diff options
author | Jason Merrill <jason@redhat.com> | 2015-08-05 13:56:14 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-08-05 13:56:14 -0400 |
commit | dc062b4986328bfeec3ebd744a9c116e28828bf0 (patch) | |
tree | 2ca6d972f81bab5e224ba92c9f66113f52c5d92f /gcc | |
parent | 85171e7877e60e2af5a76b0961e3ee8903bd084f (diff) | |
download | gcc-dc062b4986328bfeec3ebd744a9c116e28828bf0.zip gcc-dc062b4986328bfeec3ebd744a9c116e28828bf0.tar.gz gcc-dc062b4986328bfeec3ebd744a9c116e28828bf0.tar.bz2 |
re PR c++/66260 ([C++14] Failure to compile variable template with recursively defined partial specialization)
PR c++/66260
PR c++/66596
PR c++/66649
PR c++/66923
* pt.c (lookup_template_variable): Use NULL_TREE for type.
(instantiate_template_1): Also set DECL_TI_ARGS based on
the immediate parent.
(tsubst_copy_and_build) [TEMPLATE_ID_EXPR]: Handle variable templates.
(finish_template_variable): Add complain parm.
* cp-tree.h: Adjust.
From-SVN: r226642
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ32.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ35.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ36.C | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ38.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ39.C | 16 |
8 files changed, 68 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 382ad9a..e0075e0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,16 @@ 2015-08-05 Jason Merrill <jason@redhat.com> + PR c++/66260 + PR c++/66596 + PR c++/66649 + PR c++/66923 + * pt.c (lookup_template_variable): Use NULL_TREE for type. + (instantiate_template_1): Also set DECL_TI_ARGS based on + the immediate parent. + (tsubst_copy_and_build) [TEMPLATE_ID_EXPR]: Handle variable templates. + (finish_template_variable): Add complain parm. + * cp-tree.h: Adjust. + PR c++/65195 PR c++/66619 * semantics.c (finish_id_expression): Call convert_from_reference diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 63fd6e9..e70dcb4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5954,7 +5954,7 @@ extern tree perform_koenig_lookup (tree, vec<tree, va_gc> *, tsubst_flags_t); extern tree finish_call_expr (tree, vec<tree, va_gc> **, bool, bool, tsubst_flags_t); -extern tree finish_template_variable (tree); +extern tree finish_template_variable (tree, tsubst_flags_t = tf_warning_or_error); extern tree finish_increment_expr (tree, enum tree_code); extern tree finish_this_expr (void); extern tree finish_pseudo_destructor_expr (tree, tree, tree, location_t); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7ad2334..f8c123c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8187,14 +8187,14 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, tree lookup_template_variable (tree templ, tree arglist) { - tree type = unknown_type_node; + tree type = NULL_TREE; return build2 (TEMPLATE_ID_EXPR, type, templ, arglist); } /* Instantiate a variable declaration from a TEMPLATE_ID_EXPR for use. */ tree -finish_template_variable (tree var) +finish_template_variable (tree var, tsubst_flags_t complain) { tree templ = TREE_OPERAND (var, 0); @@ -8203,7 +8203,6 @@ finish_template_variable (tree var) arglist = add_outermost_template_args (tmpl_args, arglist); tree parms = DECL_TEMPLATE_PARMS (templ); - tsubst_flags_t complain = tf_warning_or_error; arglist = coerce_innermost_template_parms (parms, arglist, templ, complain, /*req_all*/true, /*use_default*/true); @@ -14750,6 +14749,17 @@ tsubst_copy_and_build (tree t, if (targs) targs = tsubst_template_args (targs, args, complain, in_decl); + if (variable_template_p (templ)) + { + templ = lookup_template_variable (templ, targs); + if (!any_dependent_template_arguments_p (targs)) + { + templ = finish_template_variable (templ, complain); + mark_used (templ); + } + RETURN (convert_from_reference (templ)); + } + if (TREE_CODE (templ) == COMPONENT_REF) { object = TREE_OPERAND (templ, 0); @@ -16153,6 +16163,7 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) /* The DECL_TI_TEMPLATE should always be the immediate parent template, not the most general template. */ DECL_TI_TEMPLATE (fndecl) = tmpl; + DECL_TI_ARGS (fndecl) = targ_ptr; /* Now we know the specialization, compute access previously deferred. */ diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ32.C b/gcc/testsuite/g++.dg/cpp1y/var-templ32.C index d9d2fff..80077a1 100644 --- a/gcc/testsuite/g++.dg/cpp1y/var-templ32.C +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ32.C @@ -4,4 +4,4 @@ template<typename T> bool V1 = true; template<typename T> -bool V1<int> = false; // { dg-error "primary template" } +bool V1<int> = false; // { dg-error "primary template|not deducible" } diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ35.C b/gcc/testsuite/g++.dg/cpp1y/var-templ35.C index c2c58ac..5ed0abc 100644 --- a/gcc/testsuite/g++.dg/cpp1y/var-templ35.C +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ35.C @@ -2,4 +2,4 @@ // { dg-do compile { target c++14 } } template<typename T> int typeID{42}; -template<typename T> double typeID<double>{10.10}; // { dg-error "primary template|redeclaration" } +template<typename T> double typeID<double>{10.10}; // { dg-error "primary template|redeclaration|not deducible" } diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ36.C b/gcc/testsuite/g++.dg/cpp1y/var-templ36.C new file mode 100644 index 0000000..760e36f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ36.C @@ -0,0 +1,15 @@ +// { dg-do compile { target c++14 } } + +template <class T> +constexpr T v = T(); + +template <class T> +constexpr T v<T*> = T(); + +template <class T> +struct A { + static constexpr decltype (v<T>) v = ::v<T>; +}; + +double d1 = v<double*>; +double d2 = A<double*>::v; diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ38.C b/gcc/testsuite/g++.dg/cpp1y/var-templ38.C new file mode 100644 index 0000000..1fd76d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ38.C @@ -0,0 +1,9 @@ +// PR c++/66596 +// { dg-do compile { target c++14 } } + +struct U { void f() {} }; +struct V { void f() {} }; +template<class T> U t; +template<> V t<int>; +template<class T> void g() { t<T>.f(); } +int main() { g<int>(); } diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ39.C b/gcc/testsuite/g++.dg/cpp1y/var-templ39.C new file mode 100644 index 0000000..e06519d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ39.C @@ -0,0 +1,16 @@ +// PR c++/66260 +// { dg-do compile { target c++14 } } + +template <class> +constexpr bool foo = false; +template <> +constexpr bool foo<int> = true; +template <class T, int N> +constexpr bool foo<T[N]> = foo<T>; + +static_assert(foo<int>, ""); +static_assert(!foo<double>, ""); +static_assert(foo<int[3]>, ""); +static_assert(!foo<double[3]>, ""); +static_assert(foo<int[2][5][3]>, ""); +static_assert(!foo<double[2][5][3]>, ""); |