Skip to content

Commit 0dfe371

Browse files
committed
[naga] Disallow logical operators && and || on vectors
Fixes #6856
1 parent da7deb4 commit 0dfe371

File tree

4 files changed

+65
-5
lines changed

4 files changed

+65
-5
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ By @wumpf in [#7144](https://github.com/gfx-rs/wgpu/pull/7144)
229229
- Allow WGSL const declarations to have abstract types. By @jamienicol in [#7055](https://github.com/gfx-rs/wgpu/pull/7055) and [#7222](https://github.com/gfx-rs/wgpu/pull/7222).
230230
- Allows override-sized arrays to resolve to the same size without causing the type arena to panic. By @KentSlaney in [#7082](https://github.com/gfx-rs/wgpu/pull/7082).
231231
- Allow abstract types to be used for WGSL switch statement selector and case selector expressions. By @jamienicol in [#7250](https://github.com/gfx-rs/wgpu/pull/7250).
232+
- The `&&` and `||` operators are no longer allowed on vectors. By @andyleiserson in [#7368](https://github.com/gfx-rs/wgpu/pull/7368).
232233
233234
#### General
234235

naga/src/proc/constant_evaluator.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -2102,10 +2102,13 @@ impl<'a> ConstantEvaluator<'a> {
21022102
| BinaryOperator::And
21032103
| BinaryOperator::ExclusiveOr
21042104
| BinaryOperator::InclusiveOr
2105-
| BinaryOperator::LogicalAnd
2106-
| BinaryOperator::LogicalOr
21072105
| BinaryOperator::ShiftLeft
21082106
| BinaryOperator::ShiftRight => left_ty,
2107+
2108+
BinaryOperator::LogicalAnd | BinaryOperator::LogicalOr => {
2109+
// Not supported on vectors
2110+
return Err(ConstantEvaluatorError::InvalidBinaryOpArgs);
2111+
}
21092112
};
21102113

21112114
let components = components

naga/src/proc/typifier.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,8 @@ impl<'a> ResolveContext<'a> {
583583
| crate::BinaryOperator::Less
584584
| crate::BinaryOperator::LessEqual
585585
| crate::BinaryOperator::Greater
586-
| crate::BinaryOperator::GreaterEqual
587-
| crate::BinaryOperator::LogicalAnd
588-
| crate::BinaryOperator::LogicalOr => {
586+
| crate::BinaryOperator::GreaterEqual => {
587+
// These accept scalars or vectors.
589588
let scalar = crate::Scalar::BOOL;
590589
let inner = match *past(left)?.inner_with(types) {
591590
Ti::Scalar { .. } => Ti::Scalar(scalar),
@@ -598,6 +597,18 @@ impl<'a> ResolveContext<'a> {
598597
};
599598
TypeResolution::Value(inner)
600599
}
600+
crate::BinaryOperator::LogicalAnd | crate::BinaryOperator::LogicalOr => {
601+
// These accept scalars only.
602+
let bool = Ti::Scalar(crate::Scalar::BOOL);
603+
let ty = past(left)?.inner_with(types);
604+
if *ty == bool {
605+
TypeResolution::Value(bool)
606+
} else {
607+
return Err(ResolveError::IncompatibleOperands(format!(
608+
"{op:?}({ty:?}, _)"
609+
)));
610+
}
611+
}
601612
crate::BinaryOperator::And
602613
| crate::BinaryOperator::ExclusiveOr
603614
| crate::BinaryOperator::InclusiveOr

naga/tests/wgsl_errors.rs

+45
Original file line numberDiff line numberDiff line change
@@ -2837,3 +2837,48 @@ fn reject_utf8_bom() {
28372837
"#,
28382838
);
28392839
}
2840+
2841+
#[test]
2842+
fn vector_logical_ops() {
2843+
// Const context
2844+
check(
2845+
"const and = vec2(true, false) && vec2(false, false);",
2846+
r###"error: Cannot apply the binary op to the arguments
2847+
┌─ wgsl:1:13
2848+
2849+
1 │ const and = vec2(true, false) && vec2(false, false);
2850+
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ see msg
2851+
2852+
"###,
2853+
);
2854+
2855+
check(
2856+
"const or = vec2(true, false) || vec2(false, false);",
2857+
r###"error: Cannot apply the binary op to the arguments
2858+
┌─ wgsl:1:12
2859+
2860+
1 │ const or = vec2(true, false) || vec2(false, false);
2861+
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ see msg
2862+
2863+
"###,
2864+
);
2865+
2866+
// Runtime context
2867+
check(
2868+
"fn foo(a: vec2<bool>, b: vec2<bool>) {
2869+
let y = a && b;
2870+
}",
2871+
r#"error: Incompatible operands: LogicalAnd(Vector { size: Bi, scalar: Scalar { kind: Bool, width: 1 } }, _)
2872+
2873+
"#,
2874+
);
2875+
2876+
check(
2877+
"fn foo(a: vec2<bool>, b: vec2<bool>) {
2878+
let y = a || b;
2879+
}",
2880+
r#"error: Incompatible operands: LogicalOr(Vector { size: Bi, scalar: Scalar { kind: Bool, width: 1 } }, _)
2881+
2882+
"#,
2883+
);
2884+
}

0 commit comments

Comments
 (0)