Reland "Fix unit test for setting locale creating malformed HLSL shader code
Fix malformed HLSL shader code in other locales than classic"
This is a reland of 5f662c0042703344eb0eef6d1c123e902e3aefbf
Original change's description:
> Fix unit test for setting locale creating malformed HLSL shader code
> Fix malformed HLSL shader code in other locales than classic
>
> Bug: angleproject:1433
> Change-Id: I30bad0bd0cfda465ec7200e48e12800d7d8efd26
> Reviewed-on: https://chromium-review.googlesource.com/c/1447862
> Reviewed-by: Geoff Lang <geofflang@chromium.org>
> Reviewed-by: Jamie Madill <jmadill@chromium.org>
> Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>
Bug: angleproject:1433
Change-Id: I94caf7b4c7179119e5a5567c3014d7232df45a13
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1516192
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>
diff --git a/src/compiler/translator/AtomicCounterFunctionHLSL.cpp b/src/compiler/translator/AtomicCounterFunctionHLSL.cpp
index 63fe026..9f8e4fd 100644
--- a/src/compiler/translator/AtomicCounterFunctionHLSL.cpp
+++ b/src/compiler/translator/AtomicCounterFunctionHLSL.cpp
@@ -9,6 +9,7 @@
#include "compiler/translator/AtomicCounterFunctionHLSL.h"
+#include "compiler/translator/Common.h"
#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
@@ -92,7 +93,7 @@
ImmutableString getAtomicCounterNameForBinding(int binding)
{
- std::stringstream counterName;
+ std::stringstream counterName = sh::InitializeStream<std::stringstream>();
counterName << kAtomicCounterBaseName << binding;
return ImmutableString(counterName.str());
}
diff --git a/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp b/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
index 7c619dd..dc48527 100644
--- a/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
+++ b/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
@@ -5,6 +5,7 @@
//
#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
+
#include "angle_gl.h"
#include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/VersionGLSL.h"
@@ -87,7 +88,7 @@
};
for (int dim = 2; dim <= 4; ++dim)
{
- std::stringstream ss;
+ std::stringstream ss = sh::InitializeStream<std::stringstream>();
ss << "emu_precision vec" << dim << " atan_emu(emu_precision vec" << dim
<< " y, emu_precision vec" << dim << " x)\n"
<< "{\n"
diff --git a/src/compiler/translator/CallDAG.cpp b/src/compiler/translator/CallDAG.cpp
index 9c0e2cf..63c8cd0 100644
--- a/src/compiler/translator/CallDAG.cpp
+++ b/src/compiler/translator/CallDAG.cpp
@@ -171,7 +171,7 @@
InitResult result = INITDAG_SUCCESS;
- std::stringstream errorStream;
+ std::stringstream errorStream = sh::InitializeStream<std::stringstream>();
while (!functionsToProcess.empty())
{
diff --git a/src/compiler/translator/Common.h b/src/compiler/translator/Common.h
index d0b8347..179cfe2 100644
--- a/src/compiler/translator/Common.h
+++ b/src/compiler/translator/Common.h
@@ -125,6 +125,15 @@
return buffer;
}
+// Initialize a new stream which must be imbued with the classic locale
+template <typename T>
+T InitializeStream()
+{
+ T stream;
+ stream.imbue(std::locale::classic());
+ return stream;
+}
+
} // namespace sh
namespace std
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 6be8638..0bd3bcb 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -68,7 +68,7 @@
{
static int fileIndex = 0;
- std::ostringstream o;
+ std::ostringstream o = sh::InitializeStream<std::ostringstream>();
o << "corpus/" << fileIndex++ << ".sample";
std::string s = o.str();
@@ -940,7 +940,7 @@
void TCompiler::setResourceString()
{
- std::ostringstream strstream;
+ std::ostringstream strstream = sh::InitializeStream<std::ostringstream>();
// clang-format off
strstream << ":MaxVertexAttribs:" << mResources.MaxVertexAttribs
@@ -1094,7 +1094,7 @@
for (size_t i = 0; i < mCallDag.size(); i++)
{
- int depth = 0;
+ int depth = 0;
const CallDAG::Record &record = mCallDag.getRecordFromIndex(i);
for (const int &calleeIndex : record.callees)
@@ -1107,7 +1107,7 @@
if (depth >= mResources.MaxCallStackDepth)
{
// Trace back the function chain to have a meaningful info log.
- std::stringstream errorStream;
+ std::stringstream errorStream = sh::InitializeStream<std::stringstream>();
errorStream << "Call stack too deep (larger than " << mResources.MaxCallStackDepth
<< ") with the following call chain: "
<< record.node->getFunction()->name();
diff --git a/src/compiler/translator/DirectiveHandler.cpp b/src/compiler/translator/DirectiveHandler.cpp
index 46e67f5..e468fd4 100644
--- a/src/compiler/translator/DirectiveHandler.cpp
+++ b/src/compiler/translator/DirectiveHandler.cpp
@@ -10,6 +10,7 @@
#include "angle_gl.h"
#include "common/debug.h"
+#include "compiler/translator/Common.h"
#include "compiler/translator/Diagnostics.h"
namespace sh
@@ -190,7 +191,7 @@
}
else
{
- std::stringstream stream;
+ std::stringstream stream = sh::InitializeStream<std::stringstream>();
stream << version;
std::string str = stream.str();
mDiagnostics.error(loc, "version number not supported", str.c_str());
diff --git a/src/compiler/translator/InfoSink.cpp b/src/compiler/translator/InfoSink.cpp
index fc19d7e..e8a8453 100644
--- a/src/compiler/translator/InfoSink.cpp
+++ b/src/compiler/translator/InfoSink.cpp
@@ -69,7 +69,7 @@
void TInfoSinkBase::location(int file, int line)
{
- TPersistStringStream stream;
+ TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>();
if (line)
stream << file << ":" << line;
else
diff --git a/src/compiler/translator/InfoSink.h b/src/compiler/translator/InfoSink.h
index 44f0e83..100d06e 100644
--- a/src/compiler/translator/InfoSink.h
+++ b/src/compiler/translator/InfoSink.h
@@ -41,7 +41,7 @@
template <typename T>
TInfoSinkBase &operator<<(const T &t)
{
- TPersistStringStream stream;
+ TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>();
stream << t;
sink.append(stream.str());
return *this;
@@ -79,7 +79,7 @@
// does not have a fractional part, the default precision format does
// not write the decimal portion which gets interpreted as integer by
// the compiler.
- TPersistStringStream stream;
+ TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>();
if (fractionalPart(f) == 0.0f)
{
stream.precision(1);
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 84e32dd..bb7fcb1 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -39,7 +39,7 @@
TString ArrayHelperFunctionName(const char *prefix, const TType &type)
{
- TStringStream fnName;
+ TStringStream fnName = sh::InitializeStream<TStringStream>();
fnName << prefix << "_";
if (type.isArray())
{
@@ -132,7 +132,7 @@
constexpr int kZeroCount = 256;
std::string DefineZeroArray()
{
- std::stringstream ss;
+ std::stringstream ss = sh::InitializeStream<std::stringstream>();
// For 'static', if the declaration does not include an initializer, the value is set to zero.
// https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-variable-syntax
ss << "static uint " << kZeros << "[" << kZeroCount << "];\n";
@@ -141,9 +141,9 @@
std::string GetZeroInitializer(size_t size)
{
- std::stringstream ss;
- size_t quotient = size / kZeroCount;
- size_t reminder = size % kZeroCount;
+ std::stringstream ss = sh::InitializeStream<std::stringstream>();
+ size_t quotient = size / kZeroCount;
+ size_t reminder = size % kZeroCount;
for (size_t i = 0; i < quotient; ++i)
{
@@ -416,7 +416,7 @@
init += indentString + "{\n";
for (unsigned int arrayIndex = 0u; arrayIndex < type.getOutermostArraySize(); ++arrayIndex)
{
- TStringStream indexedString;
+ TStringStream indexedString = sh::InitializeStream<TStringStream>();
indexedString << name << "[" << arrayIndex << "]";
TType elementType = type;
elementType.toArrayElementType();
@@ -891,8 +891,8 @@
out << kImage2DFunctionString << "\n";
- std::ostringstream systemValueDeclaration;
- std::ostringstream glBuiltinInitialization;
+ std::ostringstream systemValueDeclaration = sh::InitializeStream<std::ostringstream>();
+ std::ostringstream glBuiltinInitialization = sh::InitializeStream<std::ostringstream>();
systemValueDeclaration << "\nstruct CS_INPUT\n{\n";
glBuiltinInitialization << "\nvoid initGLBuiltins(CS_INPUT input)\n"
@@ -1900,7 +1900,7 @@
{
int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
- std::stringstream prefixSink;
+ std::stringstream prefixSink = sh::InitializeStream<std::stringstream>();
prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_" << index;
return ImmutableString(prefixSink.str());
}
@@ -1910,7 +1910,7 @@
int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
const TField *field = s->fields()[index];
- std::stringstream prefixSink;
+ std::stringstream prefixSink = sh::InitializeStream<std::stringstream>();
prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_"
<< field->name();
return ImmutableString(prefixSink.str());
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index fcaca76..4b92375 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -611,7 +611,7 @@
return true;
}
- std::stringstream reasonStream;
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
reasonStream << "l-value required";
if (!message.empty())
{
@@ -902,7 +902,7 @@
{
if (ContainsSampler(pType.userDef))
{
- std::stringstream reasonStream;
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
reasonStream << reason << " (structure contains a sampler)";
std::string reasonStr = reasonStream.str();
error(line, reasonStr.c_str(), getBasicString(pType.type));
@@ -3066,7 +3066,7 @@
if (mComputeShaderLocalSize[i] < 1 ||
mComputeShaderLocalSize[i] > maxComputeWorkGroupSizeValue)
{
- std::stringstream reasonStream;
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
reasonStream << "invalid value: Value must be at least 1 and no greater than "
<< maxComputeWorkGroupSizeValue;
const std::string &reason = reasonStream.str();
@@ -3891,7 +3891,7 @@
// one to the field's struct nesting.
if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
{
- std::stringstream reasonStream;
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
if (field.type()->getStruct()->symbolType() == SymbolType::Empty)
{
// This may happen in case there are nested struct definitions. While they are also
@@ -4085,7 +4085,7 @@
ASSERT(index >= 0);
if (index >= arraySize)
{
- std::stringstream reasonStream;
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
reasonStream << reason << " '" << index << "'";
std::string token = reasonStream.str();
outOfRangeError(outOfRangeIndexIsError, location, reason, "[]");
@@ -4387,7 +4387,7 @@
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
if (intValue < 1)
{
- std::stringstream reasonStream;
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
reasonStream << "out of range: " << getWorkGroupSizeString(index) << " must be positive";
std::string reason = reasonStream.str();
error(intValueLine, reason.c_str(), intValueString.c_str());
@@ -5672,7 +5672,7 @@
int offsetValue = values[i].getIConst();
if (offsetValue > maxOffsetValue || offsetValue < minOffsetValue)
{
- std::stringstream tokenStream;
+ std::stringstream tokenStream = sh::InitializeStream<std::stringstream>();
tokenStream << offsetValue;
std::string token = tokenStream.str();
error(offset->getLine(), "Texture offset value out of valid range",
diff --git a/src/compiler/translator/Symbol.cpp b/src/compiler/translator/Symbol.cpp
index babda8c..52ad4f3 100644
--- a/src/compiler/translator/Symbol.cpp
+++ b/src/compiler/translator/Symbol.cpp
@@ -115,7 +115,7 @@
const TType *fieldType = field->type();
if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
{
- std::stringstream fieldName;
+ std::stringstream fieldName = sh::InitializeStream<std::stringstream>();
fieldName << namePrefix << "_" << field->name();
TString fieldApiName = apiNamePrefix + ".";
fieldApiName += field->name().data();
diff --git a/src/compiler/translator/Types.cpp b/src/compiler/translator/Types.cpp
index 6fc5875..9d0374b 100644
--- a/src/compiler/translator/Types.cpp
+++ b/src/compiler/translator/Types.cpp
@@ -756,7 +756,7 @@
elementType.toArrayElementType();
for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
{
- std::stringstream elementName;
+ std::stringstream elementName = sh::InitializeStream<std::stringstream>();
elementName << namePrefix << "_" << arrayIndex;
TStringStream elementApiName;
elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
diff --git a/src/compiler/translator/ValidateOutputs.cpp b/src/compiler/translator/ValidateOutputs.cpp
index 8115523..9880255 100644
--- a/src/compiler/translator/ValidateOutputs.cpp
+++ b/src/compiler/translator/ValidateOutputs.cpp
@@ -119,7 +119,7 @@
const size_t offsetLocation = location + elementIndex;
if ((*validOutputsToUse)[offsetLocation])
{
- std::stringstream strstr;
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
strstr << "conflicting output locations with previously defined output '"
<< (*validOutputsToUse)[offsetLocation]->getName() << "'";
error(*symbol, strstr.str().c_str(), diagnostics);
diff --git a/src/compiler/translator/ValidateVaryingLocations.cpp b/src/compiler/translator/ValidateVaryingLocations.cpp
index 55f6dbe..394e35c 100644
--- a/src/compiler/translator/ValidateVaryingLocations.cpp
+++ b/src/compiler/translator/ValidateVaryingLocations.cpp
@@ -83,7 +83,7 @@
const int offsetLocation = location + elementIndex;
if (locationMap.find(offsetLocation) != locationMap.end())
{
- std::stringstream strstr;
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
strstr << "'" << varying->getName()
<< "' conflicting location with previously defined '"
<< locationMap[offsetLocation]->getName() << "'";
diff --git a/src/compiler/translator/blocklayout.cpp b/src/compiler/translator/blocklayout.cpp
index 58c4f7b..7d0609e 100644
--- a/src/compiler/translator/blocklayout.cpp
+++ b/src/compiler/translator/blocklayout.cpp
@@ -11,6 +11,7 @@
#include "common/mathutil.h"
#include "common/utilities.h"
+#include "compiler/translator/Common.h"
namespace sh
{
@@ -132,7 +133,7 @@
std::string CollapseNameStack(const std::vector<std::string> &nameStack)
{
- std::stringstream strstr;
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
for (const std::string &part : nameStack)
{
strstr << part;
@@ -415,7 +416,7 @@
void VariableNameVisitor::enterArrayElement(const ShaderVariable &arrayVar,
unsigned int arrayElement)
{
- std::stringstream strstr;
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
strstr << "[" << arrayElement << "]";
std::string elementString = strstr.str();
mNameStack.push_back(elementString);
diff --git a/src/compiler/translator/tree_ops/EmulatePrecision.cpp b/src/compiler/translator/tree_ops/EmulatePrecision.cpp
index ca4cf4a..ba19bd1 100644
--- a/src/compiler/translator/tree_ops/EmulatePrecision.cpp
+++ b/src/compiler/translator/tree_ops/EmulatePrecision.cpp
@@ -174,7 +174,7 @@
std::string RoundingHelperWriterESSL::getTypeString(const char *glslType)
{
- std::stringstream typeStrStr;
+ std::stringstream typeStrStr = sh::InitializeStream<std::stringstream>();
typeStrStr << "highp " << glslType;
return typeStrStr.str();
}
@@ -257,7 +257,7 @@
void RoundingHelperWriterGLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
const unsigned int size)
{
- std::stringstream vecTypeStrStr;
+ std::stringstream vecTypeStrStr = sh::InitializeStream<std::stringstream>();
vecTypeStrStr << "vec" << size;
std::string vecType = getTypeString(vecTypeStrStr.str().c_str());
@@ -287,7 +287,7 @@
const unsigned int rows,
const char *functionName)
{
- std::stringstream matTypeStrStr;
+ std::stringstream matTypeStrStr = sh::InitializeStream<std::stringstream>();
matTypeStrStr << "mat" << columns;
if (rows != columns)
{
@@ -379,7 +379,7 @@
void RoundingHelperWriterHLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink,
const unsigned int size)
{
- std::stringstream vecTypeStrStr;
+ std::stringstream vecTypeStrStr = sh::InitializeStream<std::stringstream>();
vecTypeStrStr << "float" << size;
std::string vecType = vecTypeStrStr.str();
@@ -409,7 +409,7 @@
const unsigned int rows,
const char *functionName)
{
- std::stringstream matTypeStrStr;
+ std::stringstream matTypeStrStr = sh::InitializeStream<std::stringstream>();
matTypeStrStr << "float" << columns << "x" << rows;
std::string matType = matTypeStrStr.str();
@@ -744,7 +744,7 @@
TIntermTyped *right,
const char *opNameStr)
{
- std::stringstream strstr;
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
if (left->getPrecision() == EbpMedium)
strstr << "angle_compound_" << opNameStr << "_frm";
else