Report intermediate expressions as errors in For next-exprs.

We weren't coercing the expression because we don't care about its type,
but that allowed intermediate-expressions to pass through without
reporting an error. Now we coerce the expression to its present type,
which will always fail if the type is disallowed and succeed otherwise.

Change-Id: Ic0de0d17f0f5d56360575efe992ce4d74dec2a5a
Bug: oss-fuzz:37620
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/441876
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
index 5c1e3c9..51d7993 100644
--- a/gn/sksl_tests.gni
+++ b/gn/sksl_tests.gni
@@ -99,6 +99,7 @@
   "/sksl/errors/Ossfuzz32851.sksl",
   "/sksl/errors/Ossfuzz37457.sksl",
   "/sksl/errors/Ossfuzz37465.sksl",
+  "/sksl/errors/Ossfuzz37620.sksl",
   "/sksl/errors/OverflowFloatLiteral.sksl",
   "/sksl/errors/OverflowIntLiteral.sksl",
   "/sksl/errors/OverflowInt64Literal.sksl",
diff --git a/resources/sksl/errors/Ossfuzz37620.sksl b/resources/sksl/errors/Ossfuzz37620.sksl
new file mode 100644
index 0000000..bfbc55b
--- /dev/null
+++ b/resources/sksl/errors/Ossfuzz37620.sksl
@@ -0,0 +1 @@
+void n() { for(;;exp); }
diff --git a/src/sksl/ir/SkSLForStatement.cpp b/src/sksl/ir/SkSLForStatement.cpp
index d876de6..721bb7b 100644
--- a/src/sksl/ir/SkSLForStatement.cpp
+++ b/src/sksl/ir/SkSLForStatement.cpp
@@ -92,6 +92,16 @@
         }
     }
 
+    if (next) {
+        // The type of the next-expression doesn't matter, but it needs to be a complete expression.
+        // Report an error on intermediate expressions like FunctionReference or TypeReference.
+        const Type& nextType = next->type();
+        next = nextType.coerceExpression(std::move(next), context);
+        if (!next) {
+            return nullptr;
+        }
+    }
+
     if (context.fConfig->strictES2Mode()) {
         if (!Analysis::ForLoopIsValidForES2(offset, initializer.get(), test.get(), next.get(),
                                             statement.get(), /*outLoopInfo=*/nullptr,
diff --git a/tests/sksl/errors/Ossfuzz37620.glsl b/tests/sksl/errors/Ossfuzz37620.glsl
new file mode 100644
index 0000000..cfd2735
--- /dev/null
+++ b/tests/sksl/errors/Ossfuzz37620.glsl
@@ -0,0 +1,4 @@
+### Compilation failed:
+
+error: 1: expected '(' to begin function call
+1 error