Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ Bottom level categories:
- `DisplayHandle` should now be passed to `InstanceDescriptor` for correct EGL initialization on Wayland. By @MarijnS95 in [#8012](https://github.com/gfx-rs/wgpu/pull/8012)
Note that the existing workaround to create surfaces before the adapter is no longer valid.

#### naga

- Reject zero-value construction of a runtime-sized array with a validation error. Previously it would crash in the HLSL backend. By @mooori in [#8741](https://github.com/gfx-rs/wgpu/pull/8741).

### Documentation

#### General
Expand Down
11 changes: 10 additions & 1 deletion naga/src/valid/expression.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use super::{compose::validate_compose, FunctionInfo, ModuleInfo, ShaderStages, TypeFlags};
use crate::arena::UniqueArena;
use crate::valid::expression::builtin::validate_zero_value;
use crate::{
arena::Handle,
proc::OverloadSet as _,
proc::{IndexableLengthError, ResolveError},
};

pub mod builtin;

#[derive(Clone, Debug, thiserror::Error)]
#[cfg_attr(test, derive(PartialEq))]
pub enum ExpressionError {
Expand Down Expand Up @@ -36,6 +39,8 @@ pub enum ExpressionError {
#[error(transparent)]
Compose(#[from] super::ComposeError),
#[error(transparent)]
ZeroValue(#[from] super::ZeroValueError),
#[error(transparent)]
IndexableLength(#[from] IndexableLengthError),
#[error("Operation {0:?} can't work with {1:?}")]
InvalidUnaryOperandType(crate::UnaryOperator, Handle<crate::Expression>),
Expand Down Expand Up @@ -377,7 +382,11 @@ impl super::Validator {
self.validate_literal(literal)?;
ShaderStages::all()
}
E::Constant(_) | E::Override(_) | E::ZeroValue(_) => ShaderStages::all(),
E::Constant(_) | E::Override(_) => ShaderStages::all(),
E::ZeroValue(ty) => {
validate_zero_value(ty, module.to_ctx())?;
ShaderStages::all()
}
E::Compose { ref components, ty } => {
validate_compose(
ty,
Expand Down
26 changes: 26 additions & 0 deletions naga/src/valid/expression/builtin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use crate::arena::Handle;

#[derive(Clone, Debug, thiserror::Error)]
#[cfg_attr(test, derive(PartialEq))]
pub enum ZeroValueError {
#[error("ZeroValue construction of runtime-sized array is not allowed")]
RuntimeSizedArray,
}

pub fn validate_zero_value(
self_ty_handle: Handle<crate::Type>,
gctx: crate::proc::GlobalCtx,
) -> Result<(), ZeroValueError> {
use crate::TypeInner as Ti;
match gctx.types[self_ty_handle].inner {
Ti::Array {
base: _,
size: crate::ArraySize::Dynamic,
stride: _,
} => {
log::error!("Constructing zero value of runtime-sized array");
Err(ZeroValueError::RuntimeSizedArray)
}
_ => Ok(()),
}
}
1 change: 1 addition & 0 deletions naga/src/valid/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use crate::{
use crate::span::{AddSpan as _, WithSpan};
pub use analyzer::{ExpressionInfo, FunctionInfo, GlobalUse, Uniformity, UniformityRequirements};
pub use compose::ComposeError;
pub use expression::builtin::ZeroValueError;
pub use expression::{check_literal_value, LiteralError};
pub use expression::{ConstExpressionError, ExpressionError};
pub use function::{CallError, FunctionError, LocalVariableError, SubgroupError};
Expand Down
29 changes: 29 additions & 0 deletions naga/tests/naga/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,35 @@ fn bad_texture_dimensions_level() {
assert!(validate("1").is_ok());
}

#[test]
fn zero_value_dyn_array_error() {
let source = r#"
@compute @workgroup_size(1)
fn main() {
let a = array<f32>();
}
"#;
let module = naga::front::wgsl::parse_str(source).expect("module should parse");
let err = valid::Validator::new(Default::default(), valid::Capabilities::all())
.validate(&module)
.map_err(|err| err.into_inner()); // discard spans
assert!(matches!(
err,
Err(naga::valid::ValidationError::EntryPoint {
stage: _,
name: _,
source: naga::valid::EntryPointError::Function(
naga::valid::FunctionError::Expression {
handle: _,
source: naga::valid::ExpressionError::ZeroValue(
naga::valid::ZeroValueError::RuntimeSizedArray
)
}
)
})
));
}

#[test]
fn arity_check() {
use ir::MathFunction as Mf;
Expand Down
Loading