The problem was that finish_class_member_access_expr got missed when we added variable templates. 68666 is a report of how this affects concepts; the patch adds both concepts and non-concepts testcases.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 40ab19fcedf621438a819dbdf08d9ee66e3143db Author: Jason Merrill <ja...@redhat.com> Date: Wed Jan 18 15:16:47 2017 -0500 PR c++/68666 - member variable template-id * typeck.c (finish_class_member_access_expr): Handle variable template-id. * pt.c (lookup_and_finish_template_variable): No longer static. * cp-tree.h: Declare it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 98e4cbd..9c44367 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6449,6 +6449,7 @@ extern cp_expr perform_koenig_lookup (cp_expr, vec<tree, va_gc> *, tsubst_flags_t); extern tree finish_call_expr (tree, vec<tree, va_gc> **, bool, bool, tsubst_flags_t); +extern tree lookup_and_finish_template_variable (tree, tree, tsubst_flags_t = tf_warning_or_error); extern tree finish_template_variable (tree, tsubst_flags_t = tf_warning_or_error); extern cp_expr finish_increment_expr (cp_expr, enum tree_code); extern tree finish_this_expr (void); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6fd03a5..c679133 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9035,7 +9035,7 @@ finish_template_variable (tree var, tsubst_flags_t complain) /* Construct a TEMPLATE_ID_EXPR for the given variable template TEMPL having TARGS template args, and instantiate it if it's not dependent. */ -static tree +tree lookup_and_finish_template_variable (tree templ, tree targs, tsubst_flags_t complain) { diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index b84f8bee..579c580 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2875,7 +2875,10 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, tree templ = member; if (BASELINK_P (templ)) - templ = lookup_template_function (templ, template_args); + member = lookup_template_function (templ, template_args); + else if (variable_template_p (templ)) + member = (lookup_and_finish_template_variable + (templ, template_args, complain)); else { if (complain & tf_error) diff --git a/gcc/testsuite/g++.dg/concepts/var-templ3.C b/gcc/testsuite/g++.dg/concepts/var-templ3.C new file mode 100644 index 0000000..b882b08 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/var-templ3.C @@ -0,0 +1,12 @@ +// PR c++/68666 +// { dg-options "-std=c++1z -fconcepts" } + +struct A { + template <class> + static constexpr bool val = true; +}; + +template <class T> +concept bool C = A::val<T>; + +C{T} struct B {}; diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ55.C b/gcc/testsuite/g++.dg/cpp1y/var-templ55.C new file mode 100644 index 0000000..0840df3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ55.C @@ -0,0 +1,12 @@ +// { dg-do compile { target c++14 } } + +template <class T> struct A { + template <class U> static const U x = 1; + static const int y = 2; +}; + +int main() { + A<int> a; + int y = a.y; // OK + int x = a.x<int>; // ??? +}