diff --git a/Test/310.frag b/Test/310.frag
index 4c468ff7672cf1c01b6e853060823356b7adaaee..1db77f2ac28e53cb98d989e3e6ce55d373f9f7d8 100644
--- a/Test/310.frag
+++ b/Test/310.frag
@@ -123,3 +123,62 @@ struct SA { float f[4]; };
 in SA inSA;          // ERROR
 struct SS { float f; S s; };
 in SS inSS;          // ERROR
+
+#ifndef GL_EXT_shader_io_blocks
+#error GL_EXT_shader_io_blocks not defined
+#endif
+
+#extension GL_EXT_shader_io_blocks : enable
+
+out outbname { int a; } outbinst;   // ERROR, not out block in fragment shader
+
+in inbname {
+    int a;
+    vec4 v;
+    struct { int b; } s;     // ERROR, nested struct definition
+} inbinst;
+
+in inbname2 {
+    layout(location = 12) int aAnon;
+    layout(location = 13) centroid in vec4 vAnon;
+};
+
+in layout(location = 13) vec4 aliased; // ERROR, aliased
+
+in inbname2 {                // ERROR, reuse of block name
+    int aAnon;
+    centroid in vec4 vAnon;
+};
+
+in badmember {               // ERROR, aAnon already in global scope
+    int aAnon;
+};
+
+int inbname;                 // ERROR, redefinition of block name
+
+vec4 vAnon;                  // ERROR, anon in global scope; redefinition
+
+in arrayed {
+    float f;
+} arrayedInst[4];
+
+void fooIO()
+{
+    vec4 v = inbinst.v + vAnon;
+    v *= arrayedInst[2].f;
+    v *= arrayedInst[i].f;       // ERROR, not constant
+}
+
+in vec4 gl_FragCoord;
+layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord;  // ERROR, non-ES
+
+layout(early_fragment_tests) in;
+out float gl_FragDepth;
+layout(depth_any) out float gl_FragDepth;  // ERROR, non-ES
+
+void foo_IO()
+{
+    gl_FragDepth = 0.2;  // ERROR, early_fragment_tests declared
+}
+
+out float gl_FragDepth;
diff --git a/Test/310.vert b/Test/310.vert
index 8e08fa4fa3fbde59bec7373b3090de2afc4c485a..a0bf9e158b51f7ee3b2757749f0ca6b8b9eca4d1 100644
--- a/Test/310.vert
+++ b/Test/310.vert
@@ -84,3 +84,42 @@ out SS outSS;          // ERROR
 
 layout(std430) uniform U430 { int a; } U430i;    // ERROR
 layout(std430) buffer B430 { int a; } B430i;
+
+#ifndef GL_OES_shader_io_blocks
+#error GL_OES_shader_io_blocks not defined
+#endif
+
+#extension GL_OES_shader_io_blocks : enable
+
+out outbname {
+    int a;
+    out vec4 v;
+    highp sampler2D s;   // ERROR, opaque type
+} outbinst;
+
+out outbname2 {
+    layout(location = 12) int aAnon;
+    layout(location = 13) vec4 vAnon;
+};
+
+layout(location = 12) out highp int aliased;  // ERROR, aliasing location
+
+in inbname { int a; } inbinst;  // ERROR, no in block in vertex shader
+
+out gl_PerVertex {              // ERROR, has extra member
+    highp vec4 gl_Position;
+    highp vec4 t;
+};
+
+void foo_IO()
+{
+    int sum  = gl_VertexID +
+               gl_InstanceID;
+    gl_Position = vec4(1.0);
+    gl_PointSize = 2.0;         // ERROR, removed by redeclaration
+}
+
+out gl_PerVertex {              // ERROR, already used and already redeclared
+    highp vec4 gl_Position;
+    highp vec4 t;
+};
diff --git a/Test/baseResults/310.frag.out b/Test/baseResults/310.frag.out
index 91ff06790d218fcd5baf08bd1fb289d8f2d1f47a..f610635fe5548ab29cf7319bf0b3be70c0cfe6d9 100644
--- a/Test/baseResults/310.frag.out
+++ b/Test/baseResults/310.frag.out
@@ -41,11 +41,28 @@ ERROR: 0:120: 'fragment-shader array-of-struct input' : not supported with this
 ERROR: 0:121: 'fragment-shader array-of-struct input' : not supported with this profile: es
 ERROR: 0:123: 'fragment-shader struct input containing an array' : not supported with this profile: es
 ERROR: 0:125: 'fragment-shader struct input containing structure' : not supported with this profile: es
-ERROR: 41 compilation errors.  No code generated.
+ERROR: 0:133: 'out' : cannot declare an output block in a fragment shader 
+ERROR: 0:138: '' : cannot nest a structure definition inside a structure or block 
+ERROR: 0:146: 'location' : overlapping use of location 13
+ERROR: 0:148: 'inbname2' : Cannot reuse block name within the same interface: in
+ERROR: 0:153: 'badmember' : nameless block contains a member that already has a name at global scope 
+ERROR: 0:157: 'inbname' : redefinition 
+ERROR: 0:159: 'vAnon' : redefinition 
+ERROR: 0:169: 'variable indexing block array' : not supported with this profile: es
+ERROR: 0:173: 'origin_upper_left' : not supported with this profile: es
+ERROR: 0:173: 'pixel_center_integer' : not supported with this profile: es
+ERROR: 0:173: 'redeclaration' : cannot redeclare with different qualification: gl_FragCoord
+ERROR: 0:177: 'depth layout qualifier' : not supported with this profile: es
+ERROR: 0:181: 'assign' :  l-value required "gl_FragDepth" (can't modify gl_FragDepth if using early_fragment_tests)
+ERROR: 54 compilation errors.  No code generated.
 
 
 Shader version: 310
+Requested GL_EXT_shader_io_blocks
+gl_FragCoord pixel center is integer
+gl_FragCoord origin is upper left
 using early_fragment_tests
+using depth_any
 ERROR: node is still EOpNull!
 0:21  Function Definition: main( (global void)
 0:21    Function Parameters: 
@@ -259,6 +276,45 @@ ERROR: node is still EOpNull!
 0:107        'v2' (temp highp 2-component vector of int)
 0:107        Function Call: imageSize(I21; (global highp 2-component vector of int)
 0:107          'i2Dqualified' (layout(binding=6 ) coherent volatile restrict uniform highp image2D)
+0:165  Function Definition: fooIO( (global void)
+0:165    Function Parameters: 
+0:167    Sequence
+0:167      Sequence
+0:167        move second child to first child (temp mediump 4-component vector of float)
+0:167          'v' (temp mediump 4-component vector of float)
+0:167          add (temp mediump 4-component vector of float)
+0:167            v: direct index for structure (in mediump 4-component vector of float)
+0:167              'inbinst' (in block{in mediump int a, in mediump 4-component vector of float v, in structure{global mediump int b} s})
+0:167              Constant:
+0:167                1 (const int)
+0:167            vAnon: direct index for structure (layout(location=13 ) centroid in mediump 4-component vector of float)
+0:167              'anon@0' (in block{layout(location=12 ) in mediump int aAnon, layout(location=13 ) centroid in mediump 4-component vector of float vAnon})
+0:167              Constant:
+0:167                1 (const uint)
+0:168      vector scale second child into first child (temp mediump 4-component vector of float)
+0:168        'v' (temp mediump 4-component vector of float)
+0:168        f: direct index for structure (in mediump float)
+0:168          direct index (temp block{in mediump float f})
+0:168            'arrayedInst' (in 4-element array of block{in mediump float f})
+0:168            Constant:
+0:168              2 (const int)
+0:168          Constant:
+0:168            0 (const int)
+0:169      vector scale second child into first child (temp mediump 4-component vector of float)
+0:169        'v' (temp mediump 4-component vector of float)
+0:169        f: direct index for structure (in mediump float)
+0:169          indirect index (temp block{in mediump float f})
+0:169            'arrayedInst' (in 4-element array of block{in mediump float f})
+0:169            'i' (uniform mediump int)
+0:169          Constant:
+0:169            0 (const int)
+0:179  Function Definition: foo_IO( (global void)
+0:179    Function Parameters: 
+0:181    Sequence
+0:181      move second child to first child (temp highp float)
+0:181        'gl_FragDepth' (gl_FragDepth highp float FragDepth)
+0:181        Constant:
+0:181          0.200000
 0:?   Linker Objects
 0:?     'gl_FragCoord' (smooth in mediump 4-component vector of float)
 0:?     'v3' (layout(location=2 ) smooth in mediump 3-component vector of float)
@@ -300,6 +356,13 @@ ERROR: node is still EOpNull!
 0:?     'insa' (smooth in 4-element array of structure{global mediump float f})
 0:?     'inSA' (smooth in structure{global 4-element array of mediump float f})
 0:?     'inSS' (smooth in structure{global mediump float f, global structure{global mediump float f} s})
+0:?     'outbinst' (out block{out mediump int a})
+0:?     'inbinst' (in block{in mediump int a, in mediump 4-component vector of float v, in structure{global mediump int b} s})
+0:?     'anon@0' (in block{layout(location=12 ) in mediump int aAnon, layout(location=13 ) centroid in mediump 4-component vector of float vAnon})
+0:?     'aliased' (layout(location=13 ) smooth in mediump 4-component vector of float)
+0:?     'arrayedInst' (in 4-element array of block{in mediump float f})
+0:?     'gl_FragDepth' (gl_FragDepth highp float FragDepth)
+0:?     'gl_FragDepth' (gl_FragDepth highp float FragDepth)
 
 
 Linked fragment stage:
@@ -307,7 +370,11 @@ Linked fragment stage:
 ERROR: Linking fragment stage: when more than one fragment shader output, all must have location qualifiers
 
 Shader version: 310
+Requested GL_EXT_shader_io_blocks
+gl_FragCoord pixel center is integer
+gl_FragCoord origin is upper left
 using early_fragment_tests
+using depth_any
 ERROR: node is still EOpNull!
 0:21  Function Definition: main( (global void)
 0:21    Function Parameters: 
@@ -521,6 +588,45 @@ ERROR: node is still EOpNull!
 0:107        'v2' (temp highp 2-component vector of int)
 0:107        Function Call: imageSize(I21; (global highp 2-component vector of int)
 0:107          'i2Dqualified' (layout(binding=6 ) coherent volatile restrict uniform highp image2D)
+0:165  Function Definition: fooIO( (global void)
+0:165    Function Parameters: 
+0:167    Sequence
+0:167      Sequence
+0:167        move second child to first child (temp mediump 4-component vector of float)
+0:167          'v' (temp mediump 4-component vector of float)
+0:167          add (temp mediump 4-component vector of float)
+0:167            v: direct index for structure (in mediump 4-component vector of float)
+0:167              'inbinst' (in block{in mediump int a, in mediump 4-component vector of float v, in structure{global mediump int b} s})
+0:167              Constant:
+0:167                1 (const int)
+0:167            vAnon: direct index for structure (layout(location=13 ) centroid in mediump 4-component vector of float)
+0:167              'anon@0' (in block{layout(location=12 ) in mediump int aAnon, layout(location=13 ) centroid in mediump 4-component vector of float vAnon})
+0:167              Constant:
+0:167                1 (const uint)
+0:168      vector scale second child into first child (temp mediump 4-component vector of float)
+0:168        'v' (temp mediump 4-component vector of float)
+0:168        f: direct index for structure (in mediump float)
+0:168          direct index (temp block{in mediump float f})
+0:168            'arrayedInst' (in 4-element array of block{in mediump float f})
+0:168            Constant:
+0:168              2 (const int)
+0:168          Constant:
+0:168            0 (const int)
+0:169      vector scale second child into first child (temp mediump 4-component vector of float)
+0:169        'v' (temp mediump 4-component vector of float)
+0:169        f: direct index for structure (in mediump float)
+0:169          indirect index (temp block{in mediump float f})
+0:169            'arrayedInst' (in 4-element array of block{in mediump float f})
+0:169            'i' (uniform mediump int)
+0:169          Constant:
+0:169            0 (const int)
+0:179  Function Definition: foo_IO( (global void)
+0:179    Function Parameters: 
+0:181    Sequence
+0:181      move second child to first child (temp highp float)
+0:181        'gl_FragDepth' (gl_FragDepth highp float FragDepth)
+0:181        Constant:
+0:181          0.200000
 0:?   Linker Objects
 0:?     'gl_FragCoord' (smooth in mediump 4-component vector of float)
 0:?     'v3' (layout(location=2 ) smooth in mediump 3-component vector of float)
@@ -562,4 +668,11 @@ ERROR: node is still EOpNull!
 0:?     'insa' (smooth in 4-element array of structure{global mediump float f})
 0:?     'inSA' (smooth in structure{global 4-element array of mediump float f})
 0:?     'inSS' (smooth in structure{global mediump float f, global structure{global mediump float f} s})
+0:?     'outbinst' (out block{out mediump int a})
+0:?     'inbinst' (in block{in mediump int a, in mediump 4-component vector of float v, in structure{global mediump int b} s})
+0:?     'anon@0' (in block{layout(location=12 ) in mediump int aAnon, layout(location=13 ) centroid in mediump 4-component vector of float vAnon})
+0:?     'aliased' (layout(location=13 ) smooth in mediump 4-component vector of float)
+0:?     'arrayedInst' (in 4-element array of block{in mediump float f})
+0:?     'gl_FragDepth' (gl_FragDepth highp float FragDepth)
+0:?     'gl_FragDepth' (gl_FragDepth highp float FragDepth)
 
diff --git a/Test/baseResults/310.geom.out b/Test/baseResults/310.geom.out
index 22e02a568e225fd5c6eb700f3b9cd25dd41926d2..7efb5f23b23b164a65d7657a77694c26ca454cab 100644
--- a/Test/baseResults/310.geom.out
+++ b/Test/baseResults/310.geom.out
@@ -1,7 +1,6 @@
 310.geom
 Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.
 WARNING: 0:3: '#extension' : extension is only partially supported: GL_EXT_geometry_shader
-WARNING: 0:3: '#extension' : extension is only partially supported: GL_EXT_shader_io_blocks
 ERROR: 0:21: 'fromVertex' : block instance name redefinition 
 ERROR: 0:25: 'fromVertex' : redefinition 
 ERROR: 0:27: 'fooC' : block instance name redefinition 
diff --git a/Test/baseResults/310.vert.out b/Test/baseResults/310.vert.out
index 2b5f995fddf54b098d1c37d85842c1128da6b1b1..901d3329d00c60b8e63106d94c9e03fad2d948f6 100644
--- a/Test/baseResults/310.vert.out
+++ b/Test/baseResults/310.vert.out
@@ -15,10 +15,18 @@ ERROR: 0:79: 'vertex-shader array-of-struct output' : not supported with this pr
 ERROR: 0:81: 'vertex-shader struct output containing an array' : not supported with this profile: es
 ERROR: 0:83: 'vertex-shader struct output containing structure' : not supported with this profile: es
 ERROR: 0:85: 'std430 on a uniform block' : not supported with this profile: es
-ERROR: 15 compilation errors.  No code generated.
+ERROR: 0:97: 's' : member of block cannot be a sampler type 
+ERROR: 0:105: 'location' : overlapping use of location 12
+ERROR: 0:107: 'in' : cannot declare an input block in a vertex shader 
+ERROR: 0:109: 'gl_PerVertex' : block redeclaration has extra members 
+ERROR: 0:119: 'gl_PointSize' : member of nameless block was not redeclared 
+ERROR: 0:119: 'assign' :  cannot convert from 'const float' to 'gl_PointSize highp void PointSize'
+ERROR: 0:122: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use 
+ERROR: 22 compilation errors.  No code generated.
 
 
 Shader version: 310
+Requested GL_OES_shader_io_blocks
 ERROR: node is still EOpNull!
 0:12  Function Definition: main( (global void)
 0:12    Function Parameters: 
@@ -166,6 +174,29 @@ ERROR: node is still EOpNull!
 0:66              2 (const int)
 0:67      Constant:
 0:67        0.000000
+0:114  Function Definition: foo_IO( (global void)
+0:114    Function Parameters: 
+0:116    Sequence
+0:116      Sequence
+0:116        move second child to first child (temp highp int)
+0:116          'sum' (temp highp int)
+0:116          add (temp highp int)
+0:116            'gl_VertexID' (gl_VertexId highp int VertexId)
+0:117            'gl_InstanceID' (gl_InstanceId highp int InstanceId)
+0:118      move second child to first child (temp highp 4-component vector of float)
+0:118        gl_Position: direct index for structure (gl_Position highp 4-component vector of float Position)
+0:118          'anon@1' (out block{gl_Position highp 4-component vector of float Position gl_Position, })
+0:118          Constant:
+0:118            0 (const uint)
+0:118        Constant:
+0:118          1.000000
+0:118          1.000000
+0:118          1.000000
+0:118          1.000000
+0:119      gl_PointSize: direct index for structure (gl_PointSize highp void PointSize)
+0:119        'anon@1' (out block{gl_Position highp 4-component vector of float Position gl_Position, })
+0:119        Constant:
+0:119          1 (const uint)
 0:?   Linker Objects
 0:?     's' (shared highp 4-component vector of float)
 0:?     'v' (buffer highp 4-component vector of float)
@@ -188,6 +219,11 @@ ERROR: node is still EOpNull!
 0:?     'outSS' (smooth out structure{global highp float f, global structure{global highp float f} s})
 0:?     'U430i' (layout(column_major std430 ) uniform block{layout(column_major std430 offset=0 ) uniform highp int a})
 0:?     'B430i' (layout(column_major std430 ) buffer block{layout(column_major std430 offset=0 ) buffer highp int a})
+0:?     'outbinst' (out block{out highp int a, out highp 4-component vector of float v, out highp sampler2D s})
+0:?     'anon@0' (out block{layout(location=12 ) out highp int aAnon, layout(location=13 ) out highp 4-component vector of float vAnon})
+0:?     'aliased' (layout(location=12 ) smooth out highp int)
+0:?     'inbinst' (in block{in highp int a})
+0:?     'anon@1' (out block{gl_Position highp 4-component vector of float Position gl_Position, })
 0:?     'gl_VertexID' (gl_VertexId highp int VertexId)
 0:?     'gl_InstanceID' (gl_InstanceId highp int InstanceId)
 
@@ -196,6 +232,7 @@ Linked vertex stage:
 
 
 Shader version: 310
+Requested GL_OES_shader_io_blocks
 ERROR: node is still EOpNull!
 0:12  Function Definition: main( (global void)
 0:12    Function Parameters: 
@@ -343,6 +380,29 @@ ERROR: node is still EOpNull!
 0:66              2 (const int)
 0:67      Constant:
 0:67        0.000000
+0:114  Function Definition: foo_IO( (global void)
+0:114    Function Parameters: 
+0:116    Sequence
+0:116      Sequence
+0:116        move second child to first child (temp highp int)
+0:116          'sum' (temp highp int)
+0:116          add (temp highp int)
+0:116            'gl_VertexID' (gl_VertexId highp int VertexId)
+0:117            'gl_InstanceID' (gl_InstanceId highp int InstanceId)
+0:118      move second child to first child (temp highp 4-component vector of float)
+0:118        gl_Position: direct index for structure (gl_Position highp 4-component vector of float Position)
+0:118          'anon@1' (out block{gl_Position highp 4-component vector of float Position gl_Position, })
+0:118          Constant:
+0:118            0 (const uint)
+0:118        Constant:
+0:118          1.000000
+0:118          1.000000
+0:118          1.000000
+0:118          1.000000
+0:119      gl_PointSize: direct index for structure (gl_PointSize highp void PointSize)
+0:119        'anon@1' (out block{gl_Position highp 4-component vector of float Position gl_Position, })
+0:119        Constant:
+0:119          1 (const uint)
 0:?   Linker Objects
 0:?     's' (shared highp 4-component vector of float)
 0:?     'v' (buffer highp 4-component vector of float)
@@ -365,6 +425,11 @@ ERROR: node is still EOpNull!
 0:?     'outSS' (smooth out structure{global highp float f, global structure{global highp float f} s})
 0:?     'U430i' (layout(column_major std430 ) uniform block{layout(column_major std430 offset=0 ) uniform highp int a})
 0:?     'B430i' (layout(column_major std430 ) buffer block{layout(column_major std430 offset=0 ) buffer highp int a})
+0:?     'outbinst' (out block{out highp int a, out highp 4-component vector of float v, out highp sampler2D s})
+0:?     'anon@0' (out block{layout(location=12 ) out highp int aAnon, layout(location=13 ) out highp 4-component vector of float vAnon})
+0:?     'aliased' (layout(location=12 ) smooth out highp int)
+0:?     'inbinst' (in block{in highp int a})
+0:?     'anon@1' (out block{gl_Position highp 4-component vector of float Position gl_Position, })
 0:?     'gl_VertexID' (gl_VertexId highp int VertexId)
 0:?     'gl_InstanceID' (gl_InstanceId highp int InstanceId)
 
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 433b84a447df700a4248587eb9dc828d3e792740..5517b55d8ee92009a3158a406c7ab5c1a8fa9d63 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -1464,10 +1464,19 @@ void TBuiltIns::initialize(int version, EProfile profile)
             stageBuiltins[EShLangVertex].append(
                 "highp int gl_VertexID;"      // needs qualifier fixed later
                 "highp int gl_InstanceID;"    // needs qualifier fixed later
-
-                "highp vec4  gl_Position;"    // needs qualifier fixed later
-                "highp float gl_PointSize;"   // needs qualifier fixed later
                 );
+            if (version < 310)
+                stageBuiltins[EShLangVertex].append(
+                    "highp vec4  gl_Position;"    // needs qualifier fixed later
+                    "highp float gl_PointSize;"   // needs qualifier fixed later
+                    );
+            else
+                stageBuiltins[EShLangVertex].append(
+                    "out gl_PerVertex {"
+                        "highp vec4  gl_Position;"    // needs qualifier fixed later
+                        "highp float gl_PointSize;"    // needs qualifier fixed later
+                    "};"
+                    );
         }
     }
 
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 711b9427e69dea5c0995eb809b73349311c4a444..b2abec6921af98ae58c12239eef852490e36f399 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -1653,8 +1653,13 @@ bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermType
         if (node->getQualifier().readonly)
             message = "can't modify a readonly buffer";
         break;
-    default:
+    case EvqFragDepth:
+        // "In addition, it is an error to statically write to gl_FragDepth in the fragment shader."
+        if (profile == EEsProfile && intermediate.getEarlyFragmentTests())
+            message = "can't modify gl_FragDepth if using early_fragment_tests";
+        break;
 
+    default:
         //
         // Type that can't be written to?
         //
@@ -2632,7 +2637,12 @@ void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TType
 //
 TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType, bool& newDeclaration)
 {
-    if (profile == EEsProfile || ! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
+    if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
+        return 0;
+
+    bool nonEsRedecls = (profile != EEsProfile && (version >= 130 || identifier == "gl_TexCoord"));
+    bool    esRedecls = (profile == EEsProfile && extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks));
+    if (! esRedecls && ! nonEsRedecls)
         return 0;
 
     // Special case when using GL_ARB_separate_shader_objects
@@ -2648,15 +2658,15 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
     // Potentially redeclaring a built-in variable...
 
     if (ssoPre150 ||
-        (identifier == "gl_FragDepth"           && version >= 420) ||
-        (identifier == "gl_FragCoord"           && version >= 150) ||
-        (identifier == "gl_ClipDistance"        && version >= 130) ||
-        (identifier == "gl_FrontColor"          && version >= 130) ||
-        (identifier == "gl_BackColor"           && version >= 130) ||
-        (identifier == "gl_FrontSecondaryColor" && version >= 130) ||
-        (identifier == "gl_BackSecondaryColor"  && version >= 130) ||
-        (identifier == "gl_SecondaryColor"      && version >= 130) ||
-        (identifier == "gl_Color"               && version >= 130 && language == EShLangFragment) ||
+        (identifier == "gl_FragDepth"           && ((nonEsRedecls && version >= 420) || esRedecls)) ||
+        (identifier == "gl_FragCoord"           && ((nonEsRedecls && version >= 150) || esRedecls)) ||
+         identifier == "gl_ClipDistance"                                                            ||
+         identifier == "gl_FrontColor"                                                              ||
+         identifier == "gl_BackColor"                                                               ||
+         identifier == "gl_FrontSecondaryColor"                                                     ||
+         identifier == "gl_BackSecondaryColor"                                                      ||
+         identifier == "gl_SecondaryColor"                                                          ||
+        (identifier == "gl_Color"               && language == EShLangFragment)                     ||
          identifier == "gl_TexCoord") {
 
         // Find the existing symbol, if any.
@@ -2715,7 +2725,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
             if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
                 qualifier.isMemory() || qualifier.isAuxiliary())
                 error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
-            if (identifier == "gl_FragCoord" && qualifier.storage != EvqVaryingIn)
+            if (qualifier.storage != EvqVaryingIn)
                 error(loc, "cannot change input storage qualification of", "redeclaration", symbol->getName().c_str());
             if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() || 
                               publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
@@ -2753,7 +2763,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
 void TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& newTypeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes)
 {
     const char* feature = "built-in block redeclaration";
-    requireProfile(loc, ~EEsProfile, feature);
+    profileRequires(loc, EEsProfile, 0, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
     profileRequires(loc, ~EEsProfile, 410, GL_ARB_separate_shader_objects, feature);
 
     if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment") {
@@ -4603,8 +4613,9 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
             switch (currentBlockQualifier.storage) {
             case EvqVaryingIn:
             case EvqVaryingOut:
-                requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile, feature);
+                requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile | EEsProfile, feature);
                 profileRequires(memberLoc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature);
+                profileRequires(memberLoc, EEsProfile, 0, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
                 memberWithLocation = true;
                 break;
             default:
@@ -4752,7 +4763,9 @@ void TParseContext::blockStageIoCheck(TSourceLoc loc, TStorageQualifier storageQ
         profileRequires(loc, ~EEsProfile, 150, GL_ARB_separate_shader_objects, "output block");
         switch (language) {
         case EShLangVertex:
-            profileRequires(loc, EEsProfile, 0, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block");
+            // ES 310 can have a block before shader_io is turned on, so skip this test for built-ins
+            if (! parsingBuiltins)
+                profileRequires(loc, EEsProfile, 0, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block");
             if (profile == EEsProfile && arraySizes)
                 arraySizeRequiredCheck(loc, arraySizes->getSize());
             break;
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index 9fc2612a078826ed13ca1cbbd7cdddb74b7c6d49..2ffd5c441c513c8980e7273d4fb22aed9747b51e 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -185,7 +185,7 @@ void TParseContext::initializeExtensionBehavior()
     extensionBehavior[GL_EXT_geometry_point_size]                  = EBhDisablePartial;
     extensionBehavior[GL_EXT_gpu_shader5]                          = EBhDisablePartial;
     extensionBehavior[GL_EXT_primitive_bounding_box]               = EBhDisablePartial;
-    extensionBehavior[GL_EXT_shader_io_blocks]                     = EBhDisablePartial;
+    extensionBehavior[GL_EXT_shader_io_blocks]                     = EBhDisable;
     extensionBehavior[GL_EXT_tessellation_shader]                  = EBhDisablePartial;
     extensionBehavior[GL_EXT_tessellation_point_size]              = EBhDisablePartial;
     extensionBehavior[GL_EXT_texture_buffer]                       = EBhDisablePartial;
@@ -195,7 +195,7 @@ void TParseContext::initializeExtensionBehavior()
     extensionBehavior[GL_OES_geometry_shader]          = EBhDisablePartial;
     extensionBehavior[GL_OES_gpu_shader5]              = EBhDisablePartial;
     extensionBehavior[GL_OES_primitive_bounding_box]   = EBhDisablePartial;
-    extensionBehavior[GL_OES_shader_io_blocks]         = EBhDisablePartial;
+    extensionBehavior[GL_OES_shader_io_blocks]         = EBhDisable;
     extensionBehavior[GL_OES_tessellation_shader]      = EBhDisablePartial;
     extensionBehavior[GL_OES_texture_buffer]           = EBhDisablePartial;
     extensionBehavior[GL_OES_texture_cube_map_array]   = EBhDisablePartial;
diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp
index 97336e94a9e474a35fc28292b80fac1f2ae6356b..7e755b4875a3423de262ebdfbb825ba9e25b8c46 100644
--- a/glslang/MachineIndependent/linkValidate.cpp
+++ b/glslang/MachineIndependent/linkValidate.cpp
@@ -715,7 +715,9 @@ int TIntermediate::computeTypeLocationSize(const TType& type) const
         return size;
     }
 
-    // "If a vertex shader input is any scalar or vector type, it will consume a single location. If a non-vertex 
+    // ES: "If a shader input is any scalar or vector type, it will consume a single location."
+
+    // Desktop: "If a vertex shader input is any scalar or vector type, it will consume a single location. If a non-vertex 
     // shader input is a scalar or vector type other than dvec3 or dvec4, it will consume a single location, while 
     // types dvec3 or dvec4 will consume two consecutive locations. Inputs of type double and dvec2 will 
     // consume only a single location, in all stages."