From 82cd63a63eaa61a4ed5c4029a1869be7446ecb3c Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Wed, 7 Aug 2024 19:08:07 +0200
Subject: [PATCH] c++: Implement CWG2387 - Linkage of const-qualified variable
 template [PR109126]

The following patch attempts to implement DR2387 by making variable
templates including their specialization TREE_PUBLIC when at file
scope and they don't have static storage class.

2024-08-07  Jakub Jelinek  <jakub@redhat.com>

	PR c++/109126
	* decl.cc (grokvardecl): Implement CWG 2387 - Linkage of
	const-qualified variable template.  Set TREE_PUBLIC on variable
	templates with const qualified types unless static is present.

	* g++.dg/DRs/dr2387.C: New test.
	* g++.dg/DRs/dr2387-aux.cc: New file.
---
 gcc/cp/decl.cc                         |  2 ++
 gcc/testsuite/g++.dg/DRs/dr2387-aux.cc | 25 +++++++++++++++++++++++++
 gcc/testsuite/g++.dg/DRs/dr2387.C      | 22 ++++++++++++++++++++++
 3 files changed, 49 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/DRs/dr2387-aux.cc
 create mode 100644 gcc/testsuite/g++.dg/DRs/dr2387.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 86d2bfab22dc..a468bfdb7b67 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -11225,6 +11225,8 @@ grokvardecl (tree type,
 				|| ! constp
 				|| volatilep
 				|| inlinep
+				|| in_template_context
+				|| processing_specialization
 				|| module_attach_p ()));
       TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
     }
diff --git a/gcc/testsuite/g++.dg/DRs/dr2387-aux.cc b/gcc/testsuite/g++.dg/DRs/dr2387-aux.cc
new file mode 100644
index 000000000000..7a78ac230157
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2387-aux.cc
@@ -0,0 +1,25 @@
+// DR 2387
+
+template <int N>
+extern const int a;
+template <int N>
+static const int b = N;
+template <int N>
+extern const int c;
+template <int N>
+extern const volatile int d;
+template <int N>
+extern const int e;
+extern const int *pa, *pb, *pc, *pe;
+extern const volatile int *pd;
+
+int
+main ()
+{
+  if (pa != &a <42>
+      || pb == &b <42>
+      || pc != &c <42>
+      || pd != &d <42>
+      || pe != &e <43>)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/DRs/dr2387.C b/gcc/testsuite/g++.dg/DRs/dr2387.C
new file mode 100644
index 000000000000..afbe618d5179
--- /dev/null
+++ b/gcc/testsuite/g++.dg/DRs/dr2387.C
@@ -0,0 +1,22 @@
+// DR 2387
+// { dg-do run { target c++14 } }
+// { dg-additional-sources "dr2387-aux.cc" }
+
+template <int N>
+const int a = N;
+template <int N>
+static const int b = N;
+template <int N>
+extern const int c = N;
+template <int N>
+const volatile int d = N;
+template <int N>
+const int e = N;
+template <>
+const int e <43> = 44;
+
+const int *pa = &a <42>;
+const int *pb = &b <42>;
+const int *pc = &c <42>;
+const volatile int *pd = &d <42>;
+const int *pe = &e <43>;
-- 
GitLab