summaryrefslogtreecommitdiffstats
path: root/base/memory
diff options
context:
space:
mode:
authordmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-20 05:47:14 +0000
committerdmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-20 05:47:14 +0000
commit1e4770f91c357e5499dff7f1dbf557c2f4b7790a (patch)
tree7d717a91d86313e2c7f23d43505f9b372fa41eab /base/memory
parentd54cf816835b99455788b46070a88220bfb6ad86 (diff)
downloadchromium_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.h21
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() {