From 59cd0e964bd8059acfec870b5c3ecf811b5a3825 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Fri, 24 May 2024 16:26:02 -0700 Subject: [PATCH] [naga] Validate `CallResult` and `AtomicResult` population. Validate that `CallResult` and `AtomicResult` expressions actually have their values provided by `Call` and `Atomic` statements, and not `Emit` statements. Fixes #5740. --- naga/src/valid/function.rs | 42 +++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/naga/src/valid/function.rs b/naga/src/valid/function.rs index 71128fc86d..543f71feda 100644 --- a/naga/src/valid/function.rs +++ b/naga/src/valid/function.rs @@ -172,6 +172,8 @@ pub enum FunctionError { WorkgroupUniformLoadInvalidPointer(Handle), #[error("Subgroup operation is invalid")] InvalidSubgroup(#[from] SubgroupError), + #[error("Emit statement should not cover \"result\" expressions like {0:?}")] + EmitResult(Handle), } bitflags::bitflags! { @@ -554,7 +556,45 @@ impl super::Validator { match *statement { S::Emit(ref range) => { for handle in range.clone() { - self.emit_expression(handle, context)?; + use crate::Expression as Ex; + match context.expressions[handle] { + Ex::Literal(_) + | Ex::Constant(_) + | Ex::Override(_) + | Ex::ZeroValue(_) + | Ex::Compose { .. } + | Ex::Access { .. } + | Ex::AccessIndex { .. } + | Ex::Splat { .. } + | Ex::Swizzle { .. } + | Ex::FunctionArgument(_) + | Ex::GlobalVariable(_) + | Ex::LocalVariable(_) + | Ex::Load { .. } + | Ex::ImageSample { .. } + | Ex::ImageLoad { .. } + | Ex::ImageQuery { .. } + | Ex::Unary { .. } + | Ex::Binary { .. } + | Ex::Select { .. } + | Ex::Derivative { .. } + | Ex::Relational { .. } + | Ex::Math { .. } + | Ex::As { .. } + | Ex::ArrayLength(_) + | Ex::RayQueryGetIntersection { .. } => { + self.emit_expression(handle, context)? + } + Ex::CallResult(_) + | Ex::AtomicResult { .. } + | Ex::WorkGroupUniformLoadResult { .. } + | Ex::RayQueryProceedResult + | Ex::SubgroupBallotResult + | Ex::SubgroupOperationResult { .. } => { + return Err(FunctionError::EmitResult(handle) + .with_span_handle(handle, context.expressions)); + } + } } } S::Block(ref block) => {