Forbid unsized structs as final members of structs. (#1443)

WGSL says:

> - The last member of the structure type defining the store type for a variable
>   ... may be a runtime-sized array.
>
> - A runtime-sized array must not be used as the store type or contained within
>   a store type in any other cases.

Thus, a struct whose final member is a struct whose final member is a
runtime-sized array is verboten.
This commit is contained in:
Jim Blandy 2021-10-01 06:40:18 -07:00 committed by GitHub
parent 4ea2d96cfb
commit ea50486b2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 2 deletions

View File

@ -473,9 +473,13 @@ impl super::Validator {
handle,
);
// only the last field can be unsized
// The last field may be an unsized array.
if !base_info.flags.contains(TypeFlags::SIZED) {
if i + 1 != members.len() {
let is_array = match types[member.ty].inner {
crate::TypeInner::Array { .. } => true,
_ => false,
};
if !is_array || i + 1 != members.len() {
let name = member.name.clone().unwrap_or_default();
return Err(TypeError::InvalidDynamicArray(name, member.ty));
}

View File

@ -913,3 +913,35 @@ fn dead_code() {
})
}
}
#[test]
fn invalid_runtime_sized_arrays() {
// You can't have structs whose last member is an unsized struct. An unsized
// array may only appear as the last member of a struct used directly as a
// variable's store type.
check_validation_error! {
"
struct Unsized {
arr: array<f32>;
};
[[block]]
struct Outer {
legit: i32;
unsized: Unsized;
};
[[group(0), binding(0)]] var<storage> outer: Outer;
fn fetch(i: i32) -> f32 {
return outer.unsized.arr[i];
}
":
Err(naga::valid::ValidationError::Type {
name: struct_name,
error: naga::valid::TypeError::InvalidDynamicArray(member_name, _),
..
})
if struct_name == "Outer" && member_name == "unsized"
}
}