Improve error-checking during array-size conversion.

The fuzzer noticed insufficient guards in IndexExpression::Convert when
converting an array size from an IntLiteral to a SKSL_INT. We had code
in IRGenerator which did this properly, so I moved our array-size
conversion logic into SkSLType and had IndexExpression share it.

Also, a variety of tests around similar error conditions were added.

Change-Id: I51529dea25f9029f81ae236511610069d66be29f
Bug: oss-fuzz:37462
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/441236
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index c4eeb8c..73278ca 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -216,37 +216,7 @@
     if (!size) {
         return 0;
     }
-    return this->convertArraySize(type, std::move(size));
-}
-
-int IRGenerator::convertArraySize(const Type& type, std::unique_ptr<Expression> size) {
-    size = this->coerce(std::move(size), *fContext.fTypes.fInt);
-    if (!size) {
-        return 0;
-    }
-    if (type.isVoid()) {
-        this->errorReporter().error(size->fOffset, "type 'void' may not be used in an array");
-        return 0;
-    }
-    if (type.isOpaque()) {
-        this->errorReporter().error(
-                size->fOffset, "opaque type '" + type.name() + "' may not be used in an array");
-        return 0;
-    }
-    if (!size->is<IntLiteral>()) {
-        this->errorReporter().error(size->fOffset, "array size must be an integer");
-        return 0;
-    }
-    SKSL_INT count = size->as<IntLiteral>().value();
-    if (count <= 0) {
-        this->errorReporter().error(size->fOffset, "array size must be positive");
-        return 0;
-    }
-    if (!SkTFitsIn<int>(count)) {
-        this->errorReporter().error(size->fOffset, "array size is too large");
-        return 0;
-    }
-    return static_cast<int>(count);
+    return type.convertArraySize(fContext, std::move(size));
 }
 
 void IRGenerator::checkVarDeclaration(int offset, const Modifiers& modifiers, const Type* baseType,
@@ -320,7 +290,7 @@
     int arraySizeValue = 0;
     if (isArray) {
         SkASSERT(arraySize);
-        arraySizeValue = this->convertArraySize(*type, std::move(arraySize));
+        arraySizeValue = type->convertArraySize(fContext, std::move(arraySize));
         if (!arraySizeValue) {
             return {};
         }