Commit d80f2944 by Olli Etuaho Committed by Commit Bot

Struct definition not allowed as function parameter type

Struct definitions are not allowed as a function parameter type now. This is specified in ESSL 3.00.6 section 12.10. ESSL 3.00.6 section 6.1.1 contradicts this, but that seems like a mistake, it's been fixed in subsequent spec versions. BUG=angleproject:2225 TEST=angle_unittests Change-Id: I6b97d120c440f0c0a45d31bbfaf292fb497160ce Reviewed-on: https://chromium-review.googlesource.com/754606Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 977abce7
......@@ -3253,6 +3253,17 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
TFunction *prevDec =
static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));
for (size_t i = 0u; i < function->getParamCount(); ++i)
{
auto &param = function->getParam(i);
if (param.type->isStructSpecifier())
{
// ESSL 3.00.6 section 12.10.
error(location, "Function parameter type cannot be a structure definition",
param.name->c_str());
}
}
if (getShaderVersion() >= 300 &&
symbolTable.hasUnmangledBuiltInForShaderVersion(function->getName().c_str(),
getShaderVersion()))
......
......@@ -123,7 +123,8 @@ TType::TType(const TPublicType &p)
primarySize(p.getPrimarySize()),
secondarySize(p.getSecondarySize()),
interfaceBlock(0),
structure(0)
structure(0),
mIsStructSpecifier(false)
{
ASSERT(primarySize <= 4);
ASSERT(secondarySize <= 4);
......@@ -132,7 +133,10 @@ TType::TType(const TPublicType &p)
makeArray(p.arraySize);
}
if (p.getUserDef())
{
structure = p.getUserDef();
mIsStructSpecifier = p.isStructSpecifier();
}
}
bool TStructure::equals(const TStructure &other) const
......
......@@ -192,7 +192,8 @@ class TType
primarySize(0),
secondarySize(0),
interfaceBlock(nullptr),
structure(nullptr)
structure(nullptr),
mIsStructSpecifier(false)
{
}
explicit TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1)
......@@ -205,7 +206,8 @@ class TType
primarySize(ps),
secondarySize(ss),
interfaceBlock(0),
structure(0)
structure(0),
mIsStructSpecifier(false)
{
}
TType(TBasicType t,
......@@ -222,7 +224,8 @@ class TType
primarySize(ps),
secondarySize(ss),
interfaceBlock(0),
structure(0)
structure(0),
mIsStructSpecifier(false)
{
}
explicit TType(const TPublicType &p);
......@@ -236,7 +239,8 @@ class TType
primarySize(1),
secondarySize(1),
interfaceBlock(0),
structure(userDef)
structure(userDef),
mIsStructSpecifier(false)
{
}
TType(TInterfaceBlock *interfaceBlockIn,
......@@ -251,7 +255,8 @@ class TType
primarySize(1),
secondarySize(1),
interfaceBlock(interfaceBlockIn),
structure(0)
structure(0),
mIsStructSpecifier(false)
{
}
......@@ -477,6 +482,8 @@ class TType
return structure ? structure->containsSamplers() : false;
}
bool isStructSpecifier() const { return mIsStructSpecifier; }
void createSamplerSymbols(const TString &namePrefix,
const TString &apiNamePrefix,
TVector<TIntermSymbol *> *outputSymbols,
......@@ -511,6 +518,7 @@ class TType
// 0 unless this is a struct
TStructure *structure;
bool mIsStructSpecifier;
mutable TString mangled;
};
......
......@@ -5222,3 +5222,55 @@ TEST_F(FragmentShaderValidationTest, EmptyStatementInSwitchBeforeFirstCase)
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Test that a nameless struct definition is not allowed as a function parameter type.
// ESSL 3.00.6 section 12.10. ESSL 3.10 January 2016 section 13.10.
TEST_F(FragmentShaderValidationTest, NamelessStructDefinitionAsParameterType)
{
const std::string &shaderString =
R"(#version 300 es
precision highp float;
out vec4 my_FragColor;
float foo(struct { float field; } f)
{
return f.field;
}
void main()
{
my_FragColor = vec4(0, 1, 0, 1);
})";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Test that a named struct definition is not allowed as a function parameter type.
// ESSL 3.00.6 section 12.10. ESSL 3.10 January 2016 section 13.10.
TEST_F(FragmentShaderValidationTest, NamedStructDefinitionAsParameterType)
{
const std::string &shaderString =
R"(#version 300 es
precision highp float;
out vec4 my_FragColor;
float foo(struct S { float field; } f)
{
return f.field;
}
void main()
{
my_FragColor = vec4(0, 1, 0, 1);
})";
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