]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: modules, clones, and overload resolution
authorJason Merrill <jason@redhat.com>
Mon, 3 Nov 2025 14:51:38 +0000 (17:51 +0300)
committerJason Merrill <jason@redhat.com>
Mon, 3 Nov 2025 14:51:38 +0000 (17:51 +0300)
21_strings/basic_string_view/cons/wchar_t/3.cc was failing with import std
because as in the reduced testcase, the module includes an instantiation of
the template constructor for <const char *, const char *>, and importing the
module was wrongly adding that instantiation to CLASSTYPE_MEMBER_VEC, so it
became part of the overload set independent of its template.
tsubst_function_decl doesn't add to CLASSTYPE_MEMBER_VEC, and importing
should work the same.

gcc/cp/ChangeLog:

* module.cc (trees_in::decl_value): Don't add an instantiation to
CLASSTYPE_MEMBER_VEC.

gcc/testsuite/ChangeLog:

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

gcc/cp/module.cc
gcc/testsuite/g++.dg/modules/clone-5_a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/clone-5_b.C [new file with mode: 0644]

index b475b07dcb1cb0da010ac39d342f4a6738825c65..e9cacf157c4e8c42e296440aed30a0b6ec6bdf0f 100644 (file)
@@ -8996,11 +8996,14 @@ trees_in::decl_value ()
          dump (dumper::TREE) && dump ("CDTOR %N is %scloned",
                                       decl, cloned_p ? "" : "not ");
          if (cloned_p)
-           build_cdtor_clones (decl, flags & 2, flags & 4,
-                               /* Update the member vec, if there is
-                                  one (we're in a different cluster
-                                  to the class defn).  */
-                               CLASSTYPE_MEMBER_VEC (DECL_CONTEXT (decl)));
+           {
+             /* Update the member vec, if there is one (we're in a different
+                cluster to the class defn) and this isn't a primary template
+                specialization (as in tsubst_function_decl).  */
+             bool up = (CLASSTYPE_MEMBER_VEC (DECL_CONTEXT (decl))
+                        && !primary_template_specialization_p (decl));
+             build_cdtor_clones (decl, flags & 2, flags & 4, up);
+           }
        }
     }
 
diff --git a/gcc/testsuite/g++.dg/modules/clone-5_a.C b/gcc/testsuite/g++.dg/modules/clone-5_a.C
new file mode 100644 (file)
index 0000000..4a72e8f
--- /dev/null
@@ -0,0 +1,25 @@
+// Test that a random instantiation of a constructor template doesn't end up in
+// the overload set for other arguments.
+
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-fmodules" }
+
+export module M;
+
+export {
+  inline int i;
+
+  template <class T>
+    struct A {
+    A(const T* p, unsigned long len) { ++i; }
+    template <class B, class E>
+    requires (!__is_convertible(E,unsigned long))
+    A(B,E) { ++i; }
+  };
+
+  inline void f()
+  {
+    const char *const p = nullptr;
+    A<char> a (p, p);          // instantiate A<const char *, const char *>
+  }
+}
diff --git a/gcc/testsuite/g++.dg/modules/clone-5_b.C b/gcc/testsuite/g++.dg/modules/clone-5_b.C
new file mode 100644 (file)
index 0000000..f66b465
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-additional-options -fmodules }
+
+import M;
+
+int main()
+{
+  const char *const p = nullptr;
+  A<char> (p, 0);
+}