Commit b3fbd867 by Olli Etuaho

Fix setting const qualifier on indexing expression

Resubmitting now that separate fix for updating mangled names of types has been merged. A unit test is added to make sure that the same regression doesn't happen again. Previously, constness of indexing expressions did not take the index expression into account. Now constness correctly takes into account both the base expression and the index expression. Setting the type of expressions that index arrays is also simplified. BUG=angleproject:1170 TEST=angle_unittests Change-Id: Ie9b6aaee8185b945c03657b13d9513cc55cd2a9f Reviewed-on: https://chromium-review.googlesource.com/303601Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent b12531c9
...@@ -2872,51 +2872,36 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -2872,51 +2872,36 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
} }
else if (baseExpression->isArray()) else if (baseExpression->isArray())
{ {
const TType &baseType = baseExpression->getType(); TType indexedType = baseExpression->getType();
if (baseType.getStruct()) indexedType.clearArrayness();
{ indexedExpression->setType(indexedType);
TType copyOfType(baseType.getStruct());
indexedExpression->setType(copyOfType);
}
else if (baseType.isInterfaceBlock())
{
TType copyOfType(baseType.getInterfaceBlock(), baseType.getQualifier(),
baseType.getLayoutQualifier(), 0);
indexedExpression->setType(copyOfType);
}
else
{
indexedExpression->setType(
TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary,
static_cast<unsigned char>(baseExpression->getNominalSize()),
static_cast<unsigned char>(baseExpression->getSecondarySize())));
}
if (baseExpression->getType().getQualifier() == EvqConst)
{
indexedExpression->getTypePointer()->setQualifier(EvqConst);
}
} }
else if (baseExpression->isMatrix()) else if (baseExpression->isMatrix())
{ {
TQualifier qualifier =
baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
indexedExpression->setType(TType(baseExpression->getBasicType(), indexedExpression->setType(TType(baseExpression->getBasicType(),
baseExpression->getPrecision(), qualifier, baseExpression->getPrecision(), EvqTemporary,
static_cast<unsigned char>(baseExpression->getRows()))); static_cast<unsigned char>(baseExpression->getRows())));
} }
else if (baseExpression->isVector()) else if (baseExpression->isVector())
{ {
TQualifier qualifier =
baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
indexedExpression->setType( indexedExpression->setType(
TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier)); TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary));
} }
else else
{ {
indexedExpression->setType(baseExpression->getType()); indexedExpression->setType(baseExpression->getType());
} }
if (baseExpression->getType().getQualifier() == EvqConst &&
indexExpression->getType().getQualifier() == EvqConst)
{
indexedExpression->getTypePointer()->setQualifier(EvqConst);
}
else
{
indexedExpression->getTypePointer()->setQualifier(EvqTemporary);
}
return indexedExpression; return indexedExpression;
} }
......
...@@ -872,3 +872,47 @@ TEST_F(MalformedShaderTest, FragmentShaderInputStructWithInt) ...@@ -872,3 +872,47 @@ TEST_F(MalformedShaderTest, FragmentShaderInputStructWithInt)
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog; FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
} }
} }
// Selecting a field of a vector that's the result of dynamic indexing a constant array should work.
TEST_F(MalformedShaderTest, ShaderSelectingFieldOfVectorIndexedFromArray)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 my_FragColor;\n"
"uniform int i;\n"
"void main() {\n"
" float f = vec2[1](vec2(0.0, 0.1))[i].x;\n"
" my_FragColor = vec4(f);\n"
"}\n";
if (!compile(shaderString))
{
FAIL() << "Shader compilation failed, expecting success " << mInfoLog;
}
}
// Passing an array into a function and then passing a value from that array into another function
// should work. This is a regression test for a bug where the mangled name of a TType was not
// properly updated when determining the type resulting from array indexing.
TEST_F(MalformedShaderTest, ArrayValueFromFunctionParameterAsParameter)
{
const std::string &shaderString =
"precision mediump float;\n"
"uniform float u;\n"
"float foo(float f) {\n"
" return f * 2.0;\n"
"}\n"
"float bar(float[2] f) {\n"
" return foo(f[0]);\n"
"}\n"
"void main()\n"
"{\n"
" float arr[2];\n"
" arr[0] = u;\n"
" gl_FragColor = vec4(bar(arr));\n"
"}\n";
if (!compile(shaderString))
{
FAIL() << "Shader compilation failed, expecting success " << mInfoLog;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment