summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-06 04:10:01 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-06 04:10:01 +0000
commitd73bd5d84da7bf066c54fa1fb94cf23ebbef1f4c (patch)
tree475906f16dc210647b019c9636e2f2771593ad94
parentf9db1089610be3e886e7c6f4716363b062cc512c (diff)
downloadgcc-d73bd5d84da7bf066c54fa1fb94cf23ebbef1f4c.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-5-branch@226657 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/pt.c18
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/var-templ32.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/var-templ35.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/var-templ36.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/var-templ38.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/var-templ39.C16
8 files changed, 79 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 72bd6f8fb15..522d1477e74 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 3ece2a58f06..8c4796fc10a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5945,7 +5945,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 2ab599f9996..f3305aa549c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8179,14 +8179,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);
@@ -8195,7 +8195,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);
@@ -14737,6 +14736,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);
@@ -16134,6 +16144,8 @@ 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;
+ if (VAR_P (fndecl))
+ 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
new file mode 100644
index 00000000000..80077a16b56
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/var-templ32.C
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++14 } }
+
+template<typename T>
+bool V1 = true;
+
+template<typename T>
+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
new file mode 100644
index 00000000000..5ed0abca4bc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/var-templ35.C
@@ -0,0 +1,5 @@
+// PR c++/66595
+// { 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|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 00000000000..760e36fca44
--- /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 00000000000..1fd76d38d4b
--- /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 00000000000..e06519d5482
--- /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]>, "");