diff mbox

C++ PATCH for c++/68666 (member variable template)

Message ID CADzB+2m+qDKJStd83JJx1YuRsxjH-7NEW1mC04O8gtFFnahKGQ@mail.gmail.com
State New
Headers show

Commit Message

Jason Merrill Jan. 18, 2017, 9:04 p.m. UTC
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 <jason@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 mbox

Patch

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>;     // ???
+}