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