Use class templates for Null objects
This allows partial-instantiating custom Null object for template Lookup<T>. Before, this had to be handcoded per instantiation. Apparently I missed adding one for AAT::ankr.lookupTable, so it was getting the wrong (generic) null for Lookup object, which is wrong and unsafe. Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=944346
This commit is contained in:
parent
1dfc2dfff5
commit
ea281aa8d0
|
@ -418,15 +418,11 @@ struct Lookup
|
||||||
} /* Close namespace. */
|
} /* Close namespace. */
|
||||||
/* Ugly hand-coded null objects for template Lookup<> :(. */
|
/* Ugly hand-coded null objects for template Lookup<> :(. */
|
||||||
extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2];
|
extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2];
|
||||||
template <>
|
template <typename T>
|
||||||
/*static*/ inline const AAT::Lookup<OT::HBUINT16>& Null<AAT::Lookup<OT::HBUINT16> > ()
|
struct Null<AAT::Lookup<T> > {
|
||||||
{ return *reinterpret_cast<const AAT::Lookup<OT::HBUINT16> *> (_hb_Null_AAT_Lookup); }
|
static AAT::Lookup<T> const & get_null ()
|
||||||
template <>
|
{ return *reinterpret_cast<const AAT::Lookup<T> *> (_hb_Null_AAT_Lookup); }
|
||||||
/*static*/ inline const AAT::Lookup<OT::HBUINT32>& Null<AAT::Lookup<OT::HBUINT32> > ()
|
};
|
||||||
{ return *reinterpret_cast<const AAT::Lookup<OT::HBUINT32> *> (_hb_Null_AAT_Lookup); }
|
|
||||||
template <>
|
|
||||||
/*static*/ inline const AAT::Lookup<OT::Offset<OT::HBUINT16, false> >& Null<AAT::Lookup<OT::Offset<OT::HBUINT16, false> > > ()
|
|
||||||
{ return *reinterpret_cast<const AAT::Lookup<OT::Offset<OT::HBUINT16, false> > *> (_hb_Null_AAT_Lookup); }
|
|
||||||
namespace AAT {
|
namespace AAT {
|
||||||
|
|
||||||
enum { DELETED_GLYPH = 0xFFFF };
|
enum { DELETED_GLYPH = 0xFFFF };
|
||||||
|
|
|
@ -105,15 +105,18 @@ hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_
|
||||||
|
|
||||||
/* Generic nul-content Null objects. */
|
/* Generic nul-content Null objects. */
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
static inline Type const & Null () {
|
struct Null {
|
||||||
|
static Type const & get_null ()
|
||||||
|
{
|
||||||
static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
|
static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
|
||||||
return *reinterpret_cast<Type const *> (_hb_NullPool);
|
return *reinterpret_cast<Type const *> (_hb_NullPool);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
template <typename QType>
|
template <typename QType>
|
||||||
struct NullHelper
|
struct NullHelper
|
||||||
{
|
{
|
||||||
typedef typename hb_remove_const (typename hb_remove_reference (QType)) Type;
|
typedef typename hb_remove_const (typename hb_remove_reference (QType)) Type;
|
||||||
static const Type & get_null () { return Null<Type> (); }
|
static const Type & get_null () { return Null<Type>::get_null (); }
|
||||||
};
|
};
|
||||||
#define Null(Type) NullHelper<Type>::get_null ()
|
#define Null(Type) NullHelper<Type>::get_null ()
|
||||||
|
|
||||||
|
@ -122,9 +125,11 @@ struct NullHelper
|
||||||
} /* Close namespace. */ \
|
} /* Close namespace. */ \
|
||||||
extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size]; \
|
extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size]; \
|
||||||
template <> \
|
template <> \
|
||||||
/*static*/ inline const Namespace::Type& Null<Namespace::Type> () { \
|
struct Null<Namespace::Type> { \
|
||||||
|
static Namespace::Type const & get_null () { \
|
||||||
return *reinterpret_cast<const Namespace::Type *> (_hb_Null_##Namespace##_##Type); \
|
return *reinterpret_cast<const Namespace::Type *> (_hb_Null_##Namespace##_##Type); \
|
||||||
} \
|
} \
|
||||||
|
}; \
|
||||||
namespace Namespace { \
|
namespace Namespace { \
|
||||||
static_assert (true, "Just so we take semicolon after.")
|
static_assert (true, "Just so we take semicolon after.")
|
||||||
#define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \
|
#define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \
|
||||||
|
@ -134,10 +139,12 @@ struct NullHelper
|
||||||
#define DECLARE_NULL_INSTANCE(Type) \
|
#define DECLARE_NULL_INSTANCE(Type) \
|
||||||
extern HB_INTERNAL const Type _hb_Null_##Type; \
|
extern HB_INTERNAL const Type _hb_Null_##Type; \
|
||||||
template <> \
|
template <> \
|
||||||
/*static*/ inline const Type& Null<Type> () { \
|
struct Null<Type> { \
|
||||||
|
static Type const & get_null () { \
|
||||||
return _hb_Null_##Type; \
|
return _hb_Null_##Type; \
|
||||||
} \
|
} \
|
||||||
static_assert (true, "Just so we take semicolon after.")
|
}; \
|
||||||
|
static_assert (true, "Just so we take semicolon after.")
|
||||||
#define DEFINE_NULL_INSTANCE(Type) \
|
#define DEFINE_NULL_INSTANCE(Type) \
|
||||||
const Type _hb_Null_##Type
|
const Type _hb_Null_##Type
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue