https://gcc.gnu.org/g:c1b4b71cfc958a622663ee5eb67a6acc5f9bb9b6

commit r14-12598-gc1b4b71cfc958a622663ee5eb67a6acc5f9bb9b6
Author: Jonathan Wakely <[email protected]>
Date:   Tue Mar 17 15:58:10 2026 +0000

    libstdc++: Optimize fs::path::operator+=(const path&) alias check
    
    Instead of a loop that compares &p to the address of each path
    component, we can just do two pointer comparisons to see if &p is within
    the contiguous array of components.
    
    We don't need to make the same change to experimental::filesystem::path
    because as noted in r15-9709-gbeb0ffd36eedf0 the TS implementation
    doesn't attempt to optimize operator+= so doesn't care if the parameter
    aliases *this.
    
    libstdc++-v3/ChangeLog:
    
            * src/c++17/fs_path.cc (path::operator+=): Use pointer
            comparison to detect aliasing instead of a loop.
    
    Reviewed-by: Tomasz KamiƄski <[email protected]>
    (cherry picked from commit 881b327773d3f366c2b638e3d07ef310b2a2dfe2)

Diff:
---
 libstdc++-v3/src/c++17/fs_path.cc | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/src/c++17/fs_path.cc 
b/libstdc++-v3/src/c++17/fs_path.cc
index 857887ec58d8..94793da64105 100644
--- a/libstdc++-v3/src/c++17/fs_path.cc
+++ b/libstdc++-v3/src/c++17/fs_path.cc
@@ -886,9 +886,11 @@ path::operator+=(const path& p)
     return *this += p.native();
   // Handle p += *i where i is in [p.begin(),p.end()), for the same reason.
   if (_M_type() == _Type::_Multi && p._M_type() != _Type::_Multi)
-    for (const path& cmpt : *this)
-      if (&cmpt == &p) [[unlikely]]
+    {
+      const auto first = _M_cmpts.begin(), last = first + _M_cmpts.size();
+      if (!std::less<>()(&p, first) && std::less<>()(&p, last)) [[unlikely]]
        return *this += p.native();
+    }
 
 #if _GLIBCXX_FILESYSTEM_IS_WINDOWS
   if (_M_type() == _Type::_Root_name

Reply via email to