diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-20 05:47:14 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-20 05:47:14 +0000 |
commit | 1e4770f91c357e5499dff7f1dbf557c2f4b7790a (patch) | |
tree | 7d717a91d86313e2c7f23d43505f9b372fa41eab /base/memory | |
parent | d54cf816835b99455788b46070a88220bfb6ad86 (diff) | |
download | chromium_src-1e4770f91c357e5499dff7f1dbf557c2f4b7790a.zip chromium_src-1e4770f91c357e5499dff7f1dbf557c2f4b7790a.tar.gz chromium_src-1e4770f91c357e5499dff7f1dbf557c2f4b7790a.tar.bz2 |
Fix scoped_ptr::Pass to not rely on undefined behavior
Invoking "other.release()" where other is of type RValue invokes undefined behavior, because the given pointer is actually of type scoped_ptr<C>. With the NaCl toolchain, this doesn't work as intended, and the pointed-to object gets destructed twice.
BUG=116317
TEST=
Review URL: https://chromiumcodereview.appspot.com/10579030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143150 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/memory')
-rw-r--r-- | base/memory/scoped_ptr.h | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/base/memory/scoped_ptr.h b/base/memory/scoped_ptr.h index 4bded15..8e4ff62 100644 --- a/base/memory/scoped_ptr.h +++ b/base/memory/scoped_ptr.h @@ -153,7 +153,12 @@ class scoped_ptr { scoped_ptr(scoped_ptr<U> other) : ptr_(other.release()) { } // Constructor. Move constructor for C++03 move emulation of this type. - scoped_ptr(RValue& other) : ptr_(other.release()) { } + scoped_ptr(RValue& other) + // The type of the underlying object is scoped_ptr; we have to + // reinterpret_cast back to the original type for the call to release to + // be valid. (See C++11 5.2.10.7) + : ptr_(reinterpret_cast<scoped_ptr&>(other).release()) { + } // Destructor. If there is a C object, delete it. // We don't need to test ptr_ == NULL because C++ does that for us. @@ -279,7 +284,12 @@ class scoped_array { explicit scoped_array(C* p = NULL) : array_(p) { } // Constructor. Move constructor for C++03 move emulation of this type. - scoped_array(RValue& other) : array_(other.release()) { } + scoped_array(RValue& other) + // The type of the underlying object is scoped_array; we have to + // reinterpret_cast back to the original type for the call to release to + // be valid. (See C++11 5.2.10.7) + : array_(reinterpret_cast<scoped_array&>(other).release()) { + } // Destructor. If there is a C object, delete it. // We don't need to test ptr_ == NULL because C++ does that for us. @@ -396,7 +406,12 @@ class scoped_ptr_malloc { explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {} // Constructor. Move constructor for C++03 move emulation of this type. - scoped_ptr_malloc(RValue& other) : ptr_(other.release()) { } + scoped_ptr_malloc(RValue& other) + // The type of the underlying object is scoped_ptr_malloc; we have to + // reinterpret_cast back to the original type for the call to release to + // be valid. (See C++11 5.2.10.7) + : ptr_(reinterpret_cast<scoped_ptr_malloc&>(other).release()) { + } // Destructor. If there is a C object, call the Free functor. ~scoped_ptr_malloc() { |