Commit f8072dbd authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[handles] Use is_convertible instead of is_base_of

std::is_base_of<A, B> has undefined behaviour if B is not a complete
type. Hence, avoid it and use is_convertible<B*, A*> instead.
This captures exactly the requirement that
  Handle<A> foo() { return produce<Handle<B>>(); }
is valid exactly if
  A* foo() { return produce<B>(); }
is valid.
Also, change some static asserts to enable_ifs in order to allow
overloading a function by different Handle types, which would cause
disambiguity otherwise.

R=tebbi@chromium.org

Change-Id: I60fbdfcfd96c7b216e42819a5b5de3423a2c38d0
Reviewed-on: https://chromium-review.googlesource.com/774841Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49440}
parent 3e0bf580
......@@ -23,7 +23,6 @@ class HandleScopeImplementer;
class Isolate;
class Object;
// ----------------------------------------------------------------------------
// Base class for Handle instantiations. Don't use directly.
class HandleBase {
......@@ -94,7 +93,8 @@ class Handle final : public HandleBase {
V8_INLINE explicit Handle(T** location = nullptr)
: HandleBase(reinterpret_cast<Object**>(location)) {
// Type check:
static_assert(std::is_base_of<Object, T>::value, "static type violation");
static_assert(std::is_convertible<T*, Object*>::value,
"static type violation");
}
V8_INLINE explicit Handle(T* object);
......@@ -105,11 +105,9 @@ class Handle final : public HandleBase {
// Constructor for handling automatic up casting.
// Ex. Handle<JSFunction> can be passed when Handle<Object> is expected.
template <typename S>
V8_INLINE Handle(Handle<S> handle) : HandleBase(handle) {
// Type check:
static_assert(std::is_base_of<T, S>::value, "static type violation");
}
template <typename S, typename = typename std::enable_if<
std::is_convertible<S*, T*>::value>::type>
V8_INLINE Handle(Handle<S> handle) : HandleBase(handle) {}
V8_INLINE T* operator->() const { return operator*(); }
......@@ -187,24 +185,19 @@ class MaybeHandle final {
// Constructor for handling automatic up casting from Handle.
// Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected.
template <typename S>
template <typename S, typename = typename std::enable_if<
std::is_convertible<S*, T*>::value>::type>
V8_INLINE MaybeHandle(Handle<S> handle)
: location_(reinterpret_cast<T**>(handle.location_)) {
// Type check:
static_assert(std::is_base_of<T, S>::value, "static type violation");
}
: location_(reinterpret_cast<T**>(handle.location_)) {}
// Constructor for handling automatic up casting.
// Ex. MaybeHandle<JSArray> can be passed when Handle<Object> is expected.
template <typename S>
template <typename S, typename = typename std::enable_if<
std::is_convertible<S*, T*>::value>::type>
V8_INLINE MaybeHandle(MaybeHandle<S> maybe_handle)
: location_(reinterpret_cast<T**>(maybe_handle.location_)) {
// Type check:
static_assert(std::is_base_of<T, S>::value, "static type violation");
}
: location_(reinterpret_cast<T**>(maybe_handle.location_)) {}
template <typename S>
V8_INLINE MaybeHandle(S* object, Isolate* isolate)
V8_INLINE MaybeHandle(T* object, Isolate* isolate)
: MaybeHandle(handle(object, isolate)) {}
V8_INLINE void Assert() const { DCHECK_NOT_NULL(location_); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment