validation: type of a let must be constructible
This forbids let declarations from having handle types. Change-Id: I6f7467b0fa3963711ec705e1a81bfdd2c550feee Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/59801 Auto-Submit: James Price <jrprice@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
9a7ca38a86
commit
d12379a405
|
@ -1070,6 +1070,14 @@ bool Resolver::ValidateVariable(const VariableInfo* info) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (var->is_const() && info->kind != VariableKind::kParameter &&
|
||||||
|
!(storage_type->IsConstructible() || storage_type->Is<sem::Pointer>())) {
|
||||||
|
AddError(storage_type->FriendlyName(builder_->Symbols()) +
|
||||||
|
" cannot be used as the type of a let",
|
||||||
|
var->source());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto* r = storage_type->As<sem::Array>()) {
|
if (auto* r = storage_type->As<sem::Array>()) {
|
||||||
if (r->IsRuntimeSized()) {
|
if (r->IsRuntimeSized()) {
|
||||||
AddError("runtime arrays may only appear as the last member of a struct",
|
AddError("runtime arrays may only appear as the last member of a struct",
|
||||||
|
|
|
@ -78,6 +78,20 @@ TEST_F(ResolverVarLetValidationTest, VarTypeNotStorable) {
|
||||||
"type of a var");
|
"type of a var");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverVarLetValidationTest, LetTypeNotConstructible) {
|
||||||
|
// [[group(0), binding(0)]] var t1 : texture_2d<f32>;
|
||||||
|
// let t2 : t1;
|
||||||
|
auto* t1 =
|
||||||
|
Global("t1", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
|
||||||
|
GroupAndBinding(0, 0));
|
||||||
|
auto* t2 = Const(Source{{56, 78}}, "t2", nullptr, Expr(t1));
|
||||||
|
WrapInFunction(t2);
|
||||||
|
|
||||||
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
"56:78 error: texture_2d<f32> cannot be used as the type of a let");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ResolverVarLetValidationTest, LetConstructorWrongType) {
|
TEST_F(ResolverVarLetValidationTest, LetConstructorWrongType) {
|
||||||
// var v : i32 = 2u
|
// var v : i32 = 2u
|
||||||
WrapInFunction(Const(Source{{3, 3}}, "v", ty.i32(), Expr(2u)));
|
WrapInFunction(Const(Source{{3, 3}}, "v", ty.i32(), Expr(2u)));
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
[[group(0), binding(0)]] var t : texture_2d<f32>;
|
|
||||||
[[group(0), binding(1)]] var s : sampler;
|
|
||||||
|
|
||||||
[[stage(fragment)]]
|
|
||||||
fn main() {
|
|
||||||
let x = t;
|
|
||||||
let a = s;
|
|
||||||
ignore(1);
|
|
||||||
let y = x;
|
|
||||||
let b = a;
|
|
||||||
ignore(2);
|
|
||||||
let z = y;
|
|
||||||
let c = b;
|
|
||||||
ignore(textureSample(z, c, vec2<f32>(1., 2.)));
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
Texture2D<float4> t : register(t0, space0);
|
|
||||||
SamplerState s : register(s1, space0);
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
const Texture2D<float4> x = t;
|
|
||||||
const SamplerState a = s;
|
|
||||||
1;
|
|
||||||
const Texture2D<float4> y = x;
|
|
||||||
const SamplerState b = a;
|
|
||||||
2;
|
|
||||||
y.Sample(b, float2(1.0f, 2.0f));
|
|
||||||
return;
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
#include <metal_stdlib>
|
|
||||||
|
|
||||||
using namespace metal;
|
|
||||||
fragment void tint_symbol(texture2d<float, access::sample> tint_symbol_1 [[texture(0)]], sampler tint_symbol_2 [[sampler(1)]]) {
|
|
||||||
texture2d<float, access::sample> const x = tint_symbol_1;
|
|
||||||
sampler const a = tint_symbol_2;
|
|
||||||
(void) 1;
|
|
||||||
texture2d<float, access::sample> const y = x;
|
|
||||||
sampler const b = a;
|
|
||||||
(void) 2;
|
|
||||||
texture2d<float, access::sample> const z = y;
|
|
||||||
sampler const c = b;
|
|
||||||
(void) z.sample(c, float2(1.0f, 2.0f));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
; SPIR-V
|
|
||||||
; Version: 1.3
|
|
||||||
; Generator: Google Tint Compiler; 0
|
|
||||||
; Bound: 28
|
|
||||||
; Schema: 0
|
|
||||||
OpCapability Shader
|
|
||||||
OpMemoryModel Logical GLSL450
|
|
||||||
OpEntryPoint Fragment %main "main"
|
|
||||||
OpExecutionMode %main OriginUpperLeft
|
|
||||||
OpName %t "t"
|
|
||||||
OpName %s "s"
|
|
||||||
OpName %main "main"
|
|
||||||
OpDecorate %t DescriptorSet 0
|
|
||||||
OpDecorate %t Binding 0
|
|
||||||
OpDecorate %s DescriptorSet 0
|
|
||||||
OpDecorate %s Binding 1
|
|
||||||
%float = OpTypeFloat 32
|
|
||||||
%3 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
|
||||||
%_ptr_UniformConstant_3 = OpTypePointer UniformConstant %3
|
|
||||||
%t = OpVariable %_ptr_UniformConstant_3 UniformConstant
|
|
||||||
%7 = OpTypeSampler
|
|
||||||
%_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7
|
|
||||||
%s = OpVariable %_ptr_UniformConstant_7 UniformConstant
|
|
||||||
%void = OpTypeVoid
|
|
||||||
%8 = OpTypeFunction %void
|
|
||||||
%int = OpTypeInt 32 1
|
|
||||||
%int_1 = OpConstant %int 1
|
|
||||||
%int_2 = OpConstant %int 2
|
|
||||||
%v4float = OpTypeVector %float 4
|
|
||||||
%22 = OpTypeSampledImage %3
|
|
||||||
%v2float = OpTypeVector %float 2
|
|
||||||
%float_1 = OpConstant %float 1
|
|
||||||
%float_2 = OpConstant %float 2
|
|
||||||
%27 = OpConstantComposite %v2float %float_1 %float_2
|
|
||||||
%main = OpFunction %void None %8
|
|
||||||
%11 = OpLabel
|
|
||||||
%12 = OpLoad %3 %t
|
|
||||||
%13 = OpLoad %7 %s
|
|
||||||
%23 = OpSampledImage %22 %12 %13
|
|
||||||
%20 = OpImageSampleImplicitLod %v4float %23 %27
|
|
||||||
OpReturn
|
|
||||||
OpFunctionEnd
|
|
|
@ -1,16 +0,0 @@
|
||||||
[[group(0), binding(0)]] var t : texture_2d<f32>;
|
|
||||||
|
|
||||||
[[group(0), binding(1)]] var s : sampler;
|
|
||||||
|
|
||||||
[[stage(fragment)]]
|
|
||||||
fn main() {
|
|
||||||
let x = t;
|
|
||||||
let a = s;
|
|
||||||
ignore(1);
|
|
||||||
let y = x;
|
|
||||||
let b = a;
|
|
||||||
ignore(2);
|
|
||||||
let z = y;
|
|
||||||
let c = b;
|
|
||||||
ignore(textureSample(z, c, vec2<f32>(1.0, 2.0)));
|
|
||||||
}
|
|
Loading…
Reference in New Issue