validation: unary operands
logical negation operand must be 'bool' or 'vecN<bool>'
complement operand must be be 'i32', 'u32', 'vecN<i32>' or 'vecN<u32>'
Negation operand must be 'i32', 'f32', 'vecN<i32>' or 'vecN<f32>'
Bug: tint:916 chromium:1216597
Change-Id: Ic88a124a32d16b542560da3ca1c159968d4043a0
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/55860
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index d16c958..9c302e4 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -2733,12 +2733,41 @@
const sem::Type* type = nullptr;
switch (unary->op()) {
- case ast::UnaryOp::kComplement:
- case ast::UnaryOp::kNegation:
case ast::UnaryOp::kNot:
// Result type matches the deref'd inner type.
type_name = TypeNameOf(unary->expr());
type = expr_type->UnwrapRef();
+ if (!type->Is<sem::Bool>() && !type->is_bool_vector()) {
+ AddError("cannot logical negate expression of type '" +
+ TypeNameOf(unary->expr()),
+ unary->expr()->source());
+ return false;
+ }
+ break;
+
+ case ast::UnaryOp::kComplement:
+ // Result type matches the deref'd inner type.
+ type_name = TypeNameOf(unary->expr());
+ type = expr_type->UnwrapRef();
+ if (!type->is_integer_scalar_or_vector()) {
+ AddError("cannot bitwise complement expression of type '" +
+ TypeNameOf(unary->expr()),
+ unary->expr()->source());
+ return false;
+ }
+ break;
+
+ case ast::UnaryOp::kNegation:
+ // Result type matches the deref'd inner type.
+ type_name = TypeNameOf(unary->expr());
+ type = expr_type->UnwrapRef();
+ if (!(type->IsAnyOf<sem::F32, sem::I32>() ||
+ type->is_signed_integer_vector() || type->is_float_vector())) {
+ AddError(
+ "cannot negate expression of type '" + TypeNameOf(unary->expr()),
+ unary->expr()->source());
+ return false;
+ }
break;
case ast::UnaryOp::kAddressOf: