tint: Add 'chromium_experimental_full_ptr_parameters' extension
Removes validation around pointer parameters.
Bug: tint:1758
Change-Id: I3adc48f780fc8c6f5525f9ecc280e2a406069b49
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112286
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/ast/extension.cc b/src/tint/ast/extension.cc
index be16806..31a8083 100644
--- a/src/tint/ast/extension.cc
+++ b/src/tint/ast/extension.cc
@@ -34,6 +34,9 @@
if (str == "chromium_experimental_dp4a") {
return Extension::kChromiumExperimentalDp4A;
}
+ if (str == "chromium_experimental_full_ptr_parameters") {
+ return Extension::kChromiumExperimentalFullPtrParameters;
+ }
if (str == "chromium_experimental_push_constant") {
return Extension::kChromiumExperimentalPushConstant;
}
@@ -51,6 +54,8 @@
return out << "chromium_disable_uniformity_analysis";
case Extension::kChromiumExperimentalDp4A:
return out << "chromium_experimental_dp4a";
+ case Extension::kChromiumExperimentalFullPtrParameters:
+ return out << "chromium_experimental_full_ptr_parameters";
case Extension::kChromiumExperimentalPushConstant:
return out << "chromium_experimental_push_constant";
case Extension::kF16:
diff --git a/src/tint/ast/extension.h b/src/tint/ast/extension.h
index f6fa03f..062e3fc 100644
--- a/src/tint/ast/extension.h
+++ b/src/tint/ast/extension.h
@@ -35,6 +35,7 @@
kUndefined,
kChromiumDisableUniformityAnalysis,
kChromiumExperimentalDp4A,
+ kChromiumExperimentalFullPtrParameters,
kChromiumExperimentalPushConstant,
kF16,
};
@@ -52,6 +53,7 @@
constexpr const char* kExtensionStrings[] = {
"chromium_disable_uniformity_analysis",
"chromium_experimental_dp4a",
+ "chromium_experimental_full_ptr_parameters",
"chromium_experimental_push_constant",
"f16",
};
diff --git a/src/tint/ast/extension_bench.cc b/src/tint/ast/extension_bench.cc
index 94b5216..5f175cc 100644
--- a/src/tint/ast/extension_bench.cc
+++ b/src/tint/ast/extension_bench.cc
@@ -45,20 +45,27 @@
"chromium_exverimentiil_dp4a",
"chro8ium_experimenWWal_dp4a",
"chromiMm_eperimxxntal_dp4a",
- "chrXmium_experimeggtal_ush_constant",
- "chromiu_experVmentalpusX_constant",
- "chro3ium_experimental_push_constant",
+ "chromium_expeggimeXtal_full_ptr_paraeters",
+ "chromium_expVrimental_full_ptr_puraXeer",
+ "chromium_experimental_full_ptr3parameters",
+ "chromium_experimental_full_ptr_parameters",
+ "chromium_experimentalEfull_ptr_parameters",
+ "chromium_experimentalfull_ptr_PPaTTameters",
+ "chromium_ddxperimental_fullptrxxparameters",
+ "c44romium_experimental_push_constant",
+ "chromium_experimental_pSSsVV_constant",
+ "chrom22Rm_experimental_pushRonstant",
"chromium_experimental_push_constant",
- "chromium_experEmental_push_constant",
- "chPPomiumexperimental_push_conTTtant",
- "chromixxm_experimentddl_push_constnt",
- "4416",
- "fSVV6",
- "RR2",
+ "chromium_exp9rimFntal_ush_constant",
+ "chrmium_experimental_push_constant",
+ "cOOromium_experiVeHtal_puh_conRRtant",
+ "y1",
+ "l77rrn6",
+ "4016",
"f16",
- "96",
- "f1",
- "VOR6",
+ "5",
+ "u16",
+ "f",
};
for (auto _ : state) {
for (auto& str : kStrings) {
diff --git a/src/tint/ast/extension_test.cc b/src/tint/ast/extension_test.cc
index 2879bf8..ea08dcc 100644
--- a/src/tint/ast/extension_test.cc
+++ b/src/tint/ast/extension_test.cc
@@ -44,6 +44,8 @@
static constexpr Case kValidCases[] = {
{"chromium_disable_uniformity_analysis", Extension::kChromiumDisableUniformityAnalysis},
{"chromium_experimental_dp4a", Extension::kChromiumExperimentalDp4A},
+ {"chromium_experimental_full_ptr_parameters",
+ Extension::kChromiumExperimentalFullPtrParameters},
{"chromium_experimental_push_constant", Extension::kChromiumExperimentalPushConstant},
{"f16", Extension::kF16},
};
@@ -55,12 +57,15 @@
{"chro1ium_experimental_dp4a", Extension::kUndefined},
{"chrJmium_experiqqetal_dp4a", Extension::kUndefined},
{"chromium_experimenll77l_dp4a", Extension::kUndefined},
- {"cppromium_experiHHenal_qqush_constant", Extension::kUndefined},
- {"chromium_xpericental_sh_vonstant", Extension::kUndefined},
- {"chromium_experimental_Gsh_cbnstant", Extension::kUndefined},
- {"f1vi", Extension::kUndefined},
- {"f8WW", Extension::kUndefined},
- {"fxx", Extension::kUndefined},
+ {"chroium_experimental_full_ptr_paqqppmetHHrs", Extension::kUndefined},
+ {"chrium_evperiental_full_ptr_paraceters", Extension::kUndefined},
+ {"chromium_expGimental_fullbptr_parameters", Extension::kUndefined},
+ {"chvomium_experimental_push_constiint", Extension::kUndefined},
+ {"chromiu8WWexperimental_push_constant", Extension::kUndefined},
+ {"chromium_experiMental_push_costanxx", Extension::kUndefined},
+ {"fgg", Extension::kUndefined},
+ {"X", Extension::kUndefined},
+ {"316", Extension::kUndefined},
};
using ExtensionParseTest = testing::TestWithParam<Case>;
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index 6933e57..bcac5a2 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -51,6 +51,9 @@
chromium_disable_uniformity_analysis
// A Chromium-specific extension for push constants
chromium_experimental_push_constant
+ // A Chromium-specific extension that enables passing of uniform, storage and workgroup
+ // address-spaced pointers as parameters, as well as pointers into sub-objects.
+ chromium_experimental_full_ptr_parameters
}
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
diff --git a/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc b/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
index aad8eb6..392f0dd 100644
--- a/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
@@ -62,7 +62,7 @@
// Error when unknown extension found
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_push_constant', 'f16')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -75,7 +75,7 @@
// Error when unknown extension found
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension. Did you mean 'f16'?
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_push_constant', 'f16')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -123,7 +123,7 @@
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_push_constant', 'f16')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -134,7 +134,7 @@
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_push_constant', 'f16')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -145,7 +145,7 @@
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_push_constant', 'f16')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
diff --git a/src/tint/resolver/call_validation_test.cc b/src/tint/resolver/call_validation_test.cc
index 82037af..e94e7b8 100644
--- a/src/tint/resolver/call_validation_test.cc
+++ b/src/tint/resolver/call_validation_test.cc
@@ -114,11 +114,29 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(ResolverCallValidationTest, PointerArgument_NotWholeVar) {
+TEST_F(ResolverCallValidationTest, PointerArgument_LetIdentExpr) {
+ // fn foo(p: ptr<function, i32>) {}
+ // fn main() {
+ // let z: i32 = 1i;
+ // foo(&z);
+ // }
+ auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+ Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("z", ty.i32(), Expr(1_i))),
+ CallStmt(Call("foo", AddressOf(Expr(Source{{12, 34}}, "z")))),
+ });
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: cannot take the address of expression");
+}
+
+TEST_F(ResolverCallValidationTest, PointerArgument_AddressOfFunctionMember) {
// struct S { m: i32; };
// fn foo(p: ptr<function, i32>) {}
// fn main() {
- // var v: S;
+ // var v : S;
// foo(&v.m);
// }
auto* S = Structure("S", utils::Vector{
@@ -138,6 +156,51 @@
"originating variable");
}
+TEST_F(ResolverCallValidationTest,
+ PointerArgument_AddressOfFunctionMember_WithFullPtrParametersExt) {
+ // enable chromium_experimental_full_ptr_parameters;
+ // struct S { m: i32; };
+ // fn foo(p: ptr<function, i32>) {}
+ // fn main() {
+ // var v : S;
+ // foo(&v.m);
+ // }
+ Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
+ auto* S = Structure("S", utils::Vector{
+ Member("m", ty.i32()),
+ });
+ auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+ Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Var("v", ty.Of(S))),
+ CallStmt(Call("foo", AddressOf(Source{{12, 34}}, MemberAccessor("v", "m")))),
+ });
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+TEST_F(ResolverCallValidationTest, PointerArgument_AddressOfLetMember) {
+ // struct S { m: i32; };
+ // fn foo(p: ptr<function, i32>) {}
+ // fn main() {
+ // let v: S = S();
+ // foo(&v.m);
+ // }
+ auto* S = Structure("S", utils::Vector{
+ Member("m", ty.i32()),
+ });
+ auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+ Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("v", ty.Of(S), Construct(ty.Of(S)))),
+ CallStmt(Call("foo", AddressOf(MemberAccessor(Source{{12, 34}}, "v", "m")))),
+ });
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: cannot take the address of expression");
+}
+
TEST_F(ResolverCallValidationTest, PointerArgument_FunctionParam) {
// fn foo(p: ptr<function, i32>) {}
// fn bar(p: ptr<function, i32>) {
@@ -181,12 +244,12 @@
},
ty.void_(),
utils::Vector{
- CallStmt(Call("foo", Expr("p"))),
+ CallStmt(Call("foo", "p")),
});
Func("main", utils::Empty, ty.void_(),
utils::Vector{
Decl(Var("v", ty.i32(), Expr(1_i))),
- CallStmt(Call("foo", AddressOf(Expr("v")))),
+ CallStmt(Call("foo", AddressOf("v"))),
},
utils::Vector{
Stage(ast::PipelineStage::kFragment),
@@ -195,40 +258,15 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(ResolverCallValidationTest, PointerArgument_FunctionParam_NotWholeVar) {
- // fn foo(p: ptr<function, i32>) {}
- // fn bar(p: ptr<function, array<i32, 4>>) {
- // foo(&(*p)[0]);
- // }
- Func("foo",
- utils::Vector{
- Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
- },
- ty.void_(), utils::Empty);
- Func("bar",
- utils::Vector{
- Param("p", ty.pointer(ty.array<i32, 4>(), ast::AddressSpace::kFunction)),
- },
- ty.void_(),
- utils::Vector{
- CallStmt(Call("foo", AddressOf(Source{{12, 34}}, IndexAccessor(Deref("p"), 0_a)))),
- });
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: arguments of pointer type must not point to a subset of the "
- "originating variable");
-}
-
TEST_F(ResolverCallValidationTest, LetPointer) {
// fn foo(p : ptr<function, i32>) {}
// @fragment
// fn main() {
// var v: i32;
// let p: ptr<function, i32> = &v;
- // foo(p);
+ // x(p);
// }
- Func("foo",
+ Func("x",
utils::Vector{
Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
},
@@ -237,7 +275,7 @@
utils::Vector{
Decl(Var("v", ty.i32())),
Decl(Let("p", ty.pointer(ty.i32(), ast::AddressSpace::kFunction), AddressOf("v"))),
- CallStmt(Call("foo", Expr(Source{{12, 34}}, "p"))),
+ CallStmt(Call("x", "p")),
},
utils::Vector{
Stage(ast::PipelineStage::kFragment),
@@ -247,10 +285,10 @@
TEST_F(ResolverCallValidationTest, LetPointerPrivate) {
// fn foo(p : ptr<private, i32>) {}
- // var<private> v: i32;
+ // var v : i32;
// @fragment
// fn main() {
- // let p: ptr<private, i32> = &v;
+ // let p : ptr<private, i32> = &v;
// foo(p);
// }
Func("foo",
@@ -299,6 +337,34 @@
"originating variable");
}
+TEST_F(ResolverCallValidationTest, LetPointer_NotWholeVar_WithFullPtrParametersExt) {
+ // enable chromium_experimental_full_ptr_parameters;
+ // fn foo(p : ptr<function, i32>) {}
+ // @fragment
+ // fn main() {
+ // var v: array<i32, 4>;
+ // let p: ptr<function, i32> = &(v[0]);
+ // x(p);
+ // }
+ Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
+ Func("foo",
+ utils::Vector{
+ Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+ },
+ ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Var("v", ty.array<i32, 4>())),
+ Decl(Let("p", ty.pointer(ty.i32(), ast::AddressSpace::kFunction),
+ AddressOf(IndexAccessor("v", 0_a)))),
+ CallStmt(Call("foo", Expr(Source{{12, 34}}, "p"))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
+ EXPECT_TRUE(r()->Resolve());
+}
+
TEST_F(ResolverCallValidationTest, ComplexPointerChain) {
// fn foo(p : ptr<function, array<i32, 4>>) {}
// @fragment
@@ -360,6 +426,37 @@
"originating variable");
}
+TEST_F(ResolverCallValidationTest, ComplexPointerChain_NotWholeVar_WithFullPtrParametersExt) {
+ // enable chromium_experimental_full_ptr_parameters;
+ // fn foo(p : ptr<function, i32>) {}
+ // @fragment
+ // fn main() {
+ // var v: array<i32, 4>;
+ // let p1 = &v;
+ // let p2 = p1;
+ // let p3 = &(*p2)[0];
+ // foo(&*p);
+ // }
+ Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
+ Func("foo",
+ utils::Vector{
+ Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+ },
+ ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Var("v", ty.array<i32, 4>())),
+ Decl(Let("p1", AddressOf("v"))),
+ Decl(Let("p2", Expr("p1"))),
+ Decl(Let("p3", AddressOf(IndexAccessor(Deref("p2"), 0_a)))),
+ CallStmt(Call("foo", AddressOf(Source{{12, 34}}, Deref("p3")))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
+ EXPECT_TRUE(r()->Resolve());
+}
+
TEST_F(ResolverCallValidationTest, CallVariable) {
// var v : i32;
// fn f() {
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index 808f556..922a1dc 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -1041,21 +1041,26 @@
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
}
+enum class Expectation {
+ kAlwaysPass,
+ kPassWithFullPtrParameterExtension,
+ kAlwaysFail,
+};
struct TestParams {
ast::AddressSpace address_space;
- bool should_pass;
+ Expectation expectation;
};
struct TestWithParams : ResolverTestWithParam<TestParams> {};
using ResolverFunctionParameterValidationTest = TestWithParams;
-TEST_P(ResolverFunctionParameterValidationTest, AddressSpace) {
+TEST_P(ResolverFunctionParameterValidationTest, AddressSpaceNoExtension) {
auto& param = GetParam();
auto* ptr_type = ty.pointer(Source{{12, 34}}, ty.i32(), param.address_space);
auto* arg = Param(Source{{12, 34}}, "p", ptr_type);
Func("f", utils::Vector{arg}, ty.void_(), utils::Empty);
- if (param.should_pass) {
+ if (param.expectation == Expectation::kAlwaysPass) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
} else {
std::stringstream ss;
@@ -1065,17 +1070,36 @@
ss.str() + "' address space");
}
}
-INSTANTIATE_TEST_SUITE_P(ResolverTest,
- ResolverFunctionParameterValidationTest,
- testing::Values(TestParams{ast::AddressSpace::kNone, false},
- TestParams{ast::AddressSpace::kIn, false},
- TestParams{ast::AddressSpace::kOut, false},
- TestParams{ast::AddressSpace::kUniform, false},
- TestParams{ast::AddressSpace::kWorkgroup, false},
- TestParams{ast::AddressSpace::kHandle, false},
- TestParams{ast::AddressSpace::kStorage, false},
- TestParams{ast::AddressSpace::kPrivate, true},
- TestParams{ast::AddressSpace::kFunction, true}));
+TEST_P(ResolverFunctionParameterValidationTest, AddressSpaceWithExtension) {
+ auto& param = GetParam();
+ auto* ptr_type = ty.pointer(Source{{12, 34}}, ty.i32(), param.address_space);
+ auto* arg = Param(Source{{12, 34}}, "p", ptr_type);
+ Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
+ Func("f", utils::Vector{arg}, ty.void_(), utils::Empty);
+
+ if (param.expectation != Expectation::kAlwaysFail) {
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+ } else {
+ std::stringstream ss;
+ ss << param.address_space;
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: function parameter of pointer type cannot be in '" +
+ ss.str() + "' address space");
+ }
+}
+INSTANTIATE_TEST_SUITE_P(
+ ResolverTest,
+ ResolverFunctionParameterValidationTest,
+ testing::Values(
+ TestParams{ast::AddressSpace::kNone, Expectation::kAlwaysFail},
+ TestParams{ast::AddressSpace::kIn, Expectation::kAlwaysFail},
+ TestParams{ast::AddressSpace::kOut, Expectation::kAlwaysFail},
+ TestParams{ast::AddressSpace::kUniform, Expectation::kPassWithFullPtrParameterExtension},
+ TestParams{ast::AddressSpace::kWorkgroup, Expectation::kPassWithFullPtrParameterExtension},
+ TestParams{ast::AddressSpace::kHandle, Expectation::kAlwaysFail},
+ TestParams{ast::AddressSpace::kStorage, Expectation::kPassWithFullPtrParameterExtension},
+ TestParams{ast::AddressSpace::kPrivate, Expectation::kAlwaysPass},
+ TestParams{ast::AddressSpace::kFunction, Expectation::kAlwaysPass}));
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index 70e1de1..9c3c591 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -800,15 +800,31 @@
}
if (auto* ref = var->Type()->As<sem::Pointer>()) {
- auto address_space = ref->AddressSpace();
- if (!(address_space == ast::AddressSpace::kFunction ||
- address_space == ast::AddressSpace::kPrivate) &&
- IsValidationEnabled(decl->attributes, ast::DisabledValidation::kIgnoreAddressSpace)) {
- std::stringstream ss;
- ss << "function parameter of pointer type cannot be in '" << address_space
- << "' address space";
- AddError(ss.str(), decl->source);
- return false;
+ if (IsValidationEnabled(decl->attributes, ast::DisabledValidation::kIgnoreAddressSpace)) {
+ bool ok = false;
+
+ auto sc = ref->AddressSpace();
+ switch (sc) {
+ case ast::AddressSpace::kFunction:
+ case ast::AddressSpace::kPrivate:
+ ok = true;
+ break;
+ case ast::AddressSpace::kStorage:
+ case ast::AddressSpace::kUniform:
+ case ast::AddressSpace::kWorkgroup:
+ ok = enabled_extensions_.Contains(
+ ast::Extension::kChromiumExperimentalFullPtrParameters);
+ break;
+ default:
+ break;
+ }
+ if (!ok) {
+ std::stringstream ss;
+ ss << "function parameter of pointer type cannot be in '" << sc
+ << "' address space";
+ AddError(ss.str(), decl->source);
+ return false;
+ }
}
}
@@ -1654,7 +1670,8 @@
return false;
}
- if (param_type->Is<sem::Pointer>()) {
+ if (param_type->Is<sem::Pointer>() &&
+ !enabled_extensions_.Contains(ast::Extension::kChromiumExperimentalFullPtrParameters)) {
// https://gpuweb.github.io/gpuweb/wgsl/#function-restriction
// Each argument of pointer type to a user-defined function must have the same memory
// view as its root identifier.