diff --git a/Test/300block.frag b/Test/300block.frag
new file mode 100644
index 0000000000000000000000000000000000000000..989fee3c6c9211953598ceddf2b1e6999f7d83cc
--- /dev/null
+++ b/Test/300block.frag
@@ -0,0 +1,38 @@
+#version 300 es
+
+struct S {
+    vec4 u;
+    uvec4 v;
+    isampler3D sampler;
+    vec3 w;
+    struct T1 {           // ERROR
+        int a;
+    } t;
+};
+
+uniform S s;
+
+uniform fooBlock {
+    uvec4 bv;
+    mat2 bm2;
+    isampler2D sampler;   // ERROR
+    struct T2 {           // ERROR
+        int a;
+    } t;
+    S fbs;
+};
+
+uniform barBlock {
+    uvec4 nbv;
+    int ni;
+} inst;
+
+uniform barBlockArray {
+    uvec4 nbv;
+    int ni;
+} insts[4];
+
+void main()
+{
+    texture(s.sampler, vec3(inst.ni, bv.y, insts[2].nbv.z));
+}
diff --git a/Test/testlist b/Test/testlist
index 23a03a554a5fe00d15ab5e77c0e92f92764968bf..355ce8ec7b59c84fd7a608633bdb45ad37ff7a73 100644
--- a/Test/testlist
+++ b/Test/testlist
@@ -27,6 +27,7 @@ comment.frag
 300layout.vert
 300layout.frag
 300operations.frag
+300block.frag
 330.frag
 330comp.frag
 constErrors.frag
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index e26ab4b39949527c6575dc3b4255e10782faf9c1..2466a7e11aade2bc01833c8cd85a1e9b05c7157c 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -392,7 +392,7 @@ typedef std::map<TTypeList*, TTypeList*>::const_iterator TStructureMapIterator;
 class TType {
 public:
     POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-    TType(TBasicType t, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
+    explicit TType(TBasicType t, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
                             basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
                             structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0),
                             fieldName(0), mangled(0), typeName(0)
@@ -416,7 +416,10 @@ public:
                             basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
                             structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
                             {
-                                sampler = p.sampler;
+                                if (basicType == EbtSampler)
+                                    sampler = p.sampler;
+                                else
+                                    sampler.clear();
                                 qualifier = p.qualifier;
                                 if (p.userDef) {
                                     structure = p.userDef->getStruct();
@@ -494,6 +497,21 @@ public:
 		arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
 	}
 
+    // Merge type from parent, where a parentType is at the beginning of a declaration,
+    // establishing some charastics for all subsequent names, while this type
+    // is on the individual names.
+    void mergeType(const TPublicType& parentType)
+    {
+        // arrayness is currently the only child aspect that has to be preserved
+        setElementType(parentType.basicType, parentType.vectorSize, parentType.matrixCols, parentType.matrixRows, parentType.userDef);
+        qualifier = parentType.qualifier;
+        sampler = parentType.sampler;
+        if (parentType.arraySizes)
+            setArraySizes(parentType.arraySizes);
+        if (parentType.userDef)
+            setTypeName(parentType.userDef->getTypeName());
+    }
+
 	TType* clone(const TStructureMap& remapper)
 	{
 		TType *newType = new TType();
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 52538fdc88d7277679d1c33498142f38f56746ac..0e39ca8c9e52df2707d7d86fe9fd0413048ae79b 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -676,7 +676,7 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif
         break;
     }
 
-    // Do non in/out error checks
+    // Do non-in/out error checks
 
     if (qualifier.storage != EvqUniform && samplerErrorCheck(line, publicType, "samplers and images must be uniform"))
         return true;
@@ -1517,7 +1517,7 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
         return;
     }
 
-    // check for qualifiers that don't belong within a block
+    // check for qualifiers and types that don't belong within a block
     for (unsigned int member = 0; member < typeList.size(); ++member) {
         TQualifier memberQualifier = typeList[member].type->getQualifier();
         if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal &&
@@ -1531,6 +1531,12 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
                 recover();
             }
         }
+
+        TBasicType basicType = typeList[member].type->getBasicType();
+        if (basicType == EbtSampler) {
+            error(line, "member of block cannot be a sampler type", typeList[member].type->getFieldName().c_str(), "");
+            recover();
+        }
     }
 
     // Make default block qualification, and adjust the member qualifications
@@ -1546,6 +1552,8 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
     // Build and add the interface block as a new type named blockName
 
     TType blockType(&typeList, blockName, publicType.qualifier.storage);
+    if (arraySizes)
+        blockType.setArraySizes(arraySizes);
     blockType.getQualifier().layoutPacking = defaultQualification.layoutPacking;
     TVariable* userTypeDef = new TVariable(&blockName, blockType, true);
     if (! symbolTable.insert(*userTypeDef)) {
diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y
index 02ae2019f75e44b5ad5c097cf7dee244dcdcb972..5e077ca85560172e37e7012f0ec3689c1ddd920b 100644
--- a/glslang/MachineIndependent/glslang.y
+++ b/glslang/MachineIndependent/glslang.y
@@ -1600,11 +1600,11 @@ fully_specified_type
             parseContext.recover();
             $2.arraySizes = 0;
         }
+        
+        if (parseContext.mergeQualifiersErrorCheck($2.line, $2, $1, true))
+            parseContext.recover();
 
         $$ = $2;
-        $$.qualifier = $1.qualifier;
-        if ($$.qualifier.precision == EpqNone)
-            $$.qualifier.precision = $2.qualifier.precision;
 
         if (! $$.qualifier.isInterpolation() && parseContext.language == EShLangFragment)
             $$.qualifier.smooth = true;
@@ -2560,6 +2560,10 @@ precision_qualifier
 struct_specifier
     : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
         // TODO: semantics: check for qualifiers that don't belong in a struct
+
+        // TODO: semantics: check that this is not nested inside a block or structure
+        //     parseContext.error($1.line, "cannot nest a block or structure definitions", $1.userDef->getTypeName().c_str(), "");
+
         TType* structure = new TType($4, *$2.string);
         TVariable* userTypeDef = new TVariable($2.string, *structure, true);
         if (! parseContext.symbolTable.insert(*userTypeDef)) {
@@ -2608,17 +2612,8 @@ struct_declaration
         if (parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
             parseContext.recover();
         }
-        for (unsigned int i = 0; i < $$->size(); ++i) {
-            //
-            // Careful not to replace already know aspects of type, like array-ness
-            //
-            (*$$)[i].type->setElementType($1.basicType, $1.vectorSize, $1.matrixCols, $1.matrixRows, $1.userDef);
-
-            if ($1.arraySizes)
-                (*$$)[i].type->setArraySizes($1.arraySizes);
-            if ($1.userDef)
-                (*$$)[i].type->setTypeName($1.userDef->getTypeName());
-        }
+        for (unsigned int i = 0; i < $$->size(); ++i)
+            (*$$)[i].type->mergeType($1);
     }
     | type_qualifier type_specifier struct_declarator_list SEMICOLON {
         if ($2.arraySizes) {
@@ -2632,17 +2627,8 @@ struct_declaration
             parseContext.recover();
         if (parseContext.mergeQualifiersErrorCheck($2.line, $2, $1, true))
             parseContext.recover();
-        for (unsigned int i = 0; i < $$->size(); ++i) {
-            //
-            // Careful not to replace already know aspects of type, like array-ness
-            //
-            (*$$)[i].type->setElementType($2.basicType, $2.vectorSize, $2.matrixCols, $2.matrixRows, $2.userDef);
-            (*$$)[i].type->getQualifier() = $2.qualifier;
-            if ($2.arraySizes)
-                (*$$)[i].type->setArraySizes($2.arraySizes);
-            if ($2.userDef)
-                (*$$)[i].type->setTypeName($2.userDef->getTypeName());
-        }
+        for (unsigned int i = 0; i < $$->size(); ++i)
+            (*$$)[i].type->mergeType($2);
     }
     ;
 
diff --git a/glslang/MachineIndependent/preprocessor/cpp.c b/glslang/MachineIndependent/preprocessor/cpp.c
index 8f24b662055bb92e27fe7a5a42c9df06ffbb91c7..efa77bc3a1b4c6eb62dd5d3f6336a20471155198 100644
--- a/glslang/MachineIndependent/preprocessor/cpp.c
+++ b/glslang/MachineIndependent/preprocessor/cpp.c
@@ -982,7 +982,7 @@ static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp)
 // return a zero, for scanning a macro that was never defined
 static int zero_scan(InputSrc *inInput, yystypepp * yylvalpp) 
 {
-    MacroInputSrc* in = (MacroInputSrc*)inInput;  //?? need to free this?
+    MacroInputSrc* in = (MacroInputSrc*)inInput;
 
     strcpy(yylvalpp->symbol_name, "0");
     yylvalpp->sc_int = 0;