From f2cfe27021def4cdbe341a57f90fa9d0c0f1ebe4 Mon Sep 17 00:00:00 2001
From: John Kessenich <cepheus@frii.com>
Date: Tue, 19 Jul 2016 15:13:47 -0600
Subject: [PATCH] Fix issue #388.

Protect more against error recovery of bad built-in variable redeclarations.
---
 Test/120.vert                              |  2 ++
 Test/baseResults/120.vert.out              |  9 +++++----
 glslang/MachineIndependent/ParseHelper.cpp | 13 +++++++------
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/Test/120.vert b/Test/120.vert
index b7724b435..d2765571e 100644
--- a/Test/120.vert
+++ b/Test/120.vert
@@ -192,6 +192,8 @@ void foo213()
     gl_ClipDistance[1] = 0.3;        // ERROR
 }
 
+int gl_ModelViewMatrix[] = 0;
+
 // token pasting (ERRORS...)
 
 #define mac abc##def
diff --git a/Test/baseResults/120.vert.out b/Test/baseResults/120.vert.out
index a6e833a3e..73ced6a1e 100644
--- a/Test/baseResults/120.vert.out
+++ b/Test/baseResults/120.vert.out
@@ -75,10 +75,11 @@ ERROR: 0:191: '=' :  cannot convert from 'temp float' to 'temp int'
 ERROR: 0:192: 'gl_ClipDistance' : undeclared identifier 
 ERROR: 0:192: 'gl_ClipDistance' :  left of '[' is not of type array, matrix, or vector  
 ERROR: 0:192: 'assign' :  l-value required (can't modify a const)
-ERROR: 0:198: 'token pasting (##)' : not supported for this version or the enabled extensions 
-ERROR: 0:198: '##' : token pasting not implemented (internal error) 
-ERROR: 0:198: '' :  syntax error
-ERROR: 79 compilation errors.  No code generated.
+ERROR: 0:195: 'gl_ModelViewMatrix' : identifiers starting with "gl_" are reserved 
+ERROR: 0:200: 'token pasting (##)' : not supported for this version or the enabled extensions 
+ERROR: 0:200: '##' : token pasting not implemented (internal error) 
+ERROR: 0:200: '' :  syntax error
+ERROR: 80 compilation errors.  No code generated.
 
 
 Shader version: 120
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index bd4b3c95b..56b326efd 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -3175,12 +3175,13 @@ void TParseContext::arrayDimMerge(TType& type, const TArraySizes* sizes)
 //
 void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, const TType& type, TSymbol*& symbol, bool& newDeclaration)
 {
-    if (! symbol) {
+    if (symbol == nullptr) {
         bool currentScope;
         symbol = symbolTable.find(identifier, nullptr, &currentScope);
 
         if (symbol && builtInName(identifier) && ! symbolTable.atBuiltInLevel()) {
             // bad shader (errors already reported) trying to redeclare a built-in name as an array
+            symbol = nullptr;
             return;
         }
         if (symbol == nullptr || ! currentScope) {
@@ -3213,7 +3214,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, con
     // Process a redeclaration.
     //
 
-    if (! symbol) {
+    if (symbol == nullptr) {
         error(loc, "array variable name expected", identifier.c_str(), "");
         return;
     }
@@ -4934,7 +4935,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
     // Check for redeclaration of built-ins and/or attempting to declare a reserved name
     bool newDeclaration = false;    // true if a new entry gets added to the symbol table
     TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers, newDeclaration);
-    if (! symbol)
+    if (symbol == nullptr)
         reservedErrorCheck(loc, identifier);
 
     inheritGlobalDefaults(type.getQualifier());
@@ -4959,18 +4960,18 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
         }
     } else {
         // non-array case
-        if (! symbol)
+        if (symbol == nullptr)
             symbol = declareNonArray(loc, identifier, type, newDeclaration);
         else if (type != symbol->getType())
             error(loc, "cannot change the type of", "redeclaration", symbol->getName().c_str());
     }
 
-    if (! symbol)
+    if (symbol == nullptr)
         return nullptr;
 
     // Deal with initializer
     TIntermNode* initNode = nullptr;
-    if (symbol && initializer) {
+    if (symbol != nullptr && initializer) {
         TVariable* variable = symbol->getAsVariable();
         if (! variable) {
             error(loc, "initializer requires a variable, not a member", identifier.c_str(), "");
-- 
GitLab