Patchwork [google,gcc-4_7,gcc-4_8,integration] Relax vector validity checks

login
register
mail settings
Submitter Paul Pluzhnikov
Date May 30, 2013, 10:19 p.m.
Message ID <ye6qtxlkxg9e.fsf@elbrus2.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/247808/
State New
Headers show

Comments

Paul Pluzhnikov - May 30, 2013, 10:19 p.m.
Greetings,

The vector validity checks introduced here:
http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00415.html

proved too strict: older versions of GCC used to do this:

  _M_start = _M_end = _M_end_of_storage = new_allocator(sizeof(T) * n)

even when n == 0, and we have code compiled by such version linked in
with new code, and failing the check.

Google ref b/9198806

Attached patch relaxes the check, while still catching dangling vector
accesses.

Ok for google/gcc_4-7, gcc-4_8 and integration branches?

Thanks,

--
Paul Pluzhnikov
Diego Novillo - May 31, 2013, 1:48 a.m.
On 2013-05-30 18:19 , Paul Pluzhnikov wrote:
> Ok for google/gcc_4-7, gcc-4_8 and integration branches?

OK.  Is this applicable to trunk and/or release branches?


Diego.
Paul Pluzhnikov - May 31, 2013, 1:52 a.m.
On Thu, May 30, 2013 at 6:48 PM, Diego Novillo <dnovillo@google.com> wrote:

> OK.  Is this applicable to trunk and/or release branches?

No: the "cheap" vector and string checks are on google branches only.

Patch

Index: libstdc++-v3/include/bits/stl_vector.h
===================================================================
--- libstdc++-v3/include/bits/stl_vector.h	(revision 199461)
+++ libstdc++-v3/include/bits/stl_vector.h	(working copy)
@@ -244,12 +244,27 @@ 
 
       bool _M_is_valid() const
       {
-        return (this->_M_impl._M_end_of_storage == 0
-		&& this->_M_impl._M_start == 0
-		&& this->_M_impl._M_finish == 0)
-	      || (this->_M_impl._M_start <= this->_M_impl._M_finish
-		  && this->_M_impl._M_finish <= this->_M_impl._M_end_of_storage
-		  && this->_M_impl._M_start < this->_M_impl._M_end_of_storage);
+        if (this->_M_impl._M_end_of_storage == 0
+	    && this->_M_impl._M_start == 0
+	    && this->_M_impl._M_finish == 0)
+	  return true;
+
+	if (this->_M_impl._M_start <= this->_M_impl._M_finish
+	    && this->_M_impl._M_finish <= this->_M_impl._M_end_of_storage)
+	  {
+	    if (this->_M_impl._M_start < this->_M_impl._M_end_of_storage)
+	      return true;
+	    else if (this->_M_impl._M_start == this->_M_impl._M_end_of_storage
+		     && this->_M_impl._M_start == this->_M_impl._M_finish)
+	      {
+		pointer _0xcdcd;
+
+		__builtin_memset(&_0xcdcd, 0xcd, sizeof(_0xcdcd));
+		return this->_M_impl._M_finish != _0xcdcd;
+	      }
+	  }
+
+	return false;
       }
 
     public: