Fix parsing error with structs containing arrays.

Previously, a struct containing a vardecl with multiple declarations
would interpret arrays incorrectly. An array would be applied to ALL
variables in the decl after its initial appearance. That is,
`int w, x[10], y, z;` would be interpreted as
`int w, x[10], y[10], z[10];`.

This is now fixed and our test case runs as expected.

Change-Id: I5b4a617c58cdfb83face651effd42770a1f68638
Bug: oss-fuzz:37622
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/441879
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>
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index 316c0fd..3a3ae6a 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -473,6 +473,7 @@
             const ASTNode::VarData& vd = var.getVarData();
 
             // Read array size if one is present.
+            const Type* fieldType = type;
             if (vd.fIsArray) {
                 const ASTNode& size = *var.begin();
                 if (!size || size.fKind != ASTNode::Kind::kInt) {
@@ -485,10 +486,10 @@
                 }
                 // Add the array dimensions to our type.
                 int arraySize = size.getInt();
-                type = fSymbols.addArrayDimension(type, arraySize);
+                fieldType = fSymbols.addArrayDimension(fieldType, arraySize);
             }
 
-            fields.push_back(Type::Field(modifiers, vd.fName, type));
+            fields.push_back(Type::Field(modifiers, vd.fName, fieldType));
             if (vd.fIsArray ? var.begin()->fNext : var.fFirstChild) {
                 this->error(declsNode.fOffset, "initializers are not permitted on struct fields");
             }
diff --git a/tests/SkSLTest.cpp b/tests/SkSLTest.cpp
index 8fc4c75..7eeda17 100644
--- a/tests/SkSLTest.cpp
+++ b/tests/SkSLTest.cpp
@@ -284,6 +284,7 @@
 SKSL_TEST(SkSLStackingVectorCasts,             "shared/StackingVectorCasts.sksl")
 SKSL_TEST(SkSLStaticIf,                        "shared/StaticIf.sksl")
 SKSL_TEST_ES3(SkSLStaticSwitch,                "shared/StaticSwitch.sksl")
+SKSL_TEST(SkSLStructArrayFollowedByScalar,     "shared/StructArrayFollowedByScalar.sksl")
 SKSL_TEST(SkSLStructsInFunctions,              "shared/StructsInFunctions.sksl")
 SKSL_TEST(SkSLSwizzleBoolConstants,            "shared/SwizzleBoolConstants.sksl")
 SKSL_TEST(SkSLSwizzleByConstantIndex,          "shared/SwizzleByConstantIndex.sksl")
diff --git a/tests/sksl/shared/StructArrayFollowedByScalar.asm.frag b/tests/sksl/shared/StructArrayFollowedByScalar.asm.frag
index 056c845..67d0fc9 100644
--- a/tests/sksl/shared/StructArrayFollowedByScalar.asm.frag
+++ b/tests/sksl/shared/StructArrayFollowedByScalar.asm.frag
@@ -1,4 +1,82 @@
-### Compilation failed:
-
-error: 10: type mismatch: '=' cannot operate on 'half[3]', 'int'
-1 error
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %_entrypoint_v "_entrypoint" %sk_FragColor %sk_Clockwise
+OpExecutionMode %_entrypoint_v OriginUpperLeft
+OpName %sk_FragColor "sk_FragColor"
+OpName %sk_Clockwise "sk_Clockwise"
+OpName %_entrypoint_v "_entrypoint_v"
+OpName %main "main"
+OpName %S "S"
+OpMemberName %S 0 "rgb"
+OpMemberName %S 1 "a"
+OpName %s "s"
+OpDecorate %sk_FragColor RelaxedPrecision
+OpDecorate %sk_FragColor Location 0
+OpDecorate %sk_FragColor Index 0
+OpDecorate %sk_Clockwise BuiltIn FrontFacing
+OpDecorate %_arr_float_int_3 ArrayStride 16
+OpMemberDecorate %S 0 Offset 0
+OpMemberDecorate %S 0 RelaxedPrecision
+OpMemberDecorate %S 1 Offset 48
+OpMemberDecorate %S 1 RelaxedPrecision
+OpDecorate %39 RelaxedPrecision
+OpDecorate %41 RelaxedPrecision
+OpDecorate %43 RelaxedPrecision
+OpDecorate %45 RelaxedPrecision
+OpDecorate %46 RelaxedPrecision
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%sk_FragColor = OpVariable %_ptr_Output_v4float Output
+%bool = OpTypeBool
+%_ptr_Input_bool = OpTypePointer Input %bool
+%sk_Clockwise = OpVariable %_ptr_Input_bool Input
+%void = OpTypeVoid
+%12 = OpTypeFunction %void
+%v2float = OpTypeVector %float 2
+%float_0 = OpConstant %float 0
+%16 = OpConstantComposite %v2float %float_0 %float_0
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+%20 = OpTypeFunction %v4float %_ptr_Function_v2float
+%int = OpTypeInt 32 1
+%int_3 = OpConstant %int 3
+%_arr_float_int_3 = OpTypeArray %float %int_3
+%S = OpTypeStruct %_arr_float_int_3 %float
+%_ptr_Function_S = OpTypePointer Function %S
+%int_0 = OpConstant %int 0
+%_ptr_Function_float = OpTypePointer Function %float
+%float_1 = OpConstant %float 1
+%int_1 = OpConstant %int 1
+%int_2 = OpConstant %int 2
+%_entrypoint_v = OpFunction %void None %12
+%13 = OpLabel
+%17 = OpVariable %_ptr_Function_v2float Function
+OpStore %17 %16
+%19 = OpFunctionCall %v4float %main %17
+OpStore %sk_FragColor %19
+OpReturn
+OpFunctionEnd
+%main = OpFunction %v4float None %20
+%21 = OpFunctionParameter %_ptr_Function_v2float
+%22 = OpLabel
+%s = OpVariable %_ptr_Function_S Function
+%30 = OpAccessChain %_ptr_Function_float %s %int_0 %int_0
+OpStore %30 %float_0
+%34 = OpAccessChain %_ptr_Function_float %s %int_0 %int_1
+OpStore %34 %float_1
+%36 = OpAccessChain %_ptr_Function_float %s %int_0 %int_2
+OpStore %36 %float_0
+%37 = OpAccessChain %_ptr_Function_float %s %int_1
+OpStore %37 %float_1
+%38 = OpAccessChain %_ptr_Function_float %s %int_0 %int_0
+%39 = OpLoad %float %38
+%40 = OpAccessChain %_ptr_Function_float %s %int_0 %int_1
+%41 = OpLoad %float %40
+%42 = OpAccessChain %_ptr_Function_float %s %int_0 %int_2
+%43 = OpLoad %float %42
+%44 = OpAccessChain %_ptr_Function_float %s %int_1
+%45 = OpLoad %float %44
+%46 = OpCompositeConstruct %v4float %39 %41 %43 %45
+OpReturnValue %46
+OpFunctionEnd
diff --git a/tests/sksl/shared/StructArrayFollowedByScalar.glsl b/tests/sksl/shared/StructArrayFollowedByScalar.glsl
index 056c845..a8d87c5 100644
--- a/tests/sksl/shared/StructArrayFollowedByScalar.glsl
+++ b/tests/sksl/shared/StructArrayFollowedByScalar.glsl
@@ -1,4 +1,14 @@
-### Compilation failed:
 
-error: 10: type mismatch: '=' cannot operate on 'half[3]', 'int'
-1 error
+out vec4 sk_FragColor;
+struct S {
+    float rgb[3];
+    float a;
+};
+vec4 main() {
+    S s;
+    s.rgb[0] = 0.0;
+    s.rgb[1] = 1.0;
+    s.rgb[2] = 0.0;
+    s.a = 1.0;
+    return vec4(s.rgb[0], s.rgb[1], s.rgb[2], s.a);
+}
diff --git a/tests/sksl/shared/StructArrayFollowedByScalar.metal b/tests/sksl/shared/StructArrayFollowedByScalar.metal
index 056c845..8f4b4f3 100644
--- a/tests/sksl/shared/StructArrayFollowedByScalar.metal
+++ b/tests/sksl/shared/StructArrayFollowedByScalar.metal
@@ -1,4 +1,23 @@
-### Compilation failed:
-
-error: 10: type mismatch: '=' cannot operate on 'half[3]', 'int'
-1 error
+#include <metal_stdlib>
+#include <simd/simd.h>
+using namespace metal;
+struct S {
+    array<float, 3> rgb;
+    float a;
+};
+struct Inputs {
+};
+struct Outputs {
+    float4 sk_FragColor [[color(0)]];
+};
+fragment Outputs fragmentMain(Inputs _in [[stage_in]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {
+    Outputs _out;
+    (void)_out;
+    S s;
+    s.rgb[0] = 0.0;
+    s.rgb[1] = 1.0;
+    s.rgb[2] = 0.0;
+    s.a = 1.0;
+    _out.sk_FragColor = float4(s.rgb[0], s.rgb[1], s.rgb[2], s.a);
+    return _out;
+}