SkSL: Only allow bitwise ops on integral types
We were allowing these ops on floating point types. The resulting GLSL
would fail to compile. We also allowed >>= and <<= on vectors (but not
any of the other bitwise ops).
The newly added unit tests were failing (eg, not catching errors). New
results are correct.
Bug: skia:10707
Change-Id: I97b769f1ce59261361109a71061b42dc8ef3c74b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317393
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 5349a2c..1107adf 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -1545,6 +1545,7 @@
const Type** outRightType,
const Type** outResultType) {
bool isLogical = false;
+ bool isBitwise = false;
bool validMatrixOrVectorOp = false;
bool isAssignment = Compiler::IsAssignment(op);
@@ -1636,12 +1637,23 @@
}
validMatrixOrVectorOp = true;
break;
+ 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_SHL:
+ case Token::Kind::TK_SHR:
+ case Token::Kind::TK_BITWISEAND:
+ case Token::Kind::TK_BITWISEOR:
+ case Token::Kind::TK_BITWISEXOR:
+ isBitwise = true;
+ validMatrixOrVectorOp = true;
+ break;
case Token::Kind::TK_PLUSEQ:
case Token::Kind::TK_MINUSEQ:
case Token::Kind::TK_SLASHEQ:
case Token::Kind::TK_PERCENTEQ:
- case Token::Kind::TK_SHLEQ:
- case Token::Kind::TK_SHREQ:
case Token::Kind::TK_PLUS:
case Token::Kind::TK_MINUS:
case Token::Kind::TK_SLASH:
@@ -1697,6 +1709,13 @@
if ((left.typeKind() == Type::TypeKind::kScalar &&
right.typeKind() == Type::TypeKind::kScalar) ||
(leftIsVectorOrMatrix && validMatrixOrVectorOp)) {
+ if (isBitwise) {
+ const Type& leftNumberType(leftIsVectorOrMatrix ? left.componentType() : left);
+ const Type& rightNumberType(rightIsVectorOrMatrix ? right.componentType() : right);
+ if (!leftNumberType.isInteger() || !rightNumberType.isInteger()) {
+ return false;
+ }
+ }
if (rightToLeftCost.isPossible(allowNarrowing) && rightToLeftCost < leftToRightCost) {
// Right-to-Left conversion is possible and cheaper
*outLeftType = &left;