Commit 9405005f by Olli Etuaho Committed by Commit Bot

Disallow interface blocks in arithmetic expressions

Interface blocks were mistakenly being allowed in some types of unary, binary and ternary expressions, when they should not have been. BUG=angleproject:2030 TEST=angle_unittests Change-Id: Ie75833ee208e1b7fef8f77fa91b90da278bc6498 Reviewed-on: https://chromium-review.googlesource.com/500269Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent cbd14085
......@@ -3688,8 +3688,9 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
case EOpPreDecrement:
case EOpNegative:
case EOpPositive:
if (child->getBasicType() == EbtStruct || child->getBasicType() == EbtBool ||
child->isArray() || IsOpaqueType(child->getBasicType()))
if (child->getBasicType() == EbtStruct || child->isInterfaceBlock() ||
child->getBasicType() == EbtBool || child->isArray() ||
IsOpaqueType(child->getBasicType()))
{
unaryOpError(loc, GetOperatorString(op), child->getCompleteString());
return nullptr;
......@@ -3773,6 +3774,19 @@ bool TParseContext::binaryOpCommonCheck(TOperator op,
}
}
if (left->isInterfaceBlock() || right->isInterfaceBlock())
{
switch (op)
{
case EOpIndexDirectInterfaceBlock:
ASSERT(left->getType().getInterfaceBlock());
break;
default:
error(loc, "Invalid operation for interface blocks", GetOperatorString(op));
return false;
}
}
if (left->isArray() || right->isArray())
{
if (mShaderVersion < 300)
......@@ -4532,6 +4546,12 @@ TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
error(loc, "ternary operator is not allowed for structures or arrays", ":");
return falseExpression;
}
if (trueExpression->getBasicType() == EbtInterfaceBlock)
{
error(loc, "ternary operator is not allowed for interface blocks", ":");
return falseExpression;
}
// WebGL2 section 5.26, the following results in an error:
// "Ternary operator applied to void, arrays, or structs containing arrays"
if (mShaderSpec == SH_WEBGL2_SPEC && trueExpression->getBasicType() == EbtVoid)
......
......@@ -3797,3 +3797,64 @@ TEST_F(FragmentShaderValidationTest, InvalidExpressionForSamplerOperands)
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Test interface blocks as invalid operands to a binary expression.
TEST_F(FragmentShaderValidationTest, InvalidInterfaceBlockBinaryExpression)
{
const std::string &shaderString =
"#version 300 es\n"
"uniform U\n"
"{\n"
" int foo; \n"
"} u;\n"
"void main()\n"
"{\n"
" u + u;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Test interface block as an invalid operand to an unary expression.
TEST_F(FragmentShaderValidationTest, InvalidInterfaceBlockUnaryExpression)
{
const std::string &shaderString =
"#version 300 es\n"
"uniform U\n"
"{\n"
" int foo; \n"
"} u;\n"
"void main()\n"
"{\n"
" +u;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Test interface block as an invalid operand to a ternary expression.
// Note that the spec is not very explicit on this, but it makes sense to forbid this.
TEST_F(FragmentShaderValidationTest, InvalidInterfaceBlockTernaryExpression)
{
const std::string &shaderString =
"#version 300 es\n"
"uniform U\n"
"{\n"
" int foo; \n"
"} u;\n"
"void main()\n"
"{\n"
" true ? u : u;\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