[valid] Check that switches have a default case (#1529)

From the WGSL spec: "Each switch statement must have exactly one default clause."
This commit is contained in:
Boris-Chengbiao Zhou 2021-11-15 01:07:55 +01:00 committed by GitHub
parent 66c3499df8
commit 1dcde48d09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 0 deletions

View File

@ -106,6 +106,8 @@ pub enum FunctionError {
InvalidSwitchType(Handle<crate::Expression>),
#[error("Multiple `switch` cases for {0:?} are present")]
ConflictingSwitchCase(i32),
#[error("The `switch` is missing a `default` case")]
MissingDefaultCase,
#[error("Multiple `default` cases are present")]
MultipleDefaultCases,
#[error("The last `switch` case contains a `falltrough`")]
@ -471,6 +473,10 @@ impl super::Validator {
}
}
}
if !default {
return Err(FunctionError::MissingDefaultCase
.with_span_static(span, "missing default case"));
}
if let Some(case) = cases.last() {
if case.fall_through {
return Err(FunctionError::LastCaseFallTrough.with_span_static(

View File

@ -36,6 +36,8 @@ fn main([[builtin(global_invocation_id)]] global_id: vec3<u32>) {
switch(0u) {
case 0u: {
}
default: {
}
}
// non-empty switch in last-statement-in-function position
@ -71,6 +73,7 @@ fn switch_case_break() {
case 0: {
break;
}
default: {}
}
return;
}
@ -81,6 +84,7 @@ fn loop_switch_continue(x: i32) {
case 1: {
continue;
}
default: {}
}
}
}

View File

@ -17,6 +17,8 @@ void switch_case_break() {
switch(0) {
case 0:
break;
default:
break;
}
return;
}
@ -26,6 +28,8 @@ void loop_switch_continue(int x) {
switch(x) {
case 1:
continue;
default:
break;
}
}
return;
@ -61,6 +65,8 @@ void main() {
switch(0u) {
case 0u:
break;
default:
break;
}
int _e10 = pos;
switch(_e10) {

View File

@ -14,6 +14,9 @@ void switch_case_break()
case 0: {
break;
}
default: {
break;
}
}
return;
}
@ -25,6 +28,9 @@ void loop_switch_continue(int x)
case 1: {
continue;
}
default: {
break;
}
}
}
return;
@ -71,6 +77,9 @@ void main(uint3 global_id : SV_DispatchThreadID)
case 0u: {
break;
}
default: {
break;
}
}
int _expr10 = pos;
switch(_expr10) {

View File

@ -19,6 +19,9 @@ void switch_case_break(
case 0: {
break;
}
default: {
break;
}
}
return;
}
@ -31,6 +34,9 @@ void loop_switch_continue(
case 1: {
continue;
}
default: {
break;
}
}
}
return;
@ -75,6 +81,9 @@ kernel void main_(
case 0u: {
break;
}
default: {
break;
}
}
int _e10 = pos;
switch(_e10) {

View File

@ -11,6 +11,8 @@ fn switch_case_break() {
case 0: {
break;
}
default: {
}
}
return;
}
@ -21,6 +23,8 @@ fn loop_switch_continue(x: i32) {
case 1: {
continue;
}
default: {
}
}
}
return;
@ -59,6 +63,8 @@ fn main([[builtin(global_invocation_id)]] global_id: vec3<u32>) {
switch(0u) {
case 0u: {
}
default: {
}
}
let e10: i32 = pos;
switch(e10) {

View File

@ -995,6 +995,7 @@ fn last_case_falltrough() {
"
fn test_falltrough() {
switch(0) {
default: {}
case 0: {
fallthrough;
}
@ -1009,3 +1010,22 @@ fn last_case_falltrough() {
)
}
}
#[test]
fn missing_default_case() {
check_validation_error! {
"
fn test_missing_default_case() {
switch(0) {
case 0: {}
}
}
":
Err(
naga::valid::ValidationError::Function {
error: naga::valid::FunctionError::MissingDefaultCase,
..
},
)
}
}