From: Jason Merrill Date: Mon, 3 Nov 2025 14:51:38 +0000 (+0300) Subject: c++: modules, clones, and overload resolution X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9f428ffbd4b6de9c940f1a1a304973bcd2f2bd4e;p=thirdparty%2Fgcc.git c++: modules, clones, and overload resolution 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 , 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. --- diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index b475b07dcb1..e9cacf157c4 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -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 index 00000000000..4a72e8ff07b --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/clone-5_a.C @@ -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 + struct A { + A(const T* p, unsigned long len) { ++i; } + template + requires (!__is_convertible(E,unsigned long)) + A(B,E) { ++i; } + }; + + inline void f() + { + const char *const p = nullptr; + A a (p, p); // instantiate A + } +} 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 index 00000000000..f66b4655caf --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/clone-5_b.C @@ -0,0 +1,9 @@ +// { dg-additional-options -fmodules } + +import M; + +int main() +{ + const char *const p = nullptr; + A (p, 0); +}