Reland "Disallow constructors of ES3 types in ES2 code."

This is a reland of 36f53ec7e10e16ad6c33156a5d5fa25975cc7fac

Original change's description:
> Disallow constructors of ES3 types in ES2 code.
>
> The fuzzer found that we constructed TypeReferences without first
> checking for disallowed tyoes. (In fact, TypeReference creation had no
> error checking at all; it didn't even have Convert/Make functions.)
>
> Added proper Convert/Make to TypeReference, and used those calls to
> report errors or cause assertions if trying to make a TypeReference to a
> type that the program did not support.
>
> (While tracking down this bug, I added strict-ES2 type assertions to our
> constructor IR nodes as well. This helped pinpoint the error and seem
> reasonable to leave in, just in case.)
>
> Change-Id: I896b68ae9d3d9e1f30d7eba9fa594617ab851c74
> Bug: oss-fuzz:39540
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/455498
> Commit-Queue: John Stiles <johnstiles@google.com>
> Commit-Queue: Brian Osman <brianosman@google.com>
> Auto-Submit: John Stiles <johnstiles@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>

Bug: oss-fuzz:39540
Change-Id: Id8e323c22b18726214613b6061c08873048b7c69
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/455617
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 4427d70..bcfdd90 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -360,8 +360,7 @@
                                      FieldAccess::OwnerKind::kAnonymousInterfaceBlock);
         }
         case Symbol::Kind::kType: {
-            const Type* t = &result->as<Type>();
-            return std::make_unique<TypeReference>(fContext, line, t);
+            return TypeReference::Convert(fContext, line, &result->as<Type>());
         }
         case Symbol::Kind::kExternal: {
             const ExternalFunction* r = &result->as<ExternalFunction>();
diff --git a/src/sksl/ir/SkSLConstructorArrayCast.cpp b/src/sksl/ir/SkSLConstructorArrayCast.cpp
index 46c97d4..55030ec 100644
--- a/src/sksl/ir/SkSLConstructorArrayCast.cpp
+++ b/src/sksl/ir/SkSLConstructorArrayCast.cpp
@@ -45,6 +45,7 @@
     SkASSERT(type.isArray());
     SkASSERT(arg->type().isArray());
     SkASSERT(type.columns() == arg->type().columns());
+    SkASSERT(type.allowedInES2() || !context.fConfig->strictES2Mode());
 
     // If this is a no-op cast, return the expression as-is.
     if (type == arg->type()) {
diff --git a/src/sksl/ir/SkSLConstructorCompound.cpp b/src/sksl/ir/SkSLConstructorCompound.cpp
index 59a9a96..41c3954 100644
--- a/src/sksl/ir/SkSLConstructorCompound.cpp
+++ b/src/sksl/ir/SkSLConstructorCompound.cpp
@@ -17,6 +17,8 @@
                                                       int line,
                                                       const Type& type,
                                                       ExpressionArray args) {
+    SkASSERT(type.allowedInES2() || !context.fConfig->strictES2Mode());
+
     // A scalar "composite" type with a single scalar argument is a no-op and can be eliminated.
     // (Pedantically, this isn't a composite at all, but it's harmless to allow and simplifies
     // call sites which need to narrow a vector and may sometimes end up with a scalar.)
diff --git a/src/sksl/ir/SkSLConstructorCompoundCast.cpp b/src/sksl/ir/SkSLConstructorCompoundCast.cpp
index e96c3d0..9f6b5d6 100644
--- a/src/sksl/ir/SkSLConstructorCompoundCast.cpp
+++ b/src/sksl/ir/SkSLConstructorCompoundCast.cpp
@@ -66,6 +66,7 @@
                                                           std::unique_ptr<Expression> arg) {
     // Only vectors or matrices of the same dimensions are allowed.
     SkASSERT(type.isVector() || type.isMatrix());
+    SkASSERT(type.allowedInES2() || !context.fConfig->strictES2Mode());
     SkASSERT(arg->type().isVector() == type.isVector());
     SkASSERT(arg->type().isMatrix() == type.isMatrix());
     SkASSERT(type.columns() == arg->type().columns());
diff --git a/src/sksl/ir/SkSLConstructorDiagonalMatrix.cpp b/src/sksl/ir/SkSLConstructorDiagonalMatrix.cpp
index 1762df6..2f85d16 100644
--- a/src/sksl/ir/SkSLConstructorDiagonalMatrix.cpp
+++ b/src/sksl/ir/SkSLConstructorDiagonalMatrix.cpp
@@ -17,6 +17,7 @@
                                                             const Type& type,
                                                             std::unique_ptr<Expression> arg) {
     SkASSERT(type.isMatrix());
+    SkASSERT(type.allowedInES2() || !context.fConfig->strictES2Mode());
     SkASSERT(arg->type().isScalar());
     SkASSERT(arg->type() == type.componentType());
     return std::make_unique<ConstructorDiagonalMatrix>(line, type, std::move(arg));
diff --git a/src/sksl/ir/SkSLConstructorMatrixResize.cpp b/src/sksl/ir/SkSLConstructorMatrixResize.cpp
index 3639e4c..c9fcf70 100644
--- a/src/sksl/ir/SkSLConstructorMatrixResize.cpp
+++ b/src/sksl/ir/SkSLConstructorMatrixResize.cpp
@@ -17,6 +17,7 @@
                                                           const Type& type,
                                                           std::unique_ptr<Expression> arg) {
     SkASSERT(type.isMatrix());
+    SkASSERT(type.allowedInES2() || !context.fConfig->strictES2Mode());
     SkASSERT(arg->type().componentType() == type.componentType());
 
     // If the matrix isn't actually changing size, return it as-is.
diff --git a/src/sksl/ir/SkSLConstructorScalarCast.cpp b/src/sksl/ir/SkSLConstructorScalarCast.cpp
index a34b9e4..0c1d353 100644
--- a/src/sksl/ir/SkSLConstructorScalarCast.cpp
+++ b/src/sksl/ir/SkSLConstructorScalarCast.cpp
@@ -52,6 +52,7 @@
                                                         const Type& type,
                                                         std::unique_ptr<Expression> arg) {
     SkASSERT(type.isScalar());
+    SkASSERT(type.allowedInES2() || !context.fConfig->strictES2Mode());
     SkASSERT(arg->type().isScalar());
 
     // No cast required when the types match.
diff --git a/src/sksl/ir/SkSLConstructorSplat.cpp b/src/sksl/ir/SkSLConstructorSplat.cpp
index 54d30bf..ac07690 100644
--- a/src/sksl/ir/SkSLConstructorSplat.cpp
+++ b/src/sksl/ir/SkSLConstructorSplat.cpp
@@ -14,6 +14,7 @@
                                                    int line,
                                                    const Type& type,
                                                    std::unique_ptr<Expression> arg) {
+    SkASSERT(type.allowedInES2() || !context.fConfig->strictES2Mode());
     SkASSERT(arg->type().scalarTypeForLiteral() == type.componentType().scalarTypeForLiteral());
     SkASSERT(arg->type().isScalar());
 
diff --git a/src/sksl/ir/SkSLIndexExpression.cpp b/src/sksl/ir/SkSLIndexExpression.cpp
index e4434e2..35752bd 100644
--- a/src/sksl/ir/SkSLIndexExpression.cpp
+++ b/src/sksl/ir/SkSLIndexExpression.cpp
@@ -8,6 +8,7 @@
 #include "src/sksl/SkSLConstantFolder.h"
 #include "src/sksl/ir/SkSLIndexExpression.h"
 #include "src/sksl/ir/SkSLSwizzle.h"
+#include "src/sksl/ir/SkSLTypeReference.h"
 
 namespace SkSL {
 
@@ -43,8 +44,8 @@
         if (!arraySize) {
             return nullptr;
         }
-        return std::make_unique<TypeReference>(context, base->fLine,
-                                               symbolTable.addArrayDimension(&baseType, arraySize));
+        return TypeReference::Convert(context, base->fLine,
+                                      symbolTable.addArrayDimension(&baseType, arraySize));
     }
     // Convert an index expression with an expression inside of it: `arr[a * 3]`.
     const Type& baseType = base->type();
diff --git a/src/sksl/ir/SkSLTypeReference.cpp b/src/sksl/ir/SkSLTypeReference.cpp
new file mode 100644
index 0000000..dda468b
--- /dev/null
+++ b/src/sksl/ir/SkSLTypeReference.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/sksl/ir/SkSLTypeReference.h"
+
+#include "include/sksl/SkSLErrorReporter.h"
+#include "src/sksl/SkSLProgramSettings.h"
+
+namespace SkSL {
+
+std::unique_ptr<TypeReference> TypeReference::Convert(const Context& context,
+                                                      int line,
+                                                      const Type* type) {
+    if (context.fConfig->strictES2Mode() && !type->allowedInES2()) {
+        context.fErrors->error(line, "type '" + type->displayName() + "' is not supported");
+        return nullptr;
+    }
+    return TypeReference::Make(context, line, type);
+}
+
+std::unique_ptr<TypeReference> TypeReference::Make(const Context& context,
+                                                   int line,
+                                                   const Type* type) {
+    SkASSERT(type->allowedInES2() || !context.fConfig->strictES2Mode());
+    return std::make_unique<TypeReference>(context, line, type);
+}
+
+} // namespace SkSL
diff --git a/src/sksl/ir/SkSLTypeReference.h b/src/sksl/ir/SkSLTypeReference.h
index 5bab7ed..38b6ff4 100644
--- a/src/sksl/ir/SkSLTypeReference.h
+++ b/src/sksl/ir/SkSLTypeReference.h
@@ -22,8 +22,15 @@
     static constexpr Kind kExpressionKind = Kind::kTypeReference;
 
     TypeReference(const Context& context, int line, const Type* value)
-        : INHERITED(line, kExpressionKind, context.fTypes.fInvalid.get())
-        , fValue(*value) {}
+        : TypeReference(line, value, context.fTypes.fInvalid.get()) {}
+
+    // Creates a reference to an SkSL type; uses the ErrorReporter to report errors.
+    static std::unique_ptr<TypeReference> Convert(const Context& context,
+                                                  int line,
+                                                  const Type* type);
+
+    // Creates a reference to an SkSL type; reports errors via ASSERT.
+    static std::unique_ptr<TypeReference> Make(const Context& context, int line, const Type* type);
 
     const Type& value() const {
         return fValue;