aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2022-09-22 08:46:23 -0400
committerPatrick Palka <ppalka@redhat.com>2022-09-22 08:46:23 -0400
commit32d8123cd6ce87acb557aec230e8359051316f9f (patch)
tree17846c76f1efa66fdfaa1a5e08c0d1fbe6266342 /gcc/testsuite
parent26607a63da99226a020e3318468139a672a14153 (diff)
downloadgcc-32d8123cd6ce87acb557aec230e8359051316f9f.zip
gcc-32d8123cd6ce87acb557aec230e8359051316f9f.tar.gz
gcc-32d8123cd6ce87acb557aec230e8359051316f9f.tar.bz2
c++ modules: partial variable template specializations [PR106826]
With partial variable template specializations, it looks like we stream the VAR_DECL (i.e. the DECL_TEMPLATE_RESULT of the corresponding TEMPLATE_DECL) since process_partial_specialization adds it to the specializations table, but we end up never streaming the corresponding TEMPLATE_DECL itself that's reachable only from the primary template's DECL_TEMPLATE_SPECIALIZATIONS list, which leads to this list being incomplete on stream-in. The modules machinery already has special logic for streaming partial specializations of class templates; this patch attempts to generalize it to handle those of variable templates as well. PR c++/106826 gcc/cp/ChangeLog: * module.cc (trees_out::decl_value): Use get_template_info in the MK_partial case to handle both VAR_DECL and TYPE_DECL. (trees_out::key_mergeable): Likewise. (trees_in::key_mergeable): Likewise. (has_definition): Consider DECL_INITIAL of a partial variable template specialization. (depset::hash::make_dependency): Handle partial variable template specializations too. gcc/testsuite/ChangeLog: * g++.dg/modules/partial-2_a.C: New test. * g++.dg/modules/partial-2_b.C: New test.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2_a.C43
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2_b.C21
2 files changed, 64 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_a.C b/gcc/testsuite/g++.dg/modules/partial-2_a.C
new file mode 100644
index 0000000..2681bb5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2_a.C
@@ -0,0 +1,43 @@
+// PR c++/106826
+// { dg-additional-options -fmodules-ts }
+// { dg-module-cmi pr106826 }
+export module pr106826;
+
+template<class T> constexpr bool is_reference_v = false;
+template<class T> constexpr bool is_reference_v<T&> = true;
+template<class T> constexpr bool is_reference_v<T&&> = true;
+
+struct A {
+ template<class T> static constexpr bool is_reference_v = false;
+};
+
+template<class T> constexpr bool A::is_reference_v<T&> = true;
+template<class T> constexpr bool A::is_reference_v<T&&> = true;
+
+#if __cpp_concepts
+namespace concepts {
+ template<class T> bool is_reference_v;
+
+ template<class T> requires __is_same(T, T&)
+ constexpr bool is_reference_v<T> = true;
+
+ template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
+ constexpr bool is_reference_v<T> = true;
+
+ template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
+ constexpr bool is_reference_v<T> = false;
+
+ struct A {
+ template<class T> static bool is_reference_v;
+ };
+
+ template<class T> requires __is_same(T, T&)
+ constexpr bool A::is_reference_v<T> = true;
+
+ template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
+ constexpr bool A::is_reference_v<T> = true;
+
+ template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
+ constexpr bool A::is_reference_v<T> = false;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_b.C b/gcc/testsuite/g++.dg/modules/partial-2_b.C
new file mode 100644
index 0000000..0af41ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2_b.C
@@ -0,0 +1,21 @@
+// PR c++/106826
+// { dg-additional-options -fmodules-ts }
+module pr106826;
+
+static_assert(is_reference_v<int&>);
+static_assert(is_reference_v<int&&>);
+static_assert(!is_reference_v<int>);
+
+static_assert(A::is_reference_v<long&>);
+static_assert(A::is_reference_v<long&&>);
+static_assert(!A::is_reference_v<long>);
+
+#if __cpp_concepts
+static_assert(concepts::is_reference_v<char&>);
+static_assert(concepts::is_reference_v<char&&>);
+static_assert(!concepts::is_reference_v<char>);
+
+static_assert(concepts::A::is_reference_v<bool&>);
+static_assert(concepts::A::is_reference_v<bool&&>);
+static_assert(!concepts::A::is_reference_v<bool>);
+#endif