diff options
author | Patrick Palka <ppalka@redhat.com> | 2021-03-06 00:07:43 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2021-03-06 00:07:43 -0500 |
commit | 574e7601829733d7cae20b5dc7034b876cc76b30 (patch) | |
tree | cd847fdecefd1d73301ec2d4edaffea8b592f698 | |
parent | b49d23f3e238c08bdbc5b892b2ed0a57b5f5caf9 (diff) | |
download | gcc-574e7601829733d7cae20b5dc7034b876cc76b30.zip gcc-574e7601829733d7cae20b5dc7034b876cc76b30.tar.gz gcc-574e7601829733d7cae20b5dc7034b876cc76b30.tar.bz2 |
c++: Fix tsubsting member variable template-id [PR96330]
This makes tsubst_copy appropriately handle a variable template-id, which
in turn fixes tsubsting a COMPONENT_REF whose member operand is known at
parse time to be a variable template-id, as in the initialization of 'x'
in the first testcase. Previously, we rejected this testcase with the
error "foo_t::bar<T> is not a function template", issued from
lookup_template_fuction.
We were already properly handling the analagous case where the object
operand of the COMPONENT_REF is dependent (and so the member operand is
a dependent template name), but there doesn't seems to be existing test
coverage for this, hence the second testcase below.
gcc/cp/ChangeLog:
PR c++/96330
* pt.c (tsubst_copy) <case TEMPLATE_ID_EXPR>: Rename local
variable 'fn' to 'tmpl'. Handle a variable template-id by
calling lookup_template_variable.
gcc/testsuite/ChangeLog:
PR c++/96330
* g++.dg/cpp1y/var-templ68.C: New test.
* g++.dg/cpp1y/var-templ68a.C: New test.
Co-authored-by: Jakub Jelinek <jakub@redhat.com>
-rw-r--r-- | gcc/cp/pt.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ68.C | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ68a.C | 16 |
3 files changed, 37 insertions, 3 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7794137..81df8c8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17110,14 +17110,17 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TEMPLATE_ID_EXPR: { /* Substituted template arguments */ - tree fn = TREE_OPERAND (t, 0); + tree tmpl = TREE_OPERAND (t, 0); tree targs = TREE_OPERAND (t, 1); - fn = tsubst_copy (fn, args, complain, in_decl); + tmpl = tsubst_copy (tmpl, args, complain, in_decl); if (targs) targs = tsubst_template_args (targs, args, complain, in_decl); - return lookup_template_function (fn, targs); + if (variable_template_p (tmpl)) + return lookup_template_variable (tmpl, targs); + else + return lookup_template_function (tmpl, targs); } case TREE_LIST: diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ68.C b/gcc/testsuite/g++.dg/cpp1y/var-templ68.C new file mode 100644 index 0000000..4c560d4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ68.C @@ -0,0 +1,15 @@ +// PR c++/96330 +// { dg-do compile { target c++14 } } + +struct foo_t { + template <class T> static constexpr bool bar = true; +}; +constexpr foo_t foo{}; + +template <class T> +void f() { + int x = foo.bar<T>; + int y = foo_t::bar<T>; +} + +template void f<int>(); diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ68a.C b/gcc/testsuite/g++.dg/cpp1y/var-templ68a.C new file mode 100644 index 0000000..6091a03 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ68a.C @@ -0,0 +1,16 @@ +// PR c++/96330 +// { dg-do compile { target c++14 } } + +template <class> +struct foo_t { + template <class T> static constexpr bool bar = true; +}; +template <class T> constexpr foo_t<T> foo{}; + +template <class T> +void f() { + int x = foo<T>.template bar<T>; + int y = foo_t<T>::template bar<T>; +} + +template void f<int>(); |