mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-15 03:41:34 +00:00
CloneContext: Assert objects are owned by the program
Check that pre-clone objects are owned by the source program. Check that post-clone object are owned by the target builder. Fixed: tint:469 Change-Id: Idd0eeb8dfb386e295b66b4b6621cc13dc1a30786 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48260 Commit-Queue: Ben Clayton <bclayton@chromium.org> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
b895ba1cea
commit
917b14b626
@ -81,7 +81,7 @@ class Node : public Castable<Node, Cloneable> {
|
|||||||
|
|
||||||
/// @param node a pointer to an AST node
|
/// @param node a pointer to an AST node
|
||||||
/// @returns the ProgramID of the given AST node.
|
/// @returns the ProgramID of the given AST node.
|
||||||
inline ProgramID ProgramIDOf(ast::Node* node) {
|
inline ProgramID ProgramIDOf(const ast::Node* node) {
|
||||||
return node ? node->program_id() : ProgramID();
|
return node ? node->program_id() : ProgramID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,11 +32,14 @@ namespace tint {
|
|||||||
class CloneContext;
|
class CloneContext;
|
||||||
class Program;
|
class Program;
|
||||||
class ProgramBuilder;
|
class ProgramBuilder;
|
||||||
|
|
||||||
namespace ast {
|
namespace ast {
|
||||||
class FunctionList;
|
class FunctionList;
|
||||||
|
class Node;
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|
||||||
|
ProgramID ProgramIDOf(const Program*);
|
||||||
|
ProgramID ProgramIDOf(const ast::Node*);
|
||||||
|
|
||||||
/// Cloneable is the base class for all objects that can be cloned
|
/// Cloneable is the base class for all objects that can be cloned
|
||||||
class Cloneable : public Castable<Cloneable> {
|
class Cloneable : public Castable<Cloneable> {
|
||||||
public:
|
public:
|
||||||
@ -46,6 +49,11 @@ class Cloneable : public Castable<Cloneable> {
|
|||||||
virtual Cloneable* Clone(CloneContext* ctx) const = 0;
|
virtual Cloneable* Clone(CloneContext* ctx) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @returns an invalid ProgramID
|
||||||
|
inline ProgramID ProgramIDOf(const Cloneable*) {
|
||||||
|
return ProgramID();
|
||||||
|
}
|
||||||
|
|
||||||
/// ShareableCloneable is the base class for Cloneable objects which will only
|
/// ShareableCloneable is the base class for Cloneable objects which will only
|
||||||
/// be cloned once when CloneContext::Clone() is called with the same object
|
/// be cloned once when CloneContext::Clone() is called with the same object
|
||||||
/// pointer.
|
/// pointer.
|
||||||
@ -95,6 +103,8 @@ class CloneContext {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(src, a);
|
||||||
|
|
||||||
// Have we cloned this object already, or was Replace() called for this
|
// Have we cloned this object already, or was Replace() called for this
|
||||||
// object?
|
// object?
|
||||||
auto it = cloned_.find(a);
|
auto it = cloned_.find(a);
|
||||||
@ -127,7 +137,11 @@ class CloneContext {
|
|||||||
cloned_.emplace(a, cloned);
|
cloned_.emplace(a, cloned);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CheckedCast<T>(cloned);
|
auto* out = CheckedCast<T>(cloned);
|
||||||
|
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(dst, out);
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clones the Node or type::Type `a` into the ProgramBuilder #dst if `a` is
|
/// Clones the Node or type::Type `a` into the ProgramBuilder #dst if `a` is
|
||||||
@ -149,6 +163,8 @@ class CloneContext {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(src, a);
|
||||||
|
|
||||||
// Have we seen this object before? If so, return the previously cloned
|
// Have we seen this object before? If so, return the previously cloned
|
||||||
// version instead of making yet another copy.
|
// version instead of making yet another copy.
|
||||||
auto it = cloned_.find(a);
|
auto it = cloned_.find(a);
|
||||||
|
@ -97,6 +97,23 @@ struct NotANode : public Castable<NotANode, Cloneable> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ProgramNode : public Castable<ProgramNode, Cloneable> {
|
||||||
|
ProgramNode(Allocator* alloc, ProgramID id, ProgramID cloned_id)
|
||||||
|
: allocator(alloc), program_id(id), cloned_program_id(cloned_id) {}
|
||||||
|
|
||||||
|
Allocator* const allocator;
|
||||||
|
ProgramID const program_id;
|
||||||
|
ProgramID const cloned_program_id;
|
||||||
|
|
||||||
|
ProgramNode* Clone(CloneContext*) const override {
|
||||||
|
return allocator->Create<ProgramNode>(cloned_program_id, cloned_program_id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ProgramID ProgramIDOf(const ProgramNode* node) {
|
||||||
|
return node->program_id;
|
||||||
|
}
|
||||||
|
|
||||||
struct UniqueTypes {
|
struct UniqueTypes {
|
||||||
using Node = UniqueNode;
|
using Node = UniqueNode;
|
||||||
using Replaceable = UniqueReplaceable;
|
using Replaceable = UniqueReplaceable;
|
||||||
@ -642,6 +659,38 @@ TYPED_TEST(CloneContextTest, CloneNewSymbols_AfterCloneSymbols) {
|
|||||||
EXPECT_EQ(cloned.Symbols().NameFor(new_c), "c");
|
EXPECT_EQ(cloned.Symbols().NameFor(new_c), "c");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(CloneContextTest, ProgramIDs) {
|
||||||
|
ProgramBuilder dst;
|
||||||
|
Program src(ProgramBuilder{});
|
||||||
|
CloneContext ctx(&dst, &src);
|
||||||
|
Allocator allocator;
|
||||||
|
ctx.Clone(allocator.Create<ProgramNode>(src.ID(), dst.ID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(CloneContextTest, ProgramIDs_ObjectNotOwnedBySrc) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder dst;
|
||||||
|
Program src(ProgramBuilder{});
|
||||||
|
CloneContext ctx(&dst, &src);
|
||||||
|
Allocator allocator;
|
||||||
|
ctx.Clone(allocator.Create<ProgramNode>(ProgramID::New(), dst.ID()));
|
||||||
|
},
|
||||||
|
R"(internal compiler error: TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(src, a))");
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(CloneContextTest, ProgramIDs_ObjectNotOwnedByDst) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder dst;
|
||||||
|
Program src(ProgramBuilder{});
|
||||||
|
CloneContext ctx(&dst, &src);
|
||||||
|
Allocator allocator;
|
||||||
|
ctx.Clone(allocator.Create<ProgramNode>(src.ID(), ProgramID::New()));
|
||||||
|
},
|
||||||
|
R"(internal compiler error: TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(dst, out))");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(UniqueNode);
|
TINT_INSTANTIATE_TYPEINFO(UniqueNode);
|
||||||
@ -651,5 +700,6 @@ TINT_INSTANTIATE_TYPEINFO(ShareableNode);
|
|||||||
TINT_INSTANTIATE_TYPEINFO(ShareableReplaceable);
|
TINT_INSTANTIATE_TYPEINFO(ShareableReplaceable);
|
||||||
TINT_INSTANTIATE_TYPEINFO(ShareableReplacement);
|
TINT_INSTANTIATE_TYPEINFO(ShareableReplacement);
|
||||||
TINT_INSTANTIATE_TYPEINFO(NotANode);
|
TINT_INSTANTIATE_TYPEINFO(NotANode);
|
||||||
|
TINT_INSTANTIATE_TYPEINFO(ProgramNode);
|
||||||
|
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
@ -171,6 +171,12 @@ class Program {
|
|||||||
bool moved_ = false;
|
bool moved_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @param program the Program
|
||||||
|
/// @returns the ProgramID of the Program
|
||||||
|
inline ProgramID ProgramIDOf(const Program* program) {
|
||||||
|
return program->ID();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_PROGRAM_H_
|
#endif // SRC_PROGRAM_H_
|
||||||
|
@ -1505,6 +1505,12 @@ struct ProgramBuilder::TypesBuilder::CToAST<void> {
|
|||||||
};
|
};
|
||||||
//! @endcond
|
//! @endcond
|
||||||
|
|
||||||
|
/// @param builder the ProgramBuilder
|
||||||
|
/// @returns the ProgramID of the ProgramBuilder
|
||||||
|
inline ProgramID ProgramIDOf(const ProgramBuilder* builder) {
|
||||||
|
return builder->ID();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_PROGRAM_BUILDER_H_
|
#endif // SRC_PROGRAM_BUILDER_H_
|
||||||
|
@ -102,6 +102,13 @@ class Type : public Castable<Type, ShareableCloneable> {
|
|||||||
Type();
|
Type();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @returns the ProgramID of the given type.
|
||||||
|
inline ProgramID ProgramIDOf(const Type*) {
|
||||||
|
/// TODO(crbug.com/tint/724): Actually implement this once we split the `type`
|
||||||
|
/// namespace into ast::Type and sem::Type.
|
||||||
|
return ProgramID();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace type
|
} // namespace type
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user