Fix double delete with invariant varyings.

The compiler would leave some TString variables lying around
after the pool gets released, leading to a potential crash.

BUG=angle:846
BUG=439202

Change-Id: I484ed9b14bba9bf653f6ed4001ae79f87791b0dd
Reviewed-on: https://chromium-review.googlesource.com/232780
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/234381
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 37969b5..72e179f 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1375,7 +1375,7 @@
             recover();
             return NULL;
         }
-        symbolTable.addInvariantVarying(*identifier);
+        symbolTable.addInvariantVarying(std::string(identifier->c_str()));
         const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
         ASSERT(variable);
         const TType &type = variable->getType();
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index 9cd7421..afb973a 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -413,7 +413,7 @@
 
     // This records invariant varyings declared through
     // "invariant varying_name;".
-    void addInvariantVarying(const TString &originalName)
+    void addInvariantVarying(const std::string &originalName)
     {
         mInvariantVaryings.insert(originalName);
     }
@@ -421,7 +421,7 @@
     // if it is set as invariant during the varying variable
     // declaration - this piece of information is stored in the
     // variable's type, not here.
-    bool isVaryingInvariant(const TString &originalName) const
+    bool isVaryingInvariant(const std::string &originalName) const
     {
       return (mGlobalInvariant ||
               mInvariantVaryings.count(originalName) > 0);
@@ -445,7 +445,7 @@
     typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
     std::vector< PrecisionStackLevel *> precisionStack;
 
-    std::set<TString> mInvariantVaryings;
+    std::set<std::string> mInvariantVaryings;
     bool mGlobalInvariant;
 
     static int uniqueIdCounter;
diff --git a/src/compiler/translator/util.cpp b/src/compiler/translator/util.cpp
index 8cc06a6..42a995e 100644
--- a/src/compiler/translator/util.cpp
+++ b/src/compiler/translator/util.cpp
@@ -307,7 +307,7 @@
         break;
       case EvqVaryingIn:
       case EvqVaryingOut:
-        if (mSymbolTable.isVaryingInvariant(name))
+        if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())))
         {
             variable->isInvariant = true;
         }
diff --git a/tests/compiler_tests/ShaderVariable_test.cpp b/tests/compiler_tests/ShaderVariable_test.cpp
index b642260..7fda29e 100644
--- a/tests/compiler_tests/ShaderVariable_test.cpp
+++ b/tests/compiler_tests/ShaderVariable_test.cpp
@@ -218,4 +218,29 @@
     EXPECT_TRUE(vx.isSameVaryingAtLinkTime(fx));
 }
 
+// Test that using invariant varyings doesn't trigger a double delete.
+TEST(ShaderVariableTest, InvariantDoubleDeleteBug)
+{
+    ShBuiltInResources resources;
+    ShInitBuiltInResources(&resources);
+
+    ShHandle compiler = ShConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, SH_GLSL_OUTPUT, &resources);
+    EXPECT_NE(static_cast<ShHandle>(0), compiler);
+
+    const char *program[] =
+    {
+        "attribute vec4 position;\n"
+        "varying float v;\n"
+        "invariant v;\n"
+        "void main() {\n"
+        "  v = 1.0;\n"
+        "  gl_Position = position;\n"
+        "}"
+    };
+
+    EXPECT_TRUE(ShCompile(compiler, program, 1, SH_OBJECT_CODE));
+    EXPECT_TRUE(ShCompile(compiler, program, 1, SH_OBJECT_CODE));
+    ShDestruct(compiler);
+}
+
 }  // namespace sh