Constructor decloning can turn the C1/C2 entry points into thunks
that call the unified primary constructor, C4. That works only if
C4 remains a usable external interface.
For libstdc++ explicit instantiations on MinGW, that is not the case:
libstdc++ exports the complete and base constructor entry points, but
not the unified C4 symbol. With -Os this could leave user code with
references to an undefined C4 constructor, as in PR libstdc++/125359.
Avoid the thunking path for constructors in maybe_clone_body. Keep
constructor clones as real bodies so callers continue to target C1/C2
instead of the unified primary constructor.
gcc/cp/ChangeLog:
PR libstdc++/125359
* optimize.cc (maybe_clone_body): Do not thunk constructor clones
through the unified primary constructor.
gcc/testsuite/ChangeLog:
PR libstdc++/125359
* g++.dg/ext/pr125359.C: New test.
Signed-off-by: Oleg Tolmatcev <[email protected]>
---
gcc/cp/optimize.cc | 10 +++++++---
gcc/testsuite/g++.dg/ext/pr125359.C | 23 +++++++++++++++++++++++
2 files changed, 30 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/ext/pr125359.C
diff --git a/gcc/cp/optimize.cc b/gcc/cp/optimize.cc
index 31ee2aaccf..7f1968ce04 100644
--- a/gcc/cp/optimize.cc
+++ b/gcc/cp/optimize.cc
@@ -556,9 +556,13 @@ maybe_clone_body (tree fn)
bool can_alias = can_alias_cdtor (fn);
- /* If we decide to turn clones into thunks, they will branch to fn.
- Must have original function available to call. */
- if (!can_alias && maybe_thunk_body (fn, need_alias))
+ /* If we decide to turn clones into thunks, they will branch to FN.
+ For constructors that would make the C1/C2 entry points call the
+ unified primary ctor (C4), which is not a stable external interface.
+ Keep constructors as real cloned bodies so callers stay on C1/C2. */
+ if (!can_alias
+ && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
+ && maybe_thunk_body (fn, need_alias))
{
pop_from_top_level ();
/* We still need to emit the original function. */
diff --git a/gcc/testsuite/g++.dg/ext/pr125359.C
b/gcc/testsuite/g++.dg/ext/pr125359.C
new file mode 100644
index 0000000000..0d894abef6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/pr125359.C
@@ -0,0 +1,23 @@
+// PR libstdc++/125359
+// { dg-do link { target *-*-mingw* } }
+// { dg-options "-std=gnu++20 -Os" }
+
+#include <string>
+#include <utility>
+#include <vector>
+
+struct S
+{
+ std::string s;
+};
+
+int
+main ()
+{
+ std::vector<S> v;
+
+ S x = {};
+ x.s = "hello";
+
+ v.push_back (std::move (x));
+}
--
2.55.0.windows.1