mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Forbid returning pointers and atomics from functions.
Introduce a new `TypeFlags::CONSTRUCTIBLE` flag, corresponding to WGSL's "constructible types". Set this on the appropriate types. Check for this flag on function return types.
This commit is contained in:
@@ -86,6 +86,8 @@ pub enum FunctionError {
|
|||||||
},
|
},
|
||||||
#[error("Argument '{name}' at index {index} has a type that can't be passed into functions.")]
|
#[error("Argument '{name}' at index {index} has a type that can't be passed into functions.")]
|
||||||
InvalidArgumentType { index: usize, name: String },
|
InvalidArgumentType { index: usize, name: String },
|
||||||
|
#[error("The function's given return type cannot be returned from functions")]
|
||||||
|
NonConstructibleReturnType,
|
||||||
#[error("Argument '{name}' at index {index} is a pointer of space {space:?}, which can't be passed into functions.")]
|
#[error("Argument '{name}' at index {index} is a pointer of space {space:?}, which can't be passed into functions.")]
|
||||||
InvalidArgumentPointerSpace {
|
InvalidArgumentPointerSpace {
|
||||||
index: usize,
|
index: usize,
|
||||||
@@ -894,6 +896,17 @@ impl super::Validator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "validate")]
|
||||||
|
if let Some(ref result) = fun.result {
|
||||||
|
if !self.types[result.ty.index()]
|
||||||
|
.flags
|
||||||
|
.contains(super::TypeFlags::CONSTRUCTIBLE)
|
||||||
|
{
|
||||||
|
return Err(FunctionError::NonConstructibleReturnType
|
||||||
|
.with_span_handle(result.ty, &module.types));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.valid_expression_set.clear();
|
self.valid_expression_set.clear();
|
||||||
self.valid_expression_list.clear();
|
self.valid_expression_list.clear();
|
||||||
for (handle, expr) in fun.expressions.iter() {
|
for (handle, expr) in fun.expressions.iter() {
|
||||||
|
|||||||
@@ -52,6 +52,15 @@ bitflags::bitflags! {
|
|||||||
|
|
||||||
/// This type can be passed as a function argument.
|
/// This type can be passed as a function argument.
|
||||||
const ARGUMENT = 0x40;
|
const ARGUMENT = 0x40;
|
||||||
|
|
||||||
|
/// A WGSL [constructible] type.
|
||||||
|
///
|
||||||
|
/// The constructible types are scalars, vectors, matrices, fixed-size
|
||||||
|
/// arrays of constructible types, and structs whose members are all
|
||||||
|
/// constructible.
|
||||||
|
///
|
||||||
|
/// [constructible]: https://gpuweb.github.io/gpuweb/wgsl/#constructible
|
||||||
|
const CONSTRUCTIBLE = 0x80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,6 +246,7 @@ impl super::Validator {
|
|||||||
| TypeFlags::SIZED
|
| TypeFlags::SIZED
|
||||||
| TypeFlags::COPY
|
| TypeFlags::COPY
|
||||||
| TypeFlags::ARGUMENT
|
| TypeFlags::ARGUMENT
|
||||||
|
| TypeFlags::CONSTRUCTIBLE
|
||||||
| shareable,
|
| shareable,
|
||||||
width as u32,
|
width as u32,
|
||||||
)
|
)
|
||||||
@@ -257,6 +267,7 @@ impl super::Validator {
|
|||||||
| TypeFlags::COPY
|
| TypeFlags::COPY
|
||||||
| TypeFlags::HOST_SHAREABLE
|
| TypeFlags::HOST_SHAREABLE
|
||||||
| TypeFlags::ARGUMENT
|
| TypeFlags::ARGUMENT
|
||||||
|
| TypeFlags::CONSTRUCTIBLE
|
||||||
| shareable,
|
| shareable,
|
||||||
count * (width as u32),
|
count * (width as u32),
|
||||||
)
|
)
|
||||||
@@ -275,7 +286,8 @@ impl super::Validator {
|
|||||||
| TypeFlags::SIZED
|
| TypeFlags::SIZED
|
||||||
| TypeFlags::COPY
|
| TypeFlags::COPY
|
||||||
| TypeFlags::HOST_SHAREABLE
|
| TypeFlags::HOST_SHAREABLE
|
||||||
| TypeFlags::ARGUMENT,
|
| TypeFlags::ARGUMENT
|
||||||
|
| TypeFlags::CONSTRUCTIBLE,
|
||||||
count * (width as u32),
|
count * (width as u32),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -467,7 +479,7 @@ impl super::Validator {
|
|||||||
return Err(TypeError::NonPositiveArrayLength(const_handle));
|
return Err(TypeError::NonPositiveArrayLength(const_handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeFlags::SIZED | TypeFlags::ARGUMENT
|
TypeFlags::SIZED | TypeFlags::ARGUMENT | TypeFlags::CONSTRUCTIBLE
|
||||||
}
|
}
|
||||||
crate::ArraySize::Dynamic => {
|
crate::ArraySize::Dynamic => {
|
||||||
// Non-SIZED types may only appear as the last element of a structure.
|
// Non-SIZED types may only appear as the last element of a structure.
|
||||||
@@ -495,7 +507,8 @@ impl super::Validator {
|
|||||||
| TypeFlags::COPY
|
| TypeFlags::COPY
|
||||||
| TypeFlags::HOST_SHAREABLE
|
| TypeFlags::HOST_SHAREABLE
|
||||||
| TypeFlags::IO_SHAREABLE
|
| TypeFlags::IO_SHAREABLE
|
||||||
| TypeFlags::ARGUMENT,
|
| TypeFlags::ARGUMENT
|
||||||
|
| TypeFlags::CONSTRUCTIBLE,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
ti.uniform_layout = Ok(Some(UNIFORM_MIN_ALIGNMENT));
|
ti.uniform_layout = Ok(Some(UNIFORM_MIN_ALIGNMENT));
|
||||||
|
|||||||
@@ -1029,6 +1029,43 @@ fn invalid_functions() {
|
|||||||
})
|
})
|
||||||
if function_name == "unacceptable_ptr_space" && argument_name == "arg"
|
if function_name == "unacceptable_ptr_space" && argument_name == "arg"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_validation! {
|
||||||
|
"
|
||||||
|
struct AFloat {
|
||||||
|
said_float: f32
|
||||||
|
};
|
||||||
|
@group(0) @binding(0)
|
||||||
|
var<storage> float: AFloat;
|
||||||
|
|
||||||
|
fn return_pointer() -> ptr<storage, f32> {
|
||||||
|
return &float.said_float;
|
||||||
|
}
|
||||||
|
":
|
||||||
|
Err(naga::valid::ValidationError::Function {
|
||||||
|
name: function_name,
|
||||||
|
error: naga::valid::FunctionError::NonConstructibleReturnType,
|
||||||
|
..
|
||||||
|
})
|
||||||
|
if function_name == "return_pointer"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_validation! {
|
||||||
|
"
|
||||||
|
@group(0) @binding(0)
|
||||||
|
var<storage> atom: atomic<u32>;
|
||||||
|
|
||||||
|
fn return_atomic() -> atomic<u32> {
|
||||||
|
return atom;
|
||||||
|
}
|
||||||
|
":
|
||||||
|
Err(naga::valid::ValidationError::Function {
|
||||||
|
name: function_name,
|
||||||
|
error: naga::valid::FunctionError::NonConstructibleReturnType,
|
||||||
|
..
|
||||||
|
})
|
||||||
|
if function_name == "return_atomic"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user