The __pool_resource::_M_unpooled member was declared with type
std::vector, which means that the type depends on whether debug mode is
active or not. Because the non-inline definitions in
src/c++17/memory_resource.cc are never compiled with debug mode, the
type declared in the header doesn't match the type in the library
definitions, leading to undefined behaviour.

The solution is to ensure the header always uses the non-debug vector,
even when debug mode is active. To make this easier a new alias template
is defined: _GLIBCXX_STD_C::pmr::vector.

        * include/std/memory_resource (__pool_resource::_M_unpooled): Use
        normal mode vector, even for debug mode.
        * include/std/vector [_GLIBCXX_DEBUG] (_GLIBCXX_STD_C::pmr::vector):
        Define alias template for normal mode vector.

Tested x86_64-linux, committed to trunk.


commit 88ea7aa5bcdfc98ead7f9ab5b01c8c58d482799c
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Mon Jan 28 23:37:27 2019 +0000

    Ensure pool resources always use normal mode vector
    
    The __pool_resource::_M_unpooled member was declared with type
    std::vector, which means that the type depends on whether debug mode is
    active or not. Because the non-inline definitions in
    src/c++17/memory_resource.cc are never compiled with debug mode, the
    type declared in the header doesn't match the type in the library
    definitions, leading to undefined behaviour.
    
    The solution is to ensure the header always uses the non-debug vector,
    even when debug mode is active. To make this easier a new alias template
    is defined: _GLIBCXX_STD_C::pmr::vector.
    
            * include/std/memory_resource (__pool_resource::_M_unpooled): Use
            normal mode vector, even for debug mode.
            * include/std/vector [_GLIBCXX_DEBUG] (_GLIBCXX_STD_C::pmr::vector):
            Define alias template for normal mode vector.

diff --git a/libstdc++-v3/include/std/memory_resource 
b/libstdc++-v3/include/std/memory_resource
index 5573494b01f..93b2ebd9759 100644
--- a/libstdc++-v3/include/std/memory_resource
+++ b/libstdc++-v3/include/std/memory_resource
@@ -354,7 +354,7 @@ namespace pmr
     struct _BigBlock;
     // Collection of blocks too big for any pool, sorted by address.
     // This also stores the only copy of the upstream memory resource pointer.
-    pmr::vector<_BigBlock> _M_unpooled;
+    _GLIBCXX_STD_C::pmr::vector<_BigBlock> _M_unpooled;
 
     const int _M_npools;
   };
diff --git a/libstdc++-v3/include/std/vector b/libstdc++-v3/include/std/vector
index 2c90765b058..e5e13ab3ef7 100644
--- a/libstdc++-v3/include/std/vector
+++ b/libstdc++-v3/include/std/vector
@@ -89,6 +89,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template<typename _Tp>
       using vector = std::vector<_Tp, polymorphic_allocator<_Tp>>;
   } // namespace pmr
+# ifdef _GLIBCXX_DEBUG
+  namespace _GLIBCXX_STD_C::pmr {
+    template<typename _Tp>
+      using vector
+       = _GLIBCXX_STD_C::vector<_Tp, std::pmr::polymorphic_allocator<_Tp>>;
+  } // namespace _GLIBCXX_STD_C::pmr
+# endif
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 #endif // C++17

Reply via email to