diff --git a/Test/130.frag b/Test/130.frag
index 7c6307508f8b5ee2e22331143b4f3544494abb5b..fd81bbfd219fd13d80c236cb2e62baa03f7c4fad 100644
--- a/Test/130.frag
+++ b/Test/130.frag
@@ -131,3 +131,10 @@ void bar23444()
     const float b = 2 * a1;
     a.x = gl_MinProgramTexelOffset + gl_MaxProgramTexelOffset;    // ERROR until shading_language_420pack is fully implemented
 }
+
+in float gl_FogFragCoord;
+
+#extension GL_ARB_separate_shader_objects : enable
+
+in float gl_FogFragCoord;
+in int gl_FogFragCoord;
diff --git a/Test/140.vert b/Test/140.vert
index 627300043836ed72e4ed25fb11e27fc2de4bebe7..6e162bec9e98de09110f8e68bc3405257eaaabb6 100644
--- a/Test/140.vert
+++ b/Test/140.vert
@@ -19,3 +19,15 @@ void main()
     gl_FogFragCoord;    // could be ERROR, but compiling under compatibility profile
     gl_FrontColor;      // could be ERROR, but compiling under compatibility profile
 }
+
+out vec4 gl_Position;  // ERROR
+
+#extension GL_ARB_separate_shader_objects : enable
+
+out vec4 gl_Position;
+in vec4 gl_Position;   // ERROR
+out vec3 gl_Position;  // ERROR
+
+out float gl_PointSize;
+out vec4 gl_ClipVertex;
+out float gl_FogFragCoord;
diff --git a/Test/baseResults/130.frag.out b/Test/baseResults/130.frag.out
index 8e0748887941b9d269f596067a8f580067d5843d..8ab00fd94af76c619a4b0ea4a174809fccde3392 100644
--- a/Test/baseResults/130.frag.out
+++ b/Test/baseResults/130.frag.out
@@ -20,11 +20,15 @@ ERROR: 0:130: 'm43' : can't use function syntax on variable
 ERROR: 0:130: '=' :  cannot convert from 'const float' to 'int'
 ERROR: 0:132: 'gl_MinProgramTexelOffset' : undeclared identifier 
 ERROR: 0:132: 'gl_MaxProgramTexelOffset' : undeclared identifier 
-ERROR: 18 compilation errors.  No code generated.
+ERROR: 0:135: 'gl_FogFragCoord' : identifiers starting with "gl_" are reserved 
+ERROR: 0:140: 'int' : must be qualified as flat in
+ERROR: 0:140: 'redeclaration' : cannot change the type of gl_FogFragCoord
+ERROR: 21 compilation errors.  No code generated.
 
 
 Shader version: 130
 Requested GL_ARB_gpu_shader5
+Requested GL_ARB_separate_shader_objects
 Requested GL_ARB_shading_language_420pack
 Requested GL_ARB_texture_cube_map_array
 Requested GL_ARB_texture_gather
@@ -351,6 +355,7 @@ ERROR: node is still EOpNull!
 0:?       32 (const int)
 0:?     'instanceName' (layout(binding=0 column_major shared ) uniform block{layout(column_major shared ) uniform int a})
 0:?     'bounds' (layout(binding=0 ) uniform sampler2D)
+0:?     'gl_FogFragCoord' (smooth in float)
 
 
 Linked fragment stage:
@@ -358,6 +363,7 @@ Linked fragment stage:
 
 Shader version: 130
 Requested GL_ARB_gpu_shader5
+Requested GL_ARB_separate_shader_objects
 Requested GL_ARB_shading_language_420pack
 Requested GL_ARB_texture_cube_map_array
 Requested GL_ARB_texture_gather
@@ -684,4 +690,5 @@ ERROR: node is still EOpNull!
 0:?       32 (const int)
 0:?     'instanceName' (layout(binding=0 column_major shared ) uniform block{layout(column_major shared ) uniform int a})
 0:?     'bounds' (layout(binding=0 ) uniform sampler2D)
+0:?     'gl_FogFragCoord' (smooth in float)
 
diff --git a/Test/baseResults/140.vert.out b/Test/baseResults/140.vert.out
index 2dc2ff60d9a18029f88203ce2dc2cda42ea12d98..61f6af88905e7543d32dc41b1d1e460e6dae7de3 100644
--- a/Test/baseResults/140.vert.out
+++ b/Test/baseResults/140.vert.out
@@ -1,7 +1,16 @@
 140.vert
+ERROR: 0:23: 'gl_Position' : identifiers starting with "gl_" are reserved 
+ERROR: 0:28: 'redeclaration' : cannot change storage, memory, or auxiliary qualification of gl_Position
+ERROR: 0:28: 'redeclaration' : cannot change interpolation qualification of gl_Position
+ERROR: 0:29: 'redeclaration' : cannot change the type of gl_Position
+ERROR: 0:32: 'gl_ClipVertex' : cannot redeclare after use 
+ERROR: 0:33: 'gl_FogFragCoord' : cannot redeclare after use 
+ERROR: 6 compilation errors.  No code generated.
+
 
 Shader version: 140
-0:? Sequence
+Requested GL_ARB_separate_shader_objects
+ERROR: node is still EOpNull!
 0:9  Function Definition: main( (void)
 0:9    Function Parameters: 
 0:11    Sequence
@@ -41,6 +50,13 @@ Shader version: 140
 0:?     'sbuf' (uniform isamplerBuffer)
 0:?     'anon@0' (layout(column_major std140 ) uniform block{layout(column_major std140 offset=0 ) uniform int anonMem})
 0:?     'gl_TexCoord' (smooth out implicitly-sized array of 4-component vector of float)
+0:?     'gl_Position' (smooth out 4-component vector of float)
+0:?     'gl_PointSize' (gl_PointSize float)
+0:?     'gl_PointSize' (gl_PointSize float)
+0:?     'gl_ClipVertex' (gl_ClipVertex 4-component vector of float)
+0:?     'gl_ClipVertex' (gl_ClipVertex 4-component vector of float)
+0:?     'gl_FogFragCoord' (smooth out float)
+0:?     'gl_FogFragCoord' (smooth out float)
 0:?     'gl_VertexID' (gl_VertexId int)
 0:?     'gl_InstanceID' (gl_InstanceId int)
 
@@ -49,7 +65,8 @@ Linked vertex stage:
 
 
 Shader version: 140
-0:? Sequence
+Requested GL_ARB_separate_shader_objects
+ERROR: node is still EOpNull!
 0:9  Function Definition: main( (void)
 0:9    Function Parameters: 
 0:11    Sequence
@@ -89,6 +106,13 @@ Shader version: 140
 0:?     'sbuf' (uniform isamplerBuffer)
 0:?     'anon@0' (layout(column_major std140 ) uniform block{layout(column_major std140 offset=0 ) uniform int anonMem})
 0:?     'gl_TexCoord' (smooth out 1-element array of 4-component vector of float)
+0:?     'gl_Position' (smooth out 4-component vector of float)
+0:?     'gl_PointSize' (gl_PointSize float)
+0:?     'gl_PointSize' (gl_PointSize float)
+0:?     'gl_ClipVertex' (gl_ClipVertex 4-component vector of float)
+0:?     'gl_ClipVertex' (gl_ClipVertex 4-component vector of float)
+0:?     'gl_FogFragCoord' (smooth out float)
+0:?     'gl_FogFragCoord' (smooth out float)
 0:?     'gl_VertexID' (gl_VertexId int)
 0:?     'gl_InstanceID' (gl_InstanceId int)
 
diff --git a/Todo.txt b/Todo.txt
index bd0cb6fd72d311bbad4c4ab8afe36fc31af57c16..125a8e527f8b9a63ecf6b2a38934ba6ded0eb2b9 100644
--- a/Todo.txt
+++ b/Todo.txt
@@ -146,9 +146,9 @@ Shader Functionality to Implement/Finish
     GLSL 4.1
       + Support for partitioning shaders into multiple programs to provide light-weight mixing of different shader stages.
             (GL_ARB_separate_shader_objects)
-        - layout qualifiers
-        - redeclaration of input/output blocks
-        - ...
+        + layout qualifiers
+        + redeclaration of input/output blocks
+        + ...
       - Add 64-bit floating-point attributes for vertex shader inputs.
       + Support viewport arrays so where the geometry shader selects which viewport array will transform its output.
     GLSL 4.2
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 070eb354589754665bf92272aa16f304523336f8..3e44dd2acd55c6b1f6e17ba9b4b60d9b192ea631 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -2348,9 +2348,20 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
     if (profile == EEsProfile || ! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
         return 0;
 
+    // Special case when using GL_ARB_separate_shader_objects
+    bool ssoPre150 = false;  // means the only reason this variable is redeclared is due to this combination
+    if (version <= 140 && extensionsTurnedOn(1, &GL_ARB_separate_shader_objects)) {
+        if (identifier == "gl_Position"     ||
+            identifier == "gl_PointSize"    ||
+            identifier == "gl_ClipVertex"   ||
+            identifier == "gl_FogFragCoord")
+            ssoPre150 = true;
+    }
+
     // Potentially redeclaring a built-in variable...
 
-    if ((identifier == "gl_FragDepth"           && version >= 420) ||
+    if (ssoPre150 ||
+        (identifier == "gl_FragDepth"           && version >= 420) ||
         (identifier == "gl_FragCoord"           && version >= 150) ||
         (identifier == "gl_ClipDistance"        && version >= 130) ||
         (identifier == "gl_FrontColor"          && version >= 130) ||
@@ -2382,12 +2393,22 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
         // Now, modify the type of the copy, as per the type of the current redeclaration.
 
         TQualifier& symbolQualifier = symbol->getWritableType().getQualifier();
-        if (identifier == "gl_FrontColor"          ||
-            identifier == "gl_BackColor"           ||
-            identifier == "gl_FrontSecondaryColor" ||
-            identifier == "gl_BackSecondaryColor"  ||
-            identifier == "gl_SecondaryColor"      ||
-            identifier == "gl_Color") {
+        if (ssoPre150) {            
+            if (intermediate.inIoAccessed(identifier))
+                error(loc, "cannot redeclare after use", identifier.c_str(), "");
+            if (qualifier.hasLayout())
+                error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
+            if (qualifier.isMemory() || qualifier.isAuxiliary() || (language == EShLangVertex   && qualifier.storage != EvqVaryingOut) ||
+                                                                   (language == EShLangFragment && qualifier.storage != EvqVaryingIn))
+                error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
+            if (! qualifier.smooth)
+                error(loc, "cannot change interpolation qualification of", "redeclaration", symbol->getName().c_str());
+        } else if (identifier == "gl_FrontColor"          ||
+                   identifier == "gl_BackColor"           ||
+                   identifier == "gl_FrontSecondaryColor" ||
+                   identifier == "gl_BackSecondaryColor"  ||
+                   identifier == "gl_SecondaryColor"      ||
+                   identifier == "gl_Color") {
             symbolQualifier.flat = qualifier.flat;
             symbolQualifier.smooth = qualifier.smooth;
             symbolQualifier.nopersp = qualifier.nopersp;