From ea50486b2dfce3e41411aa50e23646768d9558d0 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Fri, 1 Oct 2021 06:40:18 -0700 Subject: [PATCH] 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. --- src/valid/type.rs | 8 ++++++-- tests/wgsl-errors.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/valid/type.rs b/src/valid/type.rs index 540818ca23..a180831dff 100644 --- a/src/valid/type.rs +++ b/src/valid/type.rs @@ -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)); } diff --git a/tests/wgsl-errors.rs b/tests/wgsl-errors.rs index 8ccfdfa0ed..9f4f0711b0 100644 --- a/tests/wgsl-errors.rs +++ b/tests/wgsl-errors.rs @@ -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; + }; + + [[block]] + struct Outer { + legit: i32; + unsized: Unsized; + }; + + [[group(0), binding(0)]] var 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" + } +}