diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index 4f0c92379d0ca51a43fc18326910fab5b594e0c6..42ce63bdf8847594e6698e790cc0e08475148058 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -39,6 +39,7 @@
 
 #include "../Include/Common.h"
 #include "../Include/BaseTypes.h"
+#include "../Public/ShaderLang.h"
 
 namespace glslang {
 
@@ -384,6 +385,21 @@ public:
         }
     }
 
+    // True if this type of IO is supposed to be arrayed with extra level for per-vertex data
+    bool isArrayedIo(EShLanguage language) const
+    {
+        switch (language) {
+        case EShLangGeometry:
+            return isPipeInput();
+        case EShLangTessControl:
+            return ! patch && (isPipeInput() || isPipeOutput());
+        case EShLangTessEvaluation:
+            return ! patch && isPipeInput();
+        default:
+            return false;
+        }
+    }
+
     // Implementing an embedded layout-qualifier class here, since C++ can't have a real class bitfield
     void clearLayout()
     {
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 747eaf43a8caaef5620ebd1d0f3853590a040d01..addd8f667004a7e0af3e34f20f18d26b956210ff 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -590,9 +590,7 @@ void TParseContext::fixIoArraySize(TSourceLoc loc, TType& type)
 void TParseContext::ioArrayCheck(TSourceLoc loc, const TType& type, const TString& identifier)
 {
     if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
-        if ((language == EShLangGeometry       &&  type.getQualifier().storage == EvqVaryingIn) ||
-            (language == EShLangTessControl    && (type.getQualifier().storage == EvqVaryingOut || type.getQualifier().storage == EvqVaryingIn) && ! type.getQualifier().patch) ||
-            (language == EShLangTessEvaluation &&  type.getQualifier().storage == EvqVaryingIn && ! type.getQualifier().patch))
+        if (type.getQualifier().isArrayedIo(language))
             error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
     }
 }
diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp
index e9c3610ec043c4a619500dd4ab83e2fc23c74678..6625a34ef944b3607bed79b7b245868ba92ba176 100644
--- a/glslang/MachineIndependent/linkValidate.cpp
+++ b/glslang/MachineIndependent/linkValidate.cpp
@@ -607,10 +607,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
             size = 1;
     } else {
         // Strip off the outer array dimension for those having an extra one.
-        if (type.isArray() && ! qualifier.patch &&
-            (language == EShLangGeometry && qualifier.isPipeInput()) ||
-            language == EShLangTessControl                           ||
-            (language == EShLangTessEvaluation && qualifier.isPipeInput())) {
+        if (type.isArray() && qualifier.isArrayedIo(language)) {
             TType elementType(type, 0);
             size = computeTypeLocationSize(elementType);
         } else