tint/transform: Handle arrays of complex override lengths

Update CreateASTTypeFor() to handle a potential edge-case described in tint:1764.

We haven't seen this issue happen in production, nor can I find a way to trigger this with the tint executable, but try to handle this before we encounter a nasty bug.

Fixed: tint:1764
Change-Id: I496932955a6fdcbe26eacef8dcd04988f92545a1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/111040
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton
2022-11-21 19:05:24 +00:00
committed by Dawn LUCI CQ
parent efe9c49819
commit 87bccb74d8
9 changed files with 230 additions and 0 deletions

View File

@@ -114,6 +114,19 @@ const ast::Type* Transform::CreateASTTypeFor(CloneContext& ctx, const sem::Type*
return ctx.dst->ty.array(el, count, std::move(attrs));
}
if (auto* override = std::get_if<sem::UnnamedOverrideArrayCount>(&a->Count())) {
// If the array count is an unnamed (complex) override expression, then its not safe to
// redeclare this type as we'd end up with two types that would not compare equal.
// See crbug.com/tint/1764.
// Look for a type alias for this array.
for (auto* type_decl : ctx.src->AST().TypeDecls()) {
if (auto* alias = type_decl->As<ast::Alias>()) {
if (ty == ctx.src->Sem().Get(alias)) {
// Alias found. Use the alias name to ensure types compare equal.
return ctx.dst->ty.type_name(ctx.Clone(alias->name));
}
}
}
// Array is not aliased. Rebuild the array.
auto* count = ctx.Clone(override->expr->Declaration());
return ctx.dst->ty.array(el, count, std::move(attrs));
}

View File

@@ -21,6 +21,8 @@
namespace tint::transform {
namespace {
using namespace tint::number_suffixes; // NOLINT
// Inherit from Transform so we have access to protected methods
struct CreateASTTypeForTest : public testing::Test, public Transform {
ApplyResult Apply(const Program*, const DataMap&, DataMap&) const override {
@@ -95,6 +97,28 @@ TEST_F(CreateASTTypeForTest, ArrayNonImplicitStride) {
EXPECT_EQ(size->value, 2);
}
// crbug.com/tint/1764
TEST_F(CreateASTTypeForTest, AliasedArrayWithComplexOverrideLength) {
// override O = 123;
// type A = array<i32, O*2>;
//
// var<workgroup> W : A;
//
ProgramBuilder b;
auto* arr_len = b.Mul("O", 2_a);
b.Override("O", b.Expr(123_a));
auto* alias = b.Alias("A", b.ty.array(b.ty.i32(), arr_len));
Program program(std::move(b));
auto* arr_ty = program.Sem().Get(alias);
CloneContext ctx(&ast_type_builder, &program, false);
auto* ast_ty = tint::As<ast::TypeName>(CreateASTTypeFor(ctx, arr_ty));
ASSERT_NE(ast_ty, nullptr);
EXPECT_EQ(ast_type_builder.Symbols().NameFor(ast_ty->name), "A");
}
TEST_F(CreateASTTypeForTest, Struct) {
auto* str = create([](ProgramBuilder& b) {
auto* decl = b.Structure("S", {});