SkSL: Disallow '%' and '%=' on non-integral types
Bug: skia:11072
Change-Id: Ic24e40bfea5bf1d2d14c0f681632228a5ecc7104
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/342929
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
Auto-Submit: Brian Osman <brianosman@google.com>
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
index d0ca64f..5982371 100644
--- a/gn/sksl_tests.gni
+++ b/gn/sksl_tests.gni
@@ -101,6 +101,7 @@
"$_tests/sksl/errors/EnumValueMustBeConstInt.sksl",
"$_tests/sksl/errors/ErrorsInDeadCode.sksl",
"$_tests/sksl/errors/FieldAfterRuntimeArray.sksl",
+ "$_tests/sksl/errors/FloatRemainder.sksl",
"$_tests/sksl/errors/ForTypeMismatch.sksl",
"$_tests/sksl/errors/GenericArgumentMismatch.sksl",
"$_tests/sksl/errors/IfTypeMismatch.sksl",
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 71bec1a..2e7ae56 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -1532,20 +1532,22 @@
}
/**
- * Defines the set of operators which perform bitwise math.
+ * Defines the set of operators which are only valid on integral types.
*/
-static bool op_is_bitwise(Token::Kind op) {
+static bool op_only_valid_for_integral_types(Token::Kind op) {
switch (op) {
case Token::Kind::TK_SHL:
case Token::Kind::TK_SHR:
case Token::Kind::TK_BITWISEAND:
case Token::Kind::TK_BITWISEOR:
case Token::Kind::TK_BITWISEXOR:
+ case Token::Kind::TK_PERCENT:
case Token::Kind::TK_SHLEQ:
case Token::Kind::TK_SHREQ:
case Token::Kind::TK_BITWISEANDEQ:
case Token::Kind::TK_BITWISEOREQ:
case Token::Kind::TK_BITWISEXOREQ:
+ case Token::Kind::TK_PERCENTEQ:
return true;
default:
return false;
@@ -1716,7 +1718,7 @@
: left.coercionCost(right);
if ((left.isScalar() && right.isScalar()) || (leftIsVectorOrMatrix && validMatrixOrVectorOp)) {
- if (op_is_bitwise(op)) {
+ if (op_only_valid_for_integral_types(op)) {
if (!leftComponentType.isInteger() || !rightComponentType.isInteger()) {
return false;
}
diff --git a/tests/SkSLInterpreterTest.cpp b/tests/SkSLInterpreterTest.cpp
index 9dc5884..7e23e53 100644
--- a/tests/SkSLInterpreterTest.cpp
+++ b/tests/SkSLInterpreterTest.cpp
@@ -218,10 +218,6 @@
}
DEF_TEST(SkSLInterpreterRemainder, r) {
- test(r, "void main(inout half4 color) { color.r = color.r % color.g; }", 3.125, 2, 0, 0,
- 1.125, 2, 0, 0);
- test(r, "void main(inout half4 color) { color %= half4(1, 2, 3, 4); }", 9.5, 9.5, 9.5, 9.5,
- 0.5, 1.5, 0.5, 1.5);
test(r, "void main(inout half4 color) { color.r = int(color.r) % int(color.g); }", 8, 3, 0, 0,
2, 3, 0, 0);
test(r, "void main(inout half4 color) { color.rg = half2(int2(int(color.r), int(color.g)) % "
diff --git a/tests/sksl/errors/FloatRemainder.sksl b/tests/sksl/errors/FloatRemainder.sksl
new file mode 100644
index 0000000..fa77d2b
--- /dev/null
+++ b/tests/sksl/errors/FloatRemainder.sksl
@@ -0,0 +1,7 @@
+// Expect 2 errors (one per function)
+
+float x;
+float y;
+
+void rem() { x = x % y; }
+void rem_eq() { x %= y; }
diff --git a/tests/sksl/errors/golden/FloatRemainder.glsl b/tests/sksl/errors/golden/FloatRemainder.glsl
new file mode 100644
index 0000000..1ae811e
--- /dev/null
+++ b/tests/sksl/errors/golden/FloatRemainder.glsl
@@ -0,0 +1,5 @@
+### Compilation failed:
+
+error: 6: type mismatch: '%' cannot operate on 'float', 'float'
+error: 7: type mismatch: '%=' cannot operate on 'float', 'float'
+2 errors
diff --git a/tests/sksl/fp/GrModuloOp.fp b/tests/sksl/fp/GrModuloOp.fp
index fe0602a..957fd07 100644
--- a/tests/sksl/fp/GrModuloOp.fp
+++ b/tests/sksl/fp/GrModuloOp.fp
@@ -1,3 +1,4 @@
+// Test that '%' is expanded to '%%' in emitCode
void main() {
- sk_OutColor.r = half(1 % sqrt(2));
+ sk_OutColor.r = half(1 % int(sqrt(2)));
}
diff --git a/tests/sksl/fp/golden/GrModuloOp.cpp b/tests/sksl/fp/golden/GrModuloOp.cpp
index 7af7b83..53aec43 100644
--- a/tests/sksl/fp/golden/GrModuloOp.cpp
+++ b/tests/sksl/fp/golden/GrModuloOp.cpp
@@ -20,7 +20,7 @@
const GrModuloOp& _outer = args.fFp.cast<GrModuloOp>();
(void) _outer;
fragBuilder->codeAppendf(
-R"SkSL(%s.x = half(1.0 %% sqrt(2.0));
+R"SkSL(%s.x = half(1 %% int(sqrt(2.0)));
)SkSL"
, args.fOutputColor);
}