Patchwork [google,gcc-4_7,integration] Add lightweight checks for front()/back() on empty vector

login
register
mail settings
Submitter Paul Pluzhnikov
Date Jan. 19, 2013, 7:23 p.m.
Message ID <ye6q4nid3rk3.fsf@elbrus2.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/213880/
State New
Headers show

Comments

Paul Pluzhnikov - Jan. 19, 2013, 7:23 p.m.
This patch adds lightweight checks for front()/back() on empty vector.

Google ref b/7939186

Ok for google/gcc-4_7 and google/integration branches?

--
Paul Pluzhnikov
Gerald Pfeifer - Jan. 20, 2013, 11:16 a.m.
On Sat, 19 Jan 2013, Paul Pluzhnikov wrote:
> This patch adds lightweight checks for front()/back() on empty vector.

>        front()
> -      { return *begin(); }
> +      {
> +#if __google_stl_debug_vector
> +        if (empty()) __throw_logic_error("begin() on empty vector");

Isn't the error message wrong, then?  begin() on an empty vector
is perfectly fine, isn't it?  *begin() is the problem here, so
should this say

           if (empty()) __throw_logic_error("front() on empty vector");

instead?

> +#if __google_stl_debug_vector
> +        if (empty()) __throw_logic_error("back() on empty vector");
> +#endif

In the symmetric case you're already using back(), not end().

Gerald

Patch

Index: libstdc++-v3/include/bits/stl_vector.h
===================================================================
--- libstdc++-v3/include/bits/stl_vector.h	(revision 195313)
+++ libstdc++-v3/include/bits/stl_vector.h	(working copy)
@@ -878,7 +878,12 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        */
       reference
       front()
-      { return *begin(); }
+      {
+#if __google_stl_debug_vector
+        if (empty()) __throw_logic_error("begin() on empty vector");
+#endif
+        return *begin();
+      }
 
       /**
        *  Returns a read-only (constant) reference to the data at the first
@@ -886,7 +891,12 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        */
       const_reference
       front() const
-      { return *begin(); }
+      {
+#if __google_stl_debug_vector
+        if (empty()) __throw_logic_error("begin() on empty vector");
+#endif
+        return *begin();
+      }
 
       /**
        *  Returns a read/write reference to the data at the last
@@ -894,7 +904,12 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        */
       reference
       back()
-      { return *(end() - 1); }
+      {
+#if __google_stl_debug_vector
+        if (empty()) __throw_logic_error("back() on empty vector");
+#endif
+        return *(end() - 1);
+      }
       
       /**
        *  Returns a read-only (constant) reference to the data at the
@@ -902,7 +917,12 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        */
       const_reference
       back() const
-      { return *(end() - 1); }
+      {
+#if __google_stl_debug_vector
+        if (empty()) __throw_logic_error("back() on empty vector");
+#endif
+        return *(end() - 1);
+      }
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR 464. Suggestion for new member functions in standard containers.
@@ -917,7 +937,12 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       pointer
 #endif
       data() _GLIBCXX_NOEXCEPT
-      { return std::__addressof(front()); }
+      {
+#if __google_stl_debug_vector
+        if (empty()) return 0;
+#endif
+        return std::__addressof(front());
+      }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       const _Tp*
@@ -925,7 +950,12 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       const_pointer
 #endif
       data() const _GLIBCXX_NOEXCEPT
-      { return std::__addressof(front()); }
+      {
+#if __google_stl_debug_vector
+        if (empty()) return 0;
+#endif
+        return std::__addressof(front());
+      }
 
       // [23.2.4.3] modifiers
       /**