SPV: Fix issue #506: generalize struct deep copy to include arrays.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 788dd63..4513df8 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2283,13 +2283,13 @@
 // Implicitly uses the existing builder.accessChain as the storage target.
 void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id rValue)
 {
-    // we only do the complex path here if it's a structure
-    if (! type.isStruct()) {
+    // we only do the complex path here if it's an aggregate
+    if (! type.isStruct() && ! type.isArray()) {
         accessChainStore(type, rValue);
         return;
     }
 
-    // and, it has to be a case of structure type aliasing
+    // and, it has to be a case of type aliasing
     spv::Id rType = builder.getTypeId(rValue);
     spv::Id lValue = builder.accessChainGetLValue();
     spv::Id lType = builder.getContainedTypeId(builder.getTypeId(lValue));
@@ -2298,26 +2298,46 @@
         return;
     }
 
-    // Recursively (as needed) copy a struct type to a different struct type,
+    // Recursively (as needed) copy an aggregate type to a different aggregate type,
     // where the two types were the same type in GLSL. This requires member
     // by member copy, recursively.
 
-    // loop over members
-    const glslang::TTypeList& members = *type.getStruct();
-    for (int m = 0; m < (int)members.size(); ++m) {
-        const glslang::TType& glslangMemberType = *members[m].type;
+    // If an array, copy element by element.
+    if (type.isArray()) {
+        glslang::TType glslangElementType(type, 0);
+        spv::Id elementRType = builder.getContainedTypeId(rType);
+        for (int index = 0; index < type.getOuterArraySize(); ++index) {
+            // get the source member
+            spv::Id elementRValue = builder.createCompositeExtract(rValue, elementRType, index);
 
-        // get the source member
-        spv::Id memberRType = builder.getContainedTypeId(rType, m);
-        spv::Id memberRValue = builder.createCompositeExtract(rValue, memberRType, m);
+            // set up the target storage
+            builder.clearAccessChain();
+            builder.setAccessChainLValue(lValue);
+            builder.accessChainPush(builder.makeIntConstant(index));
 
-        // set up the target storage
-        builder.clearAccessChain();
-        builder.setAccessChainLValue(lValue);
-        builder.accessChainPush(builder.makeIntConstant(m));
+            // store the member
+            multiTypeStore(glslangElementType, elementRValue);
+        }
+    } else {
+        assert(type.isStruct());
 
-        // store the member
-        multiTypeStore(glslangMemberType, memberRValue);
+        // loop over structure members
+        const glslang::TTypeList& members = *type.getStruct();
+        for (int m = 0; m < (int)members.size(); ++m) {
+            const glslang::TType& glslangMemberType = *members[m].type;
+
+            // get the source member
+            spv::Id memberRType = builder.getContainedTypeId(rType, m);
+            spv::Id memberRValue = builder.createCompositeExtract(rValue, memberRType, m);
+
+            // set up the target storage
+            builder.clearAccessChain();
+            builder.setAccessChainLValue(lValue);
+            builder.accessChainPush(builder.makeIntConstant(m));
+
+            // store the member
+            multiTypeStore(glslangMemberType, memberRValue);
+        }
     }
 }