Skip to content

Commit 5cf2d1d

Browse files
committed
[naga] Disallow logical operators && and || on vectors
Fixes #6856
1 parent cd81063 commit 5cf2d1d

4 files changed

Lines changed: 65 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ By @wumpf in [#7144](https://github.com/gfx-rs/wgpu/pull/7144)
254254
- 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).
255255
- 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).
256256
- Apply automatic conversions to `let` declarations, and accept `vecN()` as a constructor for vectors (in any context). By @andyleiserson in [#7367](https://github.com/gfx-rs/wgpu/pull/7367).
257+
- The `&&` and `||` operators are no longer allowed on vectors. By @andyleiserson in [#7368](https://github.com/gfx-rs/wgpu/pull/7368).
257258
258259
#### General
259260

naga/src/proc/constant_evaluator.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,10 +2227,13 @@ impl<'a> ConstantEvaluator<'a> {
22272227
| BinaryOperator::And
22282228
| BinaryOperator::ExclusiveOr
22292229
| BinaryOperator::InclusiveOr
2230-
| BinaryOperator::LogicalAnd
2231-
| BinaryOperator::LogicalOr
22322230
| BinaryOperator::ShiftLeft
22332231
| BinaryOperator::ShiftRight => left_ty,
2232+
2233+
BinaryOperator::LogicalAnd | BinaryOperator::LogicalOr => {
2234+
// Not supported on vectors
2235+
return Err(ConstantEvaluatorError::InvalidBinaryOpArgs);
2236+
}
22342237
};
22352238

22362239
let components = components

naga/src/proc/typifier.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -592,9 +592,8 @@ impl<'a> ResolveContext<'a> {
592592
| crate::BinaryOperator::Less
593593
| crate::BinaryOperator::LessEqual
594594
| crate::BinaryOperator::Greater
595-
| crate::BinaryOperator::GreaterEqual
596-
| crate::BinaryOperator::LogicalAnd
597-
| crate::BinaryOperator::LogicalOr => {
595+
| crate::BinaryOperator::GreaterEqual => {
596+
// These accept scalars or vectors.
598597
let scalar = crate::Scalar::BOOL;
599598
let inner = match *past(left)?.inner_with(types) {
600599
Ti::Scalar { .. } => Ti::Scalar(scalar),
@@ -607,6 +606,18 @@ impl<'a> ResolveContext<'a> {
607606
};
608607
TypeResolution::Value(inner)
609608
}
609+
crate::BinaryOperator::LogicalAnd | crate::BinaryOperator::LogicalOr => {
610+
// These accept scalars only.
611+
let bool = Ti::Scalar(crate::Scalar::BOOL);
612+
let ty = past(left)?.inner_with(types);
613+
if *ty == bool {
614+
TypeResolution::Value(bool)
615+
} else {
616+
return Err(ResolveError::IncompatibleOperands(format!(
617+
"{op:?}({ty:?}, _)"
618+
)));
619+
}
620+
}
610621
crate::BinaryOperator::And
611622
| crate::BinaryOperator::ExclusiveOr
612623
| crate::BinaryOperator::InclusiveOr

naga/tests/naga/wgsl_errors.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3155,6 +3155,51 @@ fn matrix_vector_pointers() {
31553155
);
31563156
}
31573157

3158+
#[test]
3159+
fn vector_logical_ops() {
3160+
// Const context
3161+
check(
3162+
"const and = vec2(true, false) && vec2(false, false);",
3163+
r###"error: Cannot apply the binary op to the arguments
3164+
┌─ wgsl:1:13
3165+
3166+
1 │ const and = vec2(true, false) && vec2(false, false);
3167+
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ see msg
3168+
3169+
"###,
3170+
);
3171+
3172+
check(
3173+
"const or = vec2(true, false) || vec2(false, false);",
3174+
r###"error: Cannot apply the binary op to the arguments
3175+
┌─ wgsl:1:12
3176+
3177+
1 │ const or = vec2(true, false) || vec2(false, false);
3178+
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ see msg
3179+
3180+
"###,
3181+
);
3182+
3183+
// Runtime context
3184+
check(
3185+
"fn foo(a: vec2<bool>, b: vec2<bool>) {
3186+
let y = a && b;
3187+
}",
3188+
r#"error: Incompatible operands: LogicalAnd(Vector { size: Bi, scalar: Scalar { kind: Bool, width: 1 } }, _)
3189+
3190+
"#,
3191+
);
3192+
3193+
check(
3194+
"fn foo(a: vec2<bool>, b: vec2<bool>) {
3195+
let y = a || b;
3196+
}",
3197+
r#"error: Incompatible operands: LogicalOr(Vector { size: Bi, scalar: Scalar { kind: Bool, width: 1 } }, _)
3198+
3199+
"#,
3200+
);
3201+
}
3202+
31583203
#[test]
31593204
fn issue7165() {
31603205
// Regression test for https://github.com/gfx-rs/wgpu/issues/7165

0 commit comments

Comments
 (0)