In this testcase, the problem is that const variables are implicitly static, and static variables get DECL_INTERFACE_KNOWN set. Then when instantiating the variable we set DECL_EXTERNAL, with the effect that we are saying that we know that we aren't defining the variable in the current translation unit. We ought to set DECL_NOT_REALLY_EXTERN at the same time, as we do various other places.

Tested x86_64-pc-linux-gnu, applying to trunk and 5.
commit ce66414682d1e895700ae8cc96bad49d876db23a
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Jun 12 11:41:24 2015 -0400

    	PR c++/65719
    	* pt.c (tsubst_decl) [VAR_DECL]: Mark namespace-scope
    	variables as DECL_NOT_REALLY_EXTERN.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7f04fe6..ea8c8b6 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11306,8 +11306,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	  {
 	    /* T is a static data member or namespace-scope entity.
 	       We have to substitute into namespace-scope variables
-	       (even though such entities are never templates) because
-	       of cases like:
+	       (not just variable templates) because of cases like:
 	       
 	         template <class T> void f() { extern T t; }
 
@@ -11468,6 +11467,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	       initializer is present.  We mimic the non-template
 	       processing here.  */
 	    DECL_EXTERNAL (r) = 1;
+	    if (DECL_NAMESPACE_SCOPE_P (t))
+	      DECL_NOT_REALLY_EXTERN (r) = 1;
 
 	    DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec);
 	    SET_DECL_IMPLICIT_INSTANTIATION (r);
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ29.C b/gcc/testsuite/g++.dg/cpp1y/var-templ29.C
new file mode 100644
index 0000000..22f5b0b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/var-templ29.C
@@ -0,0 +1,13 @@
+// PR c++/65719
+// { dg-do link { target c++14 } }
+
+struct FunctionObject {
+    void operator()() const { }
+};
+
+template <typename T>
+constexpr FunctionObject f{};
+
+int main() {
+    f<int>();
+}

Reply via email to