Commit 143e6a74 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

cppgc: Check for correct base class inheritance

The only valid way to define a GCed type T is by inheriting from
GarbageCollected<T>. Since this is prone to typos (see tests), add a
simple check that covers most interesting use cases.

The static assert covers
  A -> B -> GarbageCollected<C>

The static assert does not cover
 A -> B -> C -> GarbageCollected<B>

(In order to do so, we would need __direct_bases() support which is
not yet available for C++.)

Bug: pdfium:1670, chromium:1056170
Change-Id: I494de48992f8ba9a1f0f9daad60584d828717403
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2810415Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73854}
parent cb4faa90
......@@ -8,6 +8,7 @@
#include <stdint.h>
#include <atomic>
#include <type_traits>
#include "cppgc/custom-space.h"
#include "cppgc/garbage-collected.h"
......@@ -103,6 +104,10 @@ class MakeGarbageCollectedTraitBase
* \returns the memory to construct an object of type T on.
*/
V8_INLINE static void* Allocate(AllocationHandle& handle, size_t size) {
static_assert(
std::is_base_of<typename T::ParentMostGarbageCollectedType, T>::value,
"U of GarbageCollected<U> must be a base of T. Check "
"GarbageCollected<T> base class inheritance.");
return SpacePolicy<
typename internal::GCInfoFolding<
T, typename T::ParentMostGarbageCollectedType>::ResultType,
......
......@@ -48,7 +48,7 @@ class Foo : public GarbageCollected<Foo> {
size_t Foo::destructor_callcount;
template <size_t Size>
class GCed : public GarbageCollected<Foo> {
class GCed : public GarbageCollected<GCed<Size>> {
public:
void Trace(cppgc::Visitor*) const {}
char buf[Size];
......
......@@ -23,7 +23,7 @@ struct OtherNoName : public GarbageCollected<OtherNoName> {
virtual void Trace(Visitor*) const {}
};
class ClassWithName final : public GarbageCollected<OtherNoName>,
class ClassWithName final : public GarbageCollected<ClassWithName>,
public NameProvider {
public:
explicit ClassWithName(const char* name) : name_(name) {}
......
......@@ -387,7 +387,7 @@ struct InlinedObject {
Member<GCed> ref;
};
class GCedWithInlinedArray : public GarbageCollected<GCed> {
class GCedWithInlinedArray : public GarbageCollected<GCedWithInlinedArray> {
public:
static constexpr size_t kNumReferences = 4;
......
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