Commit 37d96cce by Olli Etuaho

Fix accepting arrays as array indices

Previously, arrays were being incorrectly accepted as array indices. This was because the isScalar() check only checked that the type was not a vector or matrix, but still returned true for scalar arrays. This patch changes the isScalar() check so that it returns false for arrays. This makes usage of the term "scalar" more consistent in the shader translator. Most of the code using isScalar() was compatible with this change. Code in util.cpp that used to assume that isScalar() doesn't care about arrayness is refactored to work with the new behavior. BUG=angleproject:2102 TEST=angle_unittests Change-Id: I2a7f4c30fca7917d1099d0400efe3de859338b2a
parent 56229f1b
...@@ -765,7 +765,7 @@ bool TParseContext::checkIsNonVoid(const TSourceLoc &line, ...@@ -765,7 +765,7 @@ bool TParseContext::checkIsNonVoid(const TSourceLoc &line,
// or not. // or not.
bool TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type) bool TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type)
{ {
if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) if (type->getBasicType() != EbtBool || !type->isScalar())
{ {
error(line, "boolean expression expected", ""); error(line, "boolean expression expected", "");
return false; return false;
......
...@@ -378,7 +378,7 @@ class TType ...@@ -378,7 +378,7 @@ class TType
bool isInterfaceBlock() const { return type == EbtInterfaceBlock; } bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
bool isVector() const { return primarySize > 1 && secondarySize == 1; } bool isVector() const { return primarySize > 1 && secondarySize == 1; }
bool isScalar() const { return primarySize == 1 && secondarySize == 1 && !structure; } bool isScalar() const { return primarySize == 1 && secondarySize == 1 && !structure && !array; }
bool isScalarFloat() const { return isScalar() && type == EbtFloat; } bool isScalarFloat() const { return isScalar() && type == EbtFloat; }
bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); } bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
......
...@@ -186,11 +186,7 @@ GLenum GLVariableType(const TType &type) ...@@ -186,11 +186,7 @@ GLenum GLVariableType(const TType &type)
{ {
if (type.getBasicType() == EbtFloat) if (type.getBasicType() == EbtFloat)
{ {
if (type.isScalar()) if (type.isVector())
{
return GL_FLOAT;
}
else if (type.isVector())
{ {
switch (type.getNominalSize()) switch (type.getNominalSize())
{ {
...@@ -252,15 +248,13 @@ GLenum GLVariableType(const TType &type) ...@@ -252,15 +248,13 @@ GLenum GLVariableType(const TType &type)
} }
} }
else else
UNREACHABLE(); {
return GL_FLOAT;
}
} }
else if (type.getBasicType() == EbtInt) else if (type.getBasicType() == EbtInt)
{ {
if (type.isScalar()) if (type.isVector())
{
return GL_INT;
}
else if (type.isVector())
{ {
switch (type.getNominalSize()) switch (type.getNominalSize())
{ {
...@@ -275,15 +269,14 @@ GLenum GLVariableType(const TType &type) ...@@ -275,15 +269,14 @@ GLenum GLVariableType(const TType &type)
} }
} }
else else
UNREACHABLE(); {
ASSERT(!type.isMatrix());
return GL_INT;
}
} }
else if (type.getBasicType() == EbtUInt) else if (type.getBasicType() == EbtUInt)
{ {
if (type.isScalar()) if (type.isVector())
{
return GL_UNSIGNED_INT;
}
else if (type.isVector())
{ {
switch (type.getNominalSize()) switch (type.getNominalSize())
{ {
...@@ -298,15 +291,14 @@ GLenum GLVariableType(const TType &type) ...@@ -298,15 +291,14 @@ GLenum GLVariableType(const TType &type)
} }
} }
else else
UNREACHABLE(); {
ASSERT(!type.isMatrix());
return GL_UNSIGNED_INT;
}
} }
else if (type.getBasicType() == EbtBool) else if (type.getBasicType() == EbtBool)
{ {
if (type.isScalar()) if (type.isVector())
{
return GL_BOOL;
}
else if (type.isVector())
{ {
switch (type.getNominalSize()) switch (type.getNominalSize())
{ {
...@@ -321,7 +313,10 @@ GLenum GLVariableType(const TType &type) ...@@ -321,7 +313,10 @@ GLenum GLVariableType(const TType &type)
} }
} }
else else
UNREACHABLE(); {
ASSERT(!type.isMatrix());
return GL_BOOL;
}
} }
switch (type.getBasicType()) switch (type.getBasicType())
......
...@@ -4029,3 +4029,43 @@ TEST_F(FragmentShaderValidationTest, CaseLabelsWithInvalidTypesDontAssert) ...@@ -4029,3 +4029,43 @@ TEST_F(FragmentShaderValidationTest, CaseLabelsWithInvalidTypesDontAssert)
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog; FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
} }
} }
// Test that using an array as an index is not allowed.
TEST_F(FragmentShaderValidationTest, ArrayAsIndex)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 my_FragColor;\n"
"void main()\n"
"{\n"
" int i[2] = int[2](0, 1);\n"
" float f[2] = float[2](2.0, 3.0);\n"
" my_FragColor = vec4(f[i]);\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Test that using an array as an array size is not allowed.
TEST_F(FragmentShaderValidationTest, ArrayAsArraySize)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 my_FragColor;\n"
"void main()\n"
"{\n"
" const int i[2] = int[2](1, 2);\n"
" float f[i];\n"
" my_FragColor = vec4(f[0]);\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << 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