https://gcc.gnu.org/g:b624ebefa3a6a591924c0d680772ba89c5cd08d2
commit r17-4588-gb624ebefa3a6a591924c0d680772ba89c5cd08d2 Author: Jonathan Wakely <[email protected]> Date: Thu Sep 17 12:16:38 2026 +0100 libstdc++: Use deleted functions in C++98 mode We can use deleted functions in C++98 mode if we use pragmas to disable the -Wc++11-extensions diagnostics. This works with both GCC and Clang. In some cases this makes the code more robust in C++98 mode because we were previously not making types copyable at all (e.g., _Reuse_or_alloc_node in bits/stl_tree.h) and just relying on testing in C++11 and later to know we didn't use those functions. In other cases it gives better diagnostics because we were defining copy constructors and assignment operators as private libstdc++-v3/ChangeLog: * config/io/basic_file_stdio.h (__basic_file): Define copy constructor and copy assignment operator as deleted for C++98. * include/bits/stl_bvector.h (vector<bool, A>::data): Define as deleted for C++98. * include/bits/stl_tree.h (_Reuse_or_alloc_node): Define copy constructor as deleted for C++98. * include/bits/stl_vector.h (_Asan<allocator<T>>::_Reinit): Define copy constructor and copy assignment operator as deleted for C++98. (_Asan<allocator<T>>::_Grow): Likewise. * testsuite/util/replacement_memory_operators.h (__gnu_test::counter::scope): Likewise. * testsuite/util/testsuite_iterators.h (operator,, operator&) (operator+=, operator-=, operator[]): Define deleted operators for C++98. Reviewed-by: Tomasz KamiĆski <[email protected]> Diff: --- libstdc++-v3/config/io/basic_file_stdio.h | 9 ++++-- libstdc++-v3/include/bits/stl_bvector.h | 8 ++---- libstdc++-v3/include/bits/stl_tree.h | 5 ++-- libstdc++-v3/include/bits/stl_vector.h | 8 +++--- .../testsuite/util/replacement_memory_operators.h | 14 ++++------ libstdc++-v3/testsuite/util/testsuite_iterators.h | 32 ++++------------------ 6 files changed, 28 insertions(+), 48 deletions(-) diff --git a/libstdc++-v3/config/io/basic_file_stdio.h b/libstdc++-v3/config/io/basic_file_stdio.h index 5e06fd378eab..b480eb943f0c 100644 --- a/libstdc++-v3/config/io/basic_file_stdio.h +++ b/libstdc++-v3/config/io/basic_file_stdio.h @@ -62,6 +62,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: __basic_file(__c_lock* __lock = 0) throw (); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++11-extensions" + __basic_file(const __basic_file&) = delete; + __basic_file& operator=(const __basic_file&) = delete; +#pragma GCC diagnostic pop + #if __cplusplus >= 201103L __basic_file(__basic_file&& __rv, __c_lock* = 0) noexcept : _M_cfile(__rv._M_cfile), _M_cfile_created(__rv._M_cfile_created) @@ -70,9 +76,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __rv._M_cfile_created = false; } - __basic_file& operator=(const __basic_file&) = delete; - __basic_file& operator=(__basic_file&&) = delete; - void swap(__basic_file& __f) noexcept { diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index d792f7077860..3cdb48f3983c 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -1763,12 +1763,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // DR 464. Suggestion for new member functions in standard containers. // N.B. DR 464 says nothing about vector<bool> but we need something // here due to the using-declaration in __gnu_debug::vector. - // vector class. -#if __cplusplus >= 201103L +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++11-extensions" void data() = delete; -#else - void data() { } -#endif +#pragma GCC diagnostic pop }; _GLIBCXX_END_NAMESPACE_CONTAINER diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 313ee8160023..da1fbd304c0c 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -1057,9 +1057,10 @@ namespace __rb_tree _M_nodes = _Base_ptr(); } -#if __cplusplus >= 201103L +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++11-extensions" _Reuse_or_alloc_node(const _Reuse_or_alloc_node&) = delete; -#endif +#pragma GCC diagnostic pop ~_Reuse_or_alloc_node() { diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 9ddf35502e69..73fee5c07a1d 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -173,6 +173,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #endif #if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++11-extensions" // deleted functions template<typename = _Tp_alloc_type> struct _Asan { @@ -249,10 +251,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Vector_impl& _M_impl; -#if __cplusplus >= 201103L _Reinit(const _Reinit&) = delete; _Reinit& operator=(const _Reinit&) = delete; -#endif }; // Tell ASan when unused capacity is initialized to be valid. @@ -269,15 +269,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _GLIBCXX20_CONSTEXPR void _M_grew(size_type __n) { _M_n -= __n; } -#if __cplusplus >= 201103L _Grow(const _Grow&) = delete; _Grow& operator=(const _Grow&) = delete; -#endif + private: _Vector_impl& _M_impl; size_type _M_n; }; }; +#pragma GCC diagnostic pop #define _GLIBCXX_ASAN_ANNOTATE_REINIT \ typename _Base::_Vector_impl::template _Asan<>::_Reinit const \ diff --git a/libstdc++-v3/testsuite/util/replacement_memory_operators.h b/libstdc++-v3/testsuite/util/replacement_memory_operators.h index c6485b571e56..53837cabecbf 100644 --- a/libstdc++-v3/testsuite/util/replacement_memory_operators.h +++ b/libstdc++-v3/testsuite/util/replacement_memory_operators.h @@ -87,16 +87,14 @@ namespace __gnu_test ~scope() { counter::get()._M_count = _M_count; } - private: - std::size_t _M_count; - -#if __cplusplus >= 201103L +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++11-extensions" scope(const scope&) = delete; scope& operator=(const scope&) = delete; -#else - scope(const scope&); - scope& operator=(const scope&); -#endif +#pragma GCC diagnostic pop + + private: + std::size_t _M_count; }; }; diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h index ca022e5d0f9c..8aefd7b11204 100644 --- a/libstdc++-v3/testsuite/util/testsuite_iterators.h +++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h @@ -47,6 +47,9 @@ #define ITERATOR_VERIFY(x) VERIFY(x) #endif +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++11-extensions" // deleted functions + namespace __gnu_test { /** @@ -193,24 +196,14 @@ namespace __gnu_test return tmp; } -#if __cplusplus >= 201103L template<typename U> void operator,(const U&) const = delete; void operator&() const = delete; -#else - private: - template<typename U> - void operator,(const U&) const; - - void operator&() const; -#endif }; -#if __cplusplus >= 201103L template<typename T, typename U> void operator,(const T&, const output_iterator_wrapper<U>&) = delete; -#endif #if __cplusplus >= 201103L using std::remove_cv; @@ -331,24 +324,14 @@ namespace __gnu_test return tmp; } -#if __cplusplus >= 201103L template<typename U> void operator,(const U&) const = delete; void operator&() const = delete; -#else - private: - template<typename U> - void operator,(const U&) const; - - void operator&() const; -#endif }; -#if __cplusplus >= 201103L template<typename T, typename U> void operator,(const T&, const input_iterator_wrapper<U>&) = delete; -#endif /** * @brief forward_iterator wrapper for pointer @@ -607,11 +590,11 @@ namespace __gnu_test T& operator[](std::ptrdiff_t n) const { return *(*this + n); } -#if __cplusplus >= 201103L // Ensure that the iterator's difference_type is always used. template<typename D> void operator+=(D) = delete; template<typename D> void operator-=(D) = delete; template<typename D> void operator[](D) const = delete; +#if __cplusplus >= 201103L template<typename D> typename std::enable_if<std::is_integral<D>::value>::type operator-(D) const = delete; @@ -655,13 +638,11 @@ namespace __gnu_test operator+(std::ptrdiff_t n, random_access_iterator_wrapper<T> it) { return it += n; } -#if __cplusplus >= 201103L // Ensure that the iterator's difference_type is always used. template<typename T, typename D> void operator+(random_access_iterator_wrapper<T>, D) = delete; template<typename T, typename D> void operator+(D, random_access_iterator_wrapper<T>) = delete; -#endif template<typename T> @@ -809,11 +790,11 @@ namespace __gnu_test return tmp; } -#if __cplusplus >= 201103L // Ensure that the iterator's difference_type is always used. template<typename D> void operator+=(D) = delete; template<typename D> void operator-=(D) = delete; template<typename D> void operator[](D) const = delete; +#if __cplusplus >= 201103L template<typename D> typename std::enable_if<std::is_integral<D>::value>::type operator-(D) const = delete; @@ -857,13 +838,11 @@ namespace __gnu_test operator+(std::ptrdiff_t n, proxy_random_access_iterator_wrapper<T> it) { return it += n; } -#if __cplusplus >= 201103L // Ensure that the iterator's difference_type is always used. template<typename T, typename D> void operator+(proxy_random_access_iterator_wrapper<T>, D) = delete; template<typename T, typename D> void operator+(D, proxy_random_access_iterator_wrapper<T>) = delete; -#endif /** * @brief A container-type class for holding iterator wrappers @@ -1292,4 +1271,5 @@ namespace __gnu_test #endif // C++20 } // namespace __gnu_test +#pragma GCC diagnostic pop #endif // _TESTSUITE_ITERATORS
