From 664ad418f8455159fb066e9e27d159f191f976a9 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Thu, 5 Sep 2019 02:26:39 -0600 Subject: [PATCH] Fix #1879: Check for valid variable before checking for unsized arrays. The order of error checking was not quite being correct (maybe there is no correct ordering, when many checks must be done and they affect each other). So, check for block-name reuse twice. --- Test/150.frag | 1 + Test/baseResults/150.frag.out | 5 ++++- glslang/Include/Types.h | 2 ++ glslang/MachineIndependent/ParseHelper.cpp | 16 ++++++++++------ 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Test/150.frag b/Test/150.frag index 16963af..e87d633 100644 --- a/Test/150.frag +++ b/Test/150.frag @@ -47,4 +47,5 @@ void barWxyz() int primitiveID() { return gl_PrimitiveID; + gl_PerFragment; // ERROR, block name can't get reused } diff --git a/Test/baseResults/150.frag.out b/Test/baseResults/150.frag.out index 1454b55..e51b13d 100644 --- a/Test/baseResults/150.frag.out +++ b/Test/baseResults/150.frag.out @@ -3,7 +3,9 @@ ERROR: 0:4: 'redeclaration' : cannot redeclare with different qualification: gl_ ERROR: 0:5: 'redeclaration' : cannot redeclare with different qualification: gl_FragCoord ERROR: 0:6: 'layout qualifier' : can only apply origin_upper_left and pixel_center_origin to gl_FragCoord ERROR: 0:14: 'gl_FragCoord' : cannot redeclare after use -ERROR: 4 compilation errors. No code generated. +ERROR: 0:50: 'gl_PerFragment' : cannot be used (maybe an instance name is needed) +ERROR: 0:50: 'gl_PerFragment' : undeclared identifier +ERROR: 6 compilation errors. No code generated. Shader version: 150 @@ -106,6 +108,7 @@ ERROR: node is still EOpNull! 0:49 Sequence 0:49 Branch: Return with expression 0:49 'gl_PrimitiveID' ( flat in int PrimitiveID) +0:50 'gl_PerFragment' ( temp float) 0:? Linker Objects 0:? 'gl_FragCoord' ( gl_FragCoord 4-component vector of float FragCoord) 0:? 'foo' ( smooth in 4-component vector of float) diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 3140006..a419cb0 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -1661,6 +1661,8 @@ public: virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); } virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); } + // Check the block-name convention of creating a block without populating it's members: + virtual bool isUnusableName() const { return isStruct() && structure == nullptr; } virtual bool isParameterized() const { return typeParameters != nullptr; } #ifdef GLSLANG_WEB bool isAtomic() const { return false; } diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 33a1664..08fa610 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -319,10 +319,15 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb // If this is a variable or a block, check it and all it contains, but if this // is a member of an anonymous block, check the whole block, as the whole block // will need to be copied up if it contains an unsized array. - if (symbol->getType().containsUnsizedArray() || - (symbol->getAsAnonMember() && - symbol->getAsAnonMember()->getAnonContainer().getType().containsUnsizedArray())) - makeEditable(symbol); + // + // This check is being done before the block-name check further down, so guard + // for that too. + if (!symbol->getType().isUnusableName()) { + if (symbol->getType().containsUnsizedArray() || + (symbol->getAsAnonMember() && + symbol->getAsAnonMember()->getAnonContainer().getType().containsUnsizedArray())) + makeEditable(symbol); + } } #endif @@ -347,8 +352,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb // See if it was a variable. variable = symbol ? symbol->getAsVariable() : nullptr; if (variable) { - if ((variable->getType().getBasicType() == EbtBlock || - variable->getType().getBasicType() == EbtStruct) && variable->getType().getStruct() == nullptr) { + if (variable->getType().isUnusableName()) { error(loc, "cannot be used (maybe an instance name is needed)", string->c_str(), ""); variable = nullptr; } -- 2.7.4