Skip to content

Commit

Permalink
Forbid returning pointers and atomics from functions.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jimblandy committed May 26, 2022
1 parent 62da3bf commit 4eae569
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 3 deletions.
13 changes: 13 additions & 0 deletions src/valid/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ pub enum FunctionError {
},
#[error("Argument '{name}' at index {index} has a type that can't be passed into functions.")]
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.")]
InvalidArgumentPointerSpace {
index: usize,
Expand Down Expand Up @@ -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_list.clear();
for (handle, expr) in fun.expressions.iter() {
Expand Down
19 changes: 16 additions & 3 deletions src/valid/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ bitflags::bitflags! {

/// This type can be passed as a function argument.
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;
}
}

Expand Down Expand Up @@ -237,6 +246,7 @@ impl super::Validator {
| TypeFlags::SIZED
| TypeFlags::COPY
| TypeFlags::ARGUMENT
| TypeFlags::CONSTRUCTIBLE
| shareable,
width as u32,
)
Expand All @@ -257,6 +267,7 @@ impl super::Validator {
| TypeFlags::COPY
| TypeFlags::HOST_SHAREABLE
| TypeFlags::ARGUMENT
| TypeFlags::CONSTRUCTIBLE
| shareable,
count * (width as u32),
)
Expand All @@ -275,7 +286,8 @@ impl super::Validator {
| TypeFlags::SIZED
| TypeFlags::COPY
| TypeFlags::HOST_SHAREABLE
| TypeFlags::ARGUMENT,
| TypeFlags::ARGUMENT
| TypeFlags::CONSTRUCTIBLE,
count * (width as u32),
)
}
Expand Down Expand Up @@ -467,7 +479,7 @@ impl super::Validator {
return Err(TypeError::NonPositiveArrayLength(const_handle));
}

TypeFlags::SIZED | TypeFlags::ARGUMENT
TypeFlags::SIZED | TypeFlags::ARGUMENT | TypeFlags::CONSTRUCTIBLE
}
crate::ArraySize::Dynamic => {
// Non-SIZED types may only appear as the last element of a structure.
Expand Down Expand Up @@ -495,7 +507,8 @@ impl super::Validator {
| TypeFlags::COPY
| TypeFlags::HOST_SHAREABLE
| TypeFlags::IO_SHAREABLE
| TypeFlags::ARGUMENT,
| TypeFlags::ARGUMENT
| TypeFlags::CONSTRUCTIBLE,
1,
);
ti.uniform_layout = Ok(Some(UNIFORM_MIN_ALIGNMENT));
Expand Down
37 changes: 37 additions & 0 deletions tests/wgsl-errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,43 @@ fn invalid_functions() {
})
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]
Expand Down

0 comments on commit 4eae569

Please sign in to comment.