Remove literal string from error message.

The lexer doesn't actually keep the string for literals.

Bug chromium:939239

Change-Id: Ib8b28e75e36d1c6beff8afa580fc4c29c23b6eb0
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26428
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/compiler/ParseHelper.cpp b/src/OpenGL/compiler/ParseHelper.cpp
index bf731ea..b46a36f 100644
--- a/src/OpenGL/compiler/ParseHelper.cpp
+++ b/src/OpenGL/compiler/ParseHelper.cpp
@@ -2828,7 +2828,7 @@
 	return qualifier;
 }
 
-TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine)
+TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, int intValue, const TSourceLoc& intValueLine)
 {
 	TLayoutQualifier qualifier;
 
@@ -2846,7 +2846,7 @@
 		// must check that location is non-negative
 		if (intValue < 0)
 		{
-			error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative");
+			error(intValueLine, "out of range:", "", "location must be non-negative");
 			recover();
 		}
 		else
diff --git a/src/OpenGL/compiler/ParseHelper.h b/src/OpenGL/compiler/ParseHelper.h
index 10e1895..e528220 100644
--- a/src/OpenGL/compiler/ParseHelper.h
+++ b/src/OpenGL/compiler/ParseHelper.h
@@ -209,7 +209,7 @@
 	                                    const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine);
 
 	TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine);
-	TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine);
+	TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, int intValue, const TSourceLoc& intValueLine);
 	TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
 	TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, const TSourceLoc &storageLoc, TQualifier storageQualifier);
 
diff --git a/src/OpenGL/compiler/glslang.y b/src/OpenGL/compiler/glslang.y
index ab69684..11000e1 100644
--- a/src/OpenGL/compiler/glslang.y
+++ b/src/OpenGL/compiler/glslang.y
@@ -1047,10 +1047,10 @@
         $$ = context->parseLayoutQualifier(*$1.string, @1);
     }
     | IDENTIFIER EQUAL INTCONSTANT {
-        $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3);
+        $$ = context->parseLayoutQualifier(*$1.string, @1, $3.i, @3);
     }
     | IDENTIFIER EQUAL UINTCONSTANT {
-        $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3);
+        $$ = context->parseLayoutQualifier(*$1.string, @1, $3.i, @3);
     }
     ;
 
diff --git a/src/OpenGL/compiler/glslang_tab.cpp b/src/OpenGL/compiler/glslang_tab.cpp
index 6d8f589..f18ef9f 100644
--- a/src/OpenGL/compiler/glslang_tab.cpp
+++ b/src/OpenGL/compiler/glslang_tab.cpp
@@ -3777,7 +3777,7 @@
   case 153:
 
     {
-        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), *(yyvsp[0].lex).string, (yyvsp[0].lex).i, (yylsp[0]));
+        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
     }
 
     break;
@@ -3785,7 +3785,7 @@
   case 154:
 
     {
-        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), *(yyvsp[0].lex).string, (yyvsp[0].lex).i, (yylsp[0]));
+        (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
     }
 
     break;
diff --git a/tests/GLESUnitTests/unittests.cpp b/tests/GLESUnitTests/unittests.cpp
index 33fbaf6..ed8c441 100644
--- a/tests/GLESUnitTests/unittests.cpp
+++ b/tests/GLESUnitTests/unittests.cpp
@@ -775,6 +775,98 @@
 	Uninitialize();
 }
 
+// Test negative layout locations
+TEST_F(SwiftShaderTest, NegativeLocation)
+{
+	Initialize(3, false);
+
+	const std::string vs =
+		"#version 300 es\n"
+		"layout(location = 0x86868686u) in vec4 a0;\n"   // Explicitly bound in GLSL
+		"layout(location = 0x96969696u) in vec4 a2;\n"   // Explicitly bound in GLSL
+		"in vec4 a5;\n"                        // Bound to location 5 by API
+		"in mat2 a3;\n"                        // Implicit location
+		"in vec4 a1;\n"                        // Implicit location
+		"in vec4 a6;\n"                        // Implicit location
+		"out vec4 color;\n"
+		"void main()\n"
+		"{\n"
+		"   vec4 a34 = vec4(a3[0], a3[1]);\n"
+		"	gl_Position = a0;\n"
+		"   color = (a2 == vec4(1.0, 2.0, 3.0, 4.0) &&\n"
+		"            a34 == vec4(5.0, 6.0, 7.0, 8.0) &&\n"
+		"            a5 == vec4(9.0, 10.0, 11.0, 12.0) &&\n"
+		"            a1 == vec4(13.0, 14.0, 15.0, 16.0) &&\n"
+		"            a6 == vec4(17.0, 18.0, 19.0, 20.0)) ?\n"
+		"           vec4(0.0, 1.0, 0.0, 1.0) :\n"
+		"           vec4(1.0, 0.0, 0.0, 1.0);"
+		"}\n";
+
+	const std::string fs =
+		"#version 300 es\n"
+		"precision mediump float;\n"
+		"in vec4 color;\n"
+		"layout(location = 0xA6A6A6A6u) out vec4 fragColor;\n"
+		"void main()\n"
+		"{\n"
+		"	fragColor = color;\n"
+		"}\n";
+
+	{
+		GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
+		const char* vsSource[1] = { vs.c_str() };
+		glShaderSource(vertexShader, 1, vsSource, nullptr);
+		glCompileShader(vertexShader);
+		EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+		GLint vsCompileStatus = 0;
+		glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vsCompileStatus);
+		EXPECT_EQ(vsCompileStatus, GL_FALSE);
+
+		// Expect the info log to contain "out of range: location must be non-negative". This is not a spec requirement.
+		GLsizei length = 0;
+		glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &length);
+		EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+		EXPECT_NE(length, 0);
+		char *log = new char[length];
+		GLsizei written = 0;
+		glGetShaderInfoLog(vertexShader, length, &written, log);
+		EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+		EXPECT_EQ(length, written + 1);
+		EXPECT_NE(strstr(log, "out of range: location must be non-negative"), nullptr);
+		delete[] log;
+
+		glDeleteShader(vertexShader);
+	}
+
+	{
+		GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+		const char* fsSource[1] = { fs.c_str() };
+		glShaderSource(fragmentShader, 1, fsSource, nullptr);
+		glCompileShader(fragmentShader);
+		EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+		GLint fsCompileStatus = 0;
+		glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fsCompileStatus);
+		EXPECT_EQ(fsCompileStatus, GL_FALSE);
+
+		// Expect the info log to contain "out of range: location must be non-negative". This is not a spec requirement.
+		GLsizei length = 0;
+		glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &length);
+		EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+		EXPECT_NE(length, 0);
+		char *log = new char[length];
+		GLsizei written = 0;
+		glGetShaderInfoLog(fragmentShader, length, &written, log);
+		EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+		EXPECT_EQ(length, written + 1);
+		EXPECT_NE(strstr(log, "out of range: location must be non-negative"), nullptr);
+		delete[] log;
+
+		glDeleteShader(fragmentShader);
+	}
+
+	Uninitialize();
+}
+
 // Tests clearing of a texture with 'dirty' content.
 TEST_F(SwiftShaderTest, ClearDirtyTexture)
 {