]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++/modules: Really always track partial specialisations [PR116496]
authorNathaniel Shead <nathanieloshead@gmail.com>
Wed, 11 Sep 2024 12:41:21 +0000 (22:41 +1000)
committerNathaniel Shead <nathanieloshead@gmail.com>
Thu, 12 Sep 2024 01:09:19 +0000 (11:09 +1000)
My last fix for this issue (PR c++/114947, r15-810) didn't go far
enough; I had assumed that the issue where we lost track of partial
specialisations we would need to walk again later was limited to
partitions (where we always re-walk all specialisations), but the linked
PR is the same cause but for header units, and it is possible to
construct test cases exposing the same bug just for normal modules.

As such this patch just unconditionally ensures that whenever we modify
DECL_TEMPLATE_SPECIALIZATIONS we also track any partial specialisations
that might have added.

Also clean up a couple of comments and assertions to make expected state
more obvious when processing these specs.

PR c++/116496

gcc/cp/ChangeLog:

* module.cc (trees_in::decl_value): Don't call
set_defining_module_for_partial_spec here.
(depset::hash::add_partial_entities): Clarity assertions.
* pt.cc (add_mergeable_specialization): Always call
set_defining_module_for_partial_spec when adding a partial spec.

gcc/testsuite/ChangeLog:

* g++.dg/modules/partial-5_a.C: New test.
* g++.dg/modules/partial-5_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
gcc/cp/module.cc
gcc/cp/pt.cc
gcc/testsuite/g++.dg/modules/partial-5_a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/partial-5_b.C [new file with mode: 0644]

index dc0e9e5520f977da1a6d4e6ea0fc9a318c5974e9..f5df9e875d3af6383ec93c12cf28db02f790f30c 100644 (file)
@@ -8434,11 +8434,6 @@ trees_in::decl_value ()
          add_mergeable_specialization (!is_type, &spec, decl, spec_flags);
        }
 
-      /* When making a CMI from a partition we're going to need to walk partial
-        specializations again, so make sure they're tracked.  */
-      if (state->is_partition () && (spec_flags & 2))
-       set_defining_module_for_partial_spec (inner);
-
       if (NAMESPACE_SCOPE_P (decl)
          && (mk == MK_named || mk == MK_unique
              || mk == MK_enum || mk == MK_friend_spec)
@@ -13356,16 +13351,20 @@ depset::hash::add_partial_entities (vec<tree, va_gc> *partial_classes)
             specialization.  */
          gcc_checking_assert (dep->get_entity_kind ()
                               == depset::EK_PARTIAL);
+
+         /* Only emit GM entities if reached.  */
+         if (!DECL_LANG_SPECIFIC (inner)
+             || !DECL_MODULE_PURVIEW_P (inner))
+           dep->set_flag_bit<DB_UNREACHED_BIT> ();
        }
       else
-       /* It was an explicit specialization, not a partial one.  */
-       gcc_checking_assert (dep->get_entity_kind ()
-                            == depset::EK_SPECIALIZATION);
-
-      /* Only emit GM entities if reached.  */
-      if (!DECL_LANG_SPECIFIC (inner)
-         || !DECL_MODULE_PURVIEW_P (inner))
-       dep->set_flag_bit<DB_UNREACHED_BIT> ();
+       {
+         /* It was an explicit specialization, not a partial one.
+            We should have already added this.  */
+         gcc_checking_assert (dep->get_entity_kind ()
+                              == depset::EK_SPECIALIZATION);
+         gcc_checking_assert (dep->is_special ());
+       }
     }
 }
 
index 310e5dfff0335ff2ad8ec11ea3ff0b129d1b09ff..cb3164d491473bd15802b646127476253369af6d 100644 (file)
@@ -31684,6 +31684,7 @@ add_mergeable_specialization (bool decl_p, spec_entry *elt, tree decl,
                             DECL_TEMPLATE_SPECIALIZATIONS (elt->tmpl));
       TREE_TYPE (cons) = decl_p ? TREE_TYPE (elt->spec) : elt->spec;
       DECL_TEMPLATE_SPECIALIZATIONS (elt->tmpl) = cons;
+      set_defining_module_for_partial_spec (STRIP_TEMPLATE (decl));
     }
 }
 
diff --git a/gcc/testsuite/g++.dg/modules/partial-5_a.C b/gcc/testsuite/g++.dg/modules/partial-5_a.C
new file mode 100644 (file)
index 0000000..768e699
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/116496
+// { dg-additional-options "-fmodules-ts -std=c++20 -Wno-global-module" }
+// { dg-module-cmi A }
+
+module;
+template <typename T> struct S {};
+export module A;
+template <typename T> struct S<T*> {};
+template <typename T> requires false struct S<T*> {};
diff --git a/gcc/testsuite/g++.dg/modules/partial-5_b.C b/gcc/testsuite/g++.dg/modules/partial-5_b.C
new file mode 100644 (file)
index 0000000..95401fe
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/116496
+// { dg-additional-options "-fmodules-ts -std=c++20 -Wno-global-module" }
+// { dg-module-cmi B }
+
+module;
+template <typename T> struct S {};
+export module B;
+import A;
+template <typename T> requires true struct S<T*> {};