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]>
---

v2: Deleted copy ctor and copy assignment in basic_file_stdio.h

Tested x86_64-linux. Pushed to trunk.

 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 ++---
 .../util/replacement_memory_operators.h       | 14 ++++----
 .../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
-- 
2.55.0

Reply via email to