https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108636

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The problem with path::_List::type(_Type) is that it's only ever used by a
private constructor of path, which is only ever called from within the library.
But when you use -fkeep-inline-functions that private constructor gets compiled
into your code even though you don't (and can't) ever use it.

The fix is to move the definitions of those private constructors into the
library too, so that they aren't compiled into your code even with
-fkeep-inline-functions.

diff --git a/libstdc++-v3/include/bits/fs_path.h
b/libstdc++-v3/include/bits/fs_path.h
index 1cbfaaa5427..0d7bb10c1a0 100644
--- a/libstdc++-v3/include/bits/fs_path.h
+++ b/libstdc++-v3/include/bits/fs_path.h
@@ -596,12 +596,7 @@ namespace __detail
       _Multi = 0, _Root_name, _Root_dir, _Filename
     };

-    path(basic_string_view<value_type> __str, _Type __type)
-    : _M_pathname(__str)
-    {
-      __glibcxx_assert(__type != _Type::_Multi);
-      _M_cmpts.type(__type);
-    }
+    path(basic_string_view<value_type> __str, _Type __type);

     enum class _Split { _Stem, _Extension };

@@ -851,8 +846,7 @@ namespace __detail

   struct path::_Cmpt : path
   {
-    _Cmpt(basic_string_view<value_type> __s, _Type __t, size_t __pos)
-      : path(__s, __t), _M_pos(__pos) { }
+    _Cmpt(basic_string_view<value_type> __s, _Type __t, size_t __pos);

     _Cmpt() : _M_pos(-1) { }

diff --git a/libstdc++-v3/src/c++17/fs_path.cc
b/libstdc++-v3/src/c++17/fs_path.cc
index 93149c4b415..aaea7d2725d 100644
--- a/libstdc++-v3/src/c++17/fs_path.cc
+++ b/libstdc++-v3/src/c++17/fs_path.cc
@@ -187,6 +187,19 @@ struct path::_Parser
   { return origin + c.str.data() - input.data(); }
 };

+inline
+path::path(basic_string_view<value_type> __str, _Type __type)
+: _M_pathname(__str)
+{
+  __glibcxx_assert(__type != _Type::_Multi);
+  _M_cmpts.type(__type);
+}
+
+inline
+path::_Cmpt::_Cmpt(basic_string_view<value_type> __s, _Type __t, size_t __pos)
+: path(__s, __t), _M_pos(__pos)
+{ }
+
 struct path::_List::_Impl
 {
   using value_type = _Cmpt;


The good news is this doesn't have any ABI impact, so can be backported to the
release branches.

For the other undefined symbols noted in comment 1, those require new symbols
to be exported from the library. The good news there is that the comparisons
with default_sentinel_t are new in GCC 13 and so we don't need to backport
anything.

Reply via email to