diff --git a/Test/300.frag b/Test/300.frag
index dea0c4e72ddbe18acfd9e461240b27d1ab7a914e..8b67b981d71785e7c8edda8e5f4a5eeaf9443d84 100644
--- a/Test/300.frag
+++ b/Test/300.frag
@@ -145,5 +145,7 @@ void foo324(void)
     mat3x2 m32 = outerProduct(vec2(2,3), vec3(5,7,11));// rows: (10, 14, 22), (15, 21, 33)
 }
 
+uniform mediump;       // ERROR
+
 float imageBuffer;    // ERROR, reserved
 float uimage2DRect;   // ERROR, reserved
diff --git a/Test/300layout.vert b/Test/300layout.vert
index b5e1dbee6514c1fbdeed7eefaffbc23f45ea213d..06d1206dc188de0145802570cfffccc15df84baa 100644
--- a/Test/300layout.vert
+++ b/Test/300layout.vert
@@ -51,7 +51,7 @@ shared vec4 compute_only;  // ERROR
 
 layout(packed) uniform;
 
-layout(packed) float aoeuntaoeu;  // ERROR, packed on variable
+layout(packed) uniform float aoeuntaoeu;  // ERROR, packed on variable
 
 layout(location = 40) in float cd;
 layout(location = 37) in mat4x3 ce; // ERROR, overlap
diff --git a/Test/440.frag b/Test/440.frag
index 23c43b476ea2e604dd4fb70252a55bfac7db5425..22d46f56b8859aa6ad31d608ab4419f9c7a78922 100644
--- a/Test/440.frag
+++ b/Test/440.frag
@@ -20,3 +20,72 @@ layout(location = 20, component = 3) in float f[6];
 
 layout(location = 30, component = 3) out int be;
 layout(location = 30, component = 0) out vec3 bf;  // ERROR, not the same basic type
+
+writeonly uniform;          // ERROR
+readonly in;                // ERROR
+flat out;                   // ERROR
+mediump uniform;
+
+layout(offset=12) uniform;  // ERROR
+layout(offset=12) in;       // ERROR
+layout(offset=12) out;      // ERROR
+
+layout(align=16) uniform;   // ERROR
+layout(align=16) in;        // ERROR
+layout(align=16) out;       // ERROR
+
+layout(offset=12) uniform  ubl1 { int a; } inst1;  // ERROR
+layout(offset=12)      in inbl2 { int a; } inst2;  // ERROR
+layout(offset=12)     out inbl3 { int a; } inst3;  // ERROR
+
+layout(align=16, std140) uniform  ubl4 { int a; } inst4;
+layout(align=16) uniform  ubl8 { int a; } inst8;  // ERROR, no packing
+layout(align=16)      in inbl5 { int a; } inst5;  // ERROR
+layout(align=16)     out inbl6 { int a; } inst6;  // ERROR
+
+layout(offset=12) uniform vec4 v1;  // ERROR
+layout(offset=12)      in vec4 v2;  // ERROR
+layout(offset=12)     out vec4 v3;  // ERROR
+
+layout(align=16) uniform vec4 v4;   // ERROR
+layout(align=16)      in vec4 v5;   // ERROR
+layout(align=16)     out vec4 v6;   // ERROR
+
+layout(std140) in;                  // ERROR
+layout(std140) uniform vec4 v7;     // ERROR
+
+layout(align=48) uniform ubl7 {          // ERROR, not power of 2
+    layout(offset=12, align=4) float f;  // ERROR, no packing
+} inst7;
+
+in ibl10 {
+    layout(offset=12) float f;  // ERROR
+    layout(align=4) float g;    // ERROR
+} inst10;
+
+layout(std430) uniform;
+
+layout(align=32) uniform ubl9 {
+    float e;
+    layout(offset=12, align=4) float f;
+    layout(offset=20) float g;
+    float h;
+} inst9;
+
+uniform ubl11 {
+    layout(offset=12, align=4) float f;
+    float g;
+} inst11;
+
+layout(std140) uniform block {
+                        vec4   a;     // a takes offsets 0-15
+    layout(offset = 20) vec3   b;     // b takes offsets 32-43
+    layout(offset = 40) vec2   c;     // ERROR, lies within previous member
+    layout(offset = 48) vec2   d;     // d takes offsets 48-55
+    layout(align = 16)  float  e;     // e takes offsets 64-67
+    layout(align = 2)   double f;     // f takes offsets 72-79
+    layout(align = 6)   double g;     // ERROR, 6 is not a power of 2
+    layout(offset = 80) float  h;     // h takes offsets 80-83
+    layout(align = 64)  dvec3  i;     // i takes offsets 128-151
+    layout(offset = 153, align = 8) float  j;     // j takes offsets 160-163
+} specExample;
diff --git a/Test/baseResults/300.frag.out b/Test/baseResults/300.frag.out
index f1f80a8fd1b2fa17f85b51ac7f6a7f826551ba96..f9124a02b4c71e5d10b1fc7212ccdc7d15ec7f3f 100644
--- a/Test/baseResults/300.frag.out
+++ b/Test/baseResults/300.frag.out
@@ -33,9 +33,10 @@ ERROR: 0:122: '=' : can't use with samplers or structs containing samplers
 ERROR: 0:123: '==' : can't use with samplers or structs containing samplers 
 ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
 ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
-ERROR: 0:148: 'imageBuffer' : Reserved word. 
-ERROR: 0:148: '' :  syntax error
-ERROR: 36 compilation errors.  No code generated.
+ERROR: 0:148: 'qualifier' : cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type) 
+ERROR: 0:150: 'imageBuffer' : Reserved word. 
+ERROR: 0:150: '' :  syntax error
+ERROR: 37 compilation errors.  No code generated.
 
 
 ERROR: node is still EOpNull!
diff --git a/Test/baseResults/300layout.vert.out b/Test/baseResults/300layout.vert.out
index 4ce58fa083cd3321c3d682aa785ea2f6edba297b..0ce4b3c798a5a936b4a5a66153c3747e550edd93 100644
--- a/Test/baseResults/300layout.vert.out
+++ b/Test/baseResults/300layout.vert.out
@@ -15,7 +15,7 @@ ERROR: 0:38: 'output block' : not supported with this profile: es
 ERROR: 0:42: 'location qualifier on output' : not supported in this stage: vertex
 ERROR: 0:50: 'shared' : not supported with this profile: es
 ERROR: 0:50: 'shared' : not supported in this stage: vertex
-ERROR: 0:54: 'layout' : qualifiers for matrix layout and block packing only apply to uniform or buffer blocks 
+ERROR: 0:54: 'layout' : cannot specify packing on a variable declaration 
 ERROR: 0:57: 'location' : overlapping use of location 40
 ERROR: 18 compilation errors.  No code generated.
 
@@ -73,7 +73,7 @@ ERROR: node is still EOpNull!
 0:?     '__anon__2' (out block{out highp float f})
 0:?     'badoutA' (layout(location=10 ) smooth out highp 4-component vector of float)
 0:?     'compute_only' (shared highp 4-component vector of float)
-0:?     'aoeuntaoeu' (layout(packed ) highp float)
+0:?     'aoeuntaoeu' (layout(packed ) uniform highp float)
 0:?     'cd' (layout(location=40 ) in highp float)
 0:?     'ce' (layout(location=37 ) in highp 4X3 matrix of float)
 0:?     'gl_VertexID' (gl_VertexId highp int)
diff --git a/Test/baseResults/440.frag.out b/Test/baseResults/440.frag.out
index 771715ff25b3ae4934b9e816d430f35345762627..b81870cb14a20be134d1db45ec38402f47428456 100644
--- a/Test/baseResults/440.frag.out
+++ b/Test/baseResults/440.frag.out
@@ -3,7 +3,44 @@ Warning, version 440 is not yet complete; some version-specific features are pre
 ERROR: 0:11: 'location' : overlapping use of location 4
 ERROR: 0:13: 'component' : type overflows the available 4 components 
 ERROR: 0:22: 'location' : fragment outputs sharing the same location must be the same basic type 30
-ERROR: 3 compilation errors.  No code generated.
+ERROR: 0:24: 'qualifier' : cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type) 
+ERROR: 0:25: 'qualifier' : cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type) 
+ERROR: 0:26: 'qualifier' : cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type) 
+ERROR: 0:29: 'layout qualifier' : cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type) 
+ERROR: 0:30: 'layout qualifier' : cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type) 
+ERROR: 0:30: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:31: 'layout qualifier' : cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type) 
+ERROR: 0:31: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:33: 'layout qualifier' : cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type) 
+ERROR: 0:34: 'layout qualifier' : cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type) 
+ERROR: 0:34: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:35: 'layout qualifier' : cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type) 
+ERROR: 0:35: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:37: 'offset' : only applies to block members, not blocks 
+ERROR: 0:38: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:38: 'offset' : only applies to block members, not blocks 
+ERROR: 0:39: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:39: 'offset' : only applies to block members, not blocks 
+ERROR: 0:42: 'offset/align' : can only be used with std140 or std430 layout packing 
+ERROR: 0:43: 'offset/align' : can only be used with std140 or std430 layout packing 
+ERROR: 0:43: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:44: 'offset/align' : can only be used with std140 or std430 layout packing 
+ERROR: 0:44: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:46: 'offset' : cannot specify on a variable declaration 
+ERROR: 0:47: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:48: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:50: 'align' : cannot specify on a variable declaration 
+ERROR: 0:51: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:52: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:54: 'layout' : matrix or packing qualifiers can only be used on a uniform or buffer 
+ERROR: 0:55: 'layout' : cannot specify packing on a variable declaration 
+ERROR: 0:57: 'align' : must be a power of 2 
+ERROR: 0:58: 'align' : can only be used with std140 or std430 layout packing 
+ERROR: 0:63: 'align' : can only be used with std140 or std430 layout packing 
+ERROR: 0:62: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:63: 'layout' : offset/align can only be used on a uniform or buffer 
+ERROR: 0:87: 'align' : must be a power of 2 
+ERROR: 40 compilation errors.  No code generated.
 
 
 ERROR: node is still EOpNull!
@@ -16,6 +53,25 @@ ERROR: node is still EOpNull!
 0:?     'f' (layout(location=20 component=3 ) smooth in 6-element array of float)
 0:?     'be' (layout(location=30 component=3 ) out int)
 0:?     'bf' (layout(location=30 component=0 ) out 3-component vector of float)
+0:?     'inst1' (layout(column_major shared offset=12 ) uniform block{layout(column_major shared ) uniform int a})
+0:?     'inst2' (layout(offset=12 ) in block{in int a})
+0:?     'inst3' (layout(offset=12 ) out block{out int a})
+0:?     'inst4' (layout(column_major std140 align=16 ) uniform block{layout(column_major std140 align=16 ) uniform int a})
+0:?     'inst8' (layout(column_major shared align=16 ) uniform block{layout(column_major shared ) uniform int a})
+0:?     'inst5' (layout(align=16 ) in block{in int a})
+0:?     'inst6' (layout(align=16 ) out block{out int a})
+0:?     'v1' (layout(offset=12 ) uniform 4-component vector of float)
+0:?     'v2' (layout(offset=12 ) smooth in 4-component vector of float)
+0:?     'v3' (layout(offset=12 ) out 4-component vector of float)
+0:?     'v4' (layout(align=16 ) uniform 4-component vector of float)
+0:?     'v5' (layout(align=16 ) smooth in 4-component vector of float)
+0:?     'v6' (layout(align=16 ) out 4-component vector of float)
+0:?     'v7' (layout(std140 ) uniform 4-component vector of float)
+0:?     'inst7' (layout(column_major shared ) uniform block{layout(column_major shared offset=12 align=4 ) uniform float f})
+0:?     'inst10' (in block{layout(offset=12 ) in float f, layout(align=4 ) in float g})
+0:?     'inst9' (layout(column_major std430 align=32 ) uniform block{layout(column_major std430 align=32 ) uniform float e, layout(column_major std430 offset=12 align=4 ) uniform float f, layout(column_major std430 offset=20 align=32 ) uniform float g, layout(column_major std430 align=32 ) uniform float h})
+0:?     'inst11' (layout(column_major std430 ) uniform block{layout(column_major std430 offset=12 align=4 ) uniform float f, layout(column_major std430 ) uniform float g})
+0:?     'specExample' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float a, layout(column_major std140 offset=20 ) uniform 3-component vector of float b, layout(column_major std140 offset=40 ) uniform 2-component vector of float c, layout(column_major std140 offset=48 ) uniform 2-component vector of float d, layout(column_major std140 align=16 ) uniform float e, layout(column_major std140 align=2 ) uniform double f, layout(column_major std140 ) uniform double g, layout(column_major std140 offset=80 ) uniform float h, layout(column_major std140 align=64 ) uniform 3-component vector of double i, layout(column_major std140 offset=153 align=8 ) uniform float j})
 
 
 Linked fragment stage:
diff --git a/Test/baseResults/specExamples.vert.out b/Test/baseResults/specExamples.vert.out
index c9ce1621493b2d83b3b8a6157277d8a516cd6a3b..b69695a9c5fe2d36f2685daf0c3bd4bee98a12a7 100644
--- a/Test/baseResults/specExamples.vert.out
+++ b/Test/baseResults/specExamples.vert.out
@@ -19,6 +19,7 @@ ERROR: 0:55: 'stream' : there is no such layout identifier for this stage taking
 ERROR: 0:80: 's17' : redefinition 
 ERROR: 0:85: 'uniform buffer-member offset' : not supported for this version or the enabled extensions 
 ERROR: 0:85: 'binding' : requires block, or sampler/image, or atomic-counter type 
+ERROR: 0:85: 'offset' : cannot specify on a variable declaration 
 ERROR: 0:87: 'binding' : requires block, or sampler/image, or atomic-counter type 
 ERROR: 0:89: 'uniform buffer-member offset' : not supported for this version or the enabled extensions 
 WARNING: 0:89: 'layout' : useless application of layout qualifier 
@@ -42,7 +43,7 @@ ERROR: 0:153: '' : function does not return a value: func3
 ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array 
 ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array 
 ERROR: 0:194: 'constructor' : constructing from a non-dereferenced array 
-ERROR: 41 compilation errors.  No code generated.
+ERROR: 42 compilation errors.  No code generated.
 
 
 ERROR: node is still EOpNull!
diff --git a/glslang/Include/Common.h b/glslang/Include/Common.h
index e4c14ff56b636129c120b5ea44e8f8b3d3cc23b3..305b534d46c38a6450659ca8efa008253e263ec8 100644
--- a/glslang/Include/Common.h
+++ b/glslang/Include/Common.h
@@ -186,17 +186,22 @@ typedef TMap<TString, TString>::tAllocator TPragmaTableAllocator;
 
 const int GlslangMaxTokenLength = 1024;
 
+template <class T> bool IsPow2(T powerOf2)
+{
+    return (powerOf2 & (powerOf2 - 1)) == 0;
+}
+
 // Round number up to a multiple of the given powerOf2, which is not
 // a power, just a number that must be a power of 2.
 template <class T> void RoundToPow2(T& number, int powerOf2)
 {
-    assert((powerOf2 & (powerOf2 - 1)) == 0);
+    assert(IsPow2(powerOf2));
     number = (number + powerOf2 - 1) & ~(powerOf2 - 1);
 }
 
 template <class T> bool IsMultipleOfPow2(T number, int powerOf2)
 {
-    assert((powerOf2 & (powerOf2 - 1)) == 0);
+    assert(IsPow2(powerOf2));
     return ! (number & (powerOf2 - 1));
 }
 
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index 08ffd990e34410bba10291775088e1dc71517e3d..a7435d00cf1ce5f3bf9640faa60833a9ea57676b 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -401,10 +401,26 @@ public:
 
     bool hasUniformLayout() const
     {
-        return layoutMatrix  != ElmNone ||
-               layoutPacking != ElpNone ||
-               layoutOffset  != -1 ||
-               layoutAlign   != -1;
+        return hasMatrix() ||
+               hasPacking() ||
+               hasOffset() ||
+               hasAlign();
+    }
+    bool hasMatrix() const
+    {
+        return layoutMatrix != ElmNone;
+    }
+    bool hasPacking() const
+    {
+        return layoutPacking != ElpNone;
+    }
+    bool hasOffset() const
+    {
+        return layoutOffset != -1;
+    }
+    bool hasAlign() const
+    {
+        return layoutAlign != -1;
     }
     bool hasLocation() const
     {
@@ -904,13 +920,13 @@ public:
                     p += snprintf(p, end - p, "binding=%d ", qualifier.layoutBinding);
                 if (qualifier.hasStream())
                     p += snprintf(p, end - p, "stream=%d ", qualifier.layoutStream);
-                if (qualifier.layoutMatrix != ElmNone)
+                if (qualifier.hasMatrix())
                     p += snprintf(p, end - p, "%s ", TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
-                if (qualifier.layoutPacking != ElpNone)
+                if (qualifier.hasPacking())
                     p += snprintf(p, end - p, "%s ", TQualifier::getLayoutPackingString(qualifier.layoutPacking));
-                if (qualifier.layoutOffset != -1)
+                if (qualifier.hasOffset())
                     p += snprintf(p, end - p, "offset=%d ", qualifier.layoutOffset);
-                if (qualifier.layoutAlign != -1)
+                if (qualifier.hasAlign())
                     p += snprintf(p, end - p, "align=%d ", qualifier.layoutAlign);
 
                 if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset())
diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h
index 2b295b5a6fce492011138d266801cd0fb58893ab..1a2b8fe554288dbbc34000607794dd6623918b80 100644
--- a/glslang/Include/revision.h
+++ b/glslang/Include/revision.h
@@ -9,5 +9,5 @@
 // source have to figure out how to create revision.h just to get a build
 // going.  However, if it is not updated, it can be a version behind.
 
-#define GLSLANG_REVISION "25018"
-#define GLSLANG_DATE     "2014/01/26 00:56:43"
+#define GLSLANG_REVISION "25043"
+#define GLSLANG_DATE     "2014/01/27 13:02:12"
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 911da93bc90d12b8c636fda5e264665ba82703d8..34699c543cf882ba57d5d7eab47681775eecd093 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -2852,7 +2852,11 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
         const char* feature = "uniform buffer-member align";
         requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
         profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, feature);
-        publicType.qualifier.layoutAlign = value;
+        // "The specified alignment must be a power of 2, or a compile-time error results."
+        if (! IsPow2(value))
+            error(loc, "must be a power of 2", "align", "");
+        else
+            publicType.qualifier.layoutAlign = value;
         return;
     } else if (id == "location") {
         requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "location");
@@ -2965,9 +2969,9 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
 // Merge any layout qualifier information from src into dst, leaving everything else in dst alone
 void TParseContext::mergeObjectLayoutQualifiers(TSourceLoc loc, TQualifier& dst, const TQualifier& src, bool inheritOnly)
 {
-    if (src.layoutMatrix != ElmNone)
+    if (src.hasMatrix())
         dst.layoutMatrix = src.layoutMatrix;
-    if (src.layoutPacking != ElpNone)
+    if (src.hasPacking())
         dst.layoutPacking = src.layoutPacking;
 
     if (src.hasStream())
@@ -2976,16 +2980,17 @@ void TParseContext::mergeObjectLayoutQualifiers(TSourceLoc loc, TQualifier& dst,
     if (src.hasXfbBuffer())
         dst.layoutXfbBuffer = src.layoutXfbBuffer;
 
+    if (src.hasAlign())
+        dst.layoutAlign = src.layoutAlign;
+
     if (! inheritOnly) {
         if (src.layoutLocation != TQualifier::layoutLocationEnd)
             dst.layoutLocation = src.layoutLocation;
         if (src.layoutComponent != TQualifier::layoutComponentEnd)
             dst.layoutComponent = src.layoutComponent;
         
-        if (src.layoutOffset != -1)
+        if (src.hasOffset())
             dst.layoutOffset = src.layoutOffset;
-        if (src.layoutAlign != -1)
-            dst.layoutAlign = src.layoutAlign;
 
         if (src.layoutBinding != TQualifier::layoutBindingEnd)
             dst.layoutBinding = src.layoutBinding;
@@ -3021,24 +3026,26 @@ void TParseContext::layoutObjectCheck(TSourceLoc loc, const TSymbol& symbol)
     }
 
     // Check packing and matrix 
-    // TODO: 4.4 enhanced layouts: generalize to include offset/align
-    if (qualifier.layoutMatrix || qualifier.layoutPacking) {
+    if (qualifier.hasUniformLayout()) {
         switch (qualifier.storage) {
         case EvqBuffer:
         case EvqUniform:
             if (type.getBasicType() != EbtBlock) {
-                if (qualifier.layoutMatrix != ElmNone)
+                if (qualifier.hasMatrix())
                     error(loc, "cannot specify matrix layout on a variable declaration", "layout", "");
-                if (qualifier.layoutPacking != ElpNone)
+                if (qualifier.hasPacking())
                     error(loc, "cannot specify packing on a variable declaration", "layout", "");
+                // "The offset qualifier can only be used on block members of blocks..."
+                if (qualifier.hasOffset())
+                    error(loc, "cannot specify on a variable declaration", "offset", "");
+                // "The align qualifier can only be used on blocks or block members..."
+                if (qualifier.hasAlign())
+                    error(loc, "cannot specify on a variable declaration", "align", "");
             }
             break;
         default:
-            if (type.getBasicType() != EbtBlock && symbol.getAsVariable()) {
-                if (qualifier.layoutMatrix != ElmNone ||
-                    qualifier.layoutPacking != ElpNone)
-                    error(loc, "qualifiers for matrix layout and block packing only apply to uniform or buffer blocks", "layout", "");
-            }
+            // these were already filtered by layoutTypeCheck() (or its callees)
+            break;
         }
     }
 }
@@ -3127,6 +3134,12 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type)
                 error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : "");
         }
     }
+
+    // "The offset qualifier can only be used on block members of blocks..."                
+    if (qualifier.hasOffset()) {
+        if (type.getBasicType() == EbtBlock)
+            error(loc, "only applies to block members, not blocks", "offset", "");        
+    }
 }
 
 // Do layout error checking that can be done within a qualifier proper, not needing to know
@@ -3185,7 +3198,6 @@ void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& quali
         if (qualifier.storage != EvqUniform && qualifier.storage != EvqBuffer)
             error(loc, "requires uniform or buffer storage qualifier", "binding", "");
     }
-
     if (qualifier.hasStream()) {
         if (qualifier.storage != EvqVaryingOut)
             error(loc, "can only be used on an output", "stream", "");
@@ -3194,6 +3206,14 @@ void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& quali
         if (qualifier.storage != EvqVaryingOut)
             error(loc, "can only be used on an output", "xfb layout qualifier", "");
     }
+    if (qualifier.hasUniformLayout()) {
+        if (! (qualifier.storage == EvqUniform || qualifier.storage == EvqBuffer)) {
+            if (qualifier.hasMatrix() || qualifier.hasPacking())
+                error(loc, "matrix or packing qualifiers can only be used on a uniform or buffer", "layout", "");
+            if (qualifier.hasOffset() || qualifier.hasAlign())
+                error(loc, "offset/align can only be used on a uniform or buffer", "layout", "");
+        }
+    }
 }
 
 // For places that can't have shader-level layout qualifiers
@@ -3871,8 +3891,18 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
     }
 
     // fix and check for member layout qualifiers
-    // TODO: 4.4 enhanced layouts: generalize to include offset/align
+
     mergeObjectLayoutQualifiers(loc, defaultQualification, currentBlockQualifier, true);
+
+    // "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
+    // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
+    if (currentBlockQualifier.hasAlign() || currentBlockQualifier.hasAlign()) {
+        if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) {
+            error(loc, "can only be used with std140 or std430 layout packing", "offset/align", "");
+            defaultQualification.layoutAlign = -1;
+        }
+    }
+
     bool memberWithLocation = false;
     bool memberWithoutLocation = false;
     for (unsigned int member = 0; member < typeList.size(); ++member) {
@@ -3892,7 +3922,7 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
                 error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", "");
         }
 
-        if (memberQualifier.layoutPacking != ElpNone)
+        if (memberQualifier.hasPacking())
             error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), "");
         if (memberQualifier.hasLocation()) {
             const char* feature = "location on block member";
@@ -3909,6 +3939,11 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
             }
         } else
             memberWithoutLocation = true;
+        if (memberQualifier.hasAlign()) {
+            if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430)
+                error(memberLoc, "can only be used with std140 or std430 layout packing", "align", "");
+        }
+
         TQualifier newMemberQualification = defaultQualification;
         mergeQualifiers(memberLoc, newMemberQualification, memberQualifier, false);
         memberQualifier = newMemberQualification;
@@ -3917,6 +3952,7 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
     // Process the members
     fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
     fixBlockXfbOffsets(loc, currentBlockQualifier, typeList);
+    fixBlockUniformOffsets(loc, currentBlockQualifier, typeList);
     for (unsigned int member = 0; member < typeList.size(); ++member)
         layoutTypeCheck(typeList[member].loc, *typeList[member].type);
 
@@ -4037,10 +4073,10 @@ void TParseContext::fixBlockXfbOffsets(TSourceLoc loc, TQualifier& qualifier, TT
     // members of that block not qualified with an xfb_offsetwill not be assigned transform feedback buffer 
     // offsets."
 
-    if (! currentBlockQualifier.hasXfbBuffer() || ! currentBlockQualifier.hasXfbOffset())
+    if (! qualifier.hasXfbBuffer() || ! qualifier.hasXfbOffset())
         return;
 
-    int nextOffset = currentBlockQualifier.layoutXfbOffset;
+    int nextOffset = qualifier.layoutXfbOffset;
     for (unsigned int member = 0; member < typeList.size(); ++member) {
         TQualifier& memberQualifier = typeList[member].type->getQualifier();
         bool containsDouble = false;
@@ -4061,6 +4097,12 @@ void TParseContext::fixBlockXfbOffsets(TSourceLoc loc, TQualifier& qualifier, TT
     qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd;
 }
 
+void TParseContext::fixBlockUniformOffsets(TSourceLoc loc, TQualifier& qualifier, TTypeList& typeList)
+{
+    if (qualifier.storage != EvqUniform || qualifier.storage != EvqBuffer)
+        return;
+}
+
 // For an identifier that is already declared, add more qualification to it.
 void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, const TString& identifier)
 {
@@ -4203,22 +4245,26 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub
         qualifier.isMemory() ||
         qualifier.isInterpolation() ||
         qualifier.precision != EpqNone)
-        error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "", "");
+        error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "qualifier", "");
+    // "The offset qualifier can only be used on block members of blocks..."
+    // "The align qualifier can only be used on blocks or block members..."
+    if (qualifier.hasOffset() ||
+        qualifier.hasAlign())
+        error(loc, "cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type)", "layout qualifier", "");
 
     layoutQualifierCheck(loc, qualifier);
 
-    // TODO: 4.4 enhanced layouts:  generalize to include all new ones
     switch (qualifier.storage) {
     case EvqUniform:
-        if (qualifier.layoutMatrix != ElmNone)
+        if (qualifier.hasMatrix())
             globalUniformDefaults.layoutMatrix = qualifier.layoutMatrix;
-        if (qualifier.layoutPacking != ElpNone)
+        if (qualifier.hasPacking())
             globalUniformDefaults.layoutPacking = qualifier.layoutPacking;
         break;
     case EvqBuffer:
-        if (qualifier.layoutMatrix != ElmNone)
+        if (qualifier.hasMatrix())
             globalBufferDefaults.layoutMatrix = qualifier.layoutMatrix;
-        if (qualifier.layoutPacking != ElpNone)
+        if (qualifier.hasPacking())
             globalBufferDefaults.layoutPacking = qualifier.layoutPacking;
         break;
     case EvqVaryingIn:
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index 813f3237dedfe13e831e602e82fc4fc420d32c8a..cf8abd4fe951165779e86b094a0371d2fcb5c170 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -166,6 +166,7 @@ public:
     void declareBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
     void fixBlockLocations(TSourceLoc, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
     void fixBlockXfbOffsets(TSourceLoc, TQualifier&, TTypeList&);
+    void fixBlockUniformOffsets(TSourceLoc, TQualifier&, TTypeList&);
     void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier);
     void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
     void invariantCheck(TSourceLoc, const TType&, const TString& identifier);