A variable template or partial specialization trying to refer to the
template in its initializer got confused because name lookup found the
VAR_DECL rather than the template. Fixed by avoiding pushing the VAR_DECL.
Tested x86_64-pc-linux-gnu, applying to trunk and 5.
commit fb2e3bd25d2b8ce5cde5facf156941c7eae5d643
Author: Jason Merrill <ja...@redhat.com>
Date: Mon May 4 21:09:11 2015 -0500
* decl.c (start_decl): Don't push the plain VAR_DECL for a
variable template.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6ec1579..261a12d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4825,8 +4825,11 @@ start_decl (const cp_declarator *declarator,
was_public = TREE_PUBLIC (decl);
- /* Enter this declaration into the symbol table. */
- decl = maybe_push_decl (decl);
+ /* Enter this declaration into the symbol table. Don't push the plain
+ VAR_DECL for a variable template. */
+ if (!template_parm_scope_p ()
+ || TREE_CODE (decl) != VAR_DECL)
+ decl = maybe_push_decl (decl);
if (processing_template_decl)
decl = push_template_decl (decl);
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ24.C b/gcc/testsuite/g++.dg/cpp1y/var-templ24.C
new file mode 100644
index 0000000..d8f7cbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/var-templ24.C
@@ -0,0 +1,5 @@
+// { dg-do compile { target c++14 } }
+
+template <class T> bool Foo = Foo<int>;
+template <> bool Foo<int> = true;
+int i = Foo<char>;