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 ...@@ -3253,6 +3253,17 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
TFunction *prevDec = TFunction *prevDec =
static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion())); 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 && if (getShaderVersion() >= 300 &&
symbolTable.hasUnmangledBuiltInForShaderVersion(function->getName().c_str(), symbolTable.hasUnmangledBuiltInForShaderVersion(function->getName().c_str(),
getShaderVersion())) getShaderVersion()))
......
...@@ -123,7 +123,8 @@ TType::TType(const TPublicType &p) ...@@ -123,7 +123,8 @@ TType::TType(const TPublicType &p)
primarySize(p.getPrimarySize()), primarySize(p.getPrimarySize()),
secondarySize(p.getSecondarySize()), secondarySize(p.getSecondarySize()),
interfaceBlock(0), interfaceBlock(0),
structure(0) structure(0),
mIsStructSpecifier(false)
{ {
ASSERT(primarySize <= 4); ASSERT(primarySize <= 4);
ASSERT(secondarySize <= 4); ASSERT(secondarySize <= 4);
...@@ -132,7 +133,10 @@ TType::TType(const TPublicType &p) ...@@ -132,7 +133,10 @@ TType::TType(const TPublicType &p)
makeArray(p.arraySize); makeArray(p.arraySize);
} }
if (p.getUserDef()) if (p.getUserDef())
{
structure = p.getUserDef(); structure = p.getUserDef();
mIsStructSpecifier = p.isStructSpecifier();
}
} }
bool TStructure::equals(const TStructure &other) const bool TStructure::equals(const TStructure &other) const
......
...@@ -192,7 +192,8 @@ class TType ...@@ -192,7 +192,8 @@ class TType
primarySize(0), primarySize(0),
secondarySize(0), secondarySize(0),
interfaceBlock(nullptr), interfaceBlock(nullptr),
structure(nullptr) structure(nullptr),
mIsStructSpecifier(false)
{ {
} }
explicit TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1) explicit TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1)
...@@ -205,7 +206,8 @@ class TType ...@@ -205,7 +206,8 @@ class TType
primarySize(ps), primarySize(ps),
secondarySize(ss), secondarySize(ss),
interfaceBlock(0), interfaceBlock(0),
structure(0) structure(0),
mIsStructSpecifier(false)
{ {
} }
TType(TBasicType t, TType(TBasicType t,
...@@ -222,7 +224,8 @@ class TType ...@@ -222,7 +224,8 @@ class TType
primarySize(ps), primarySize(ps),
secondarySize(ss), secondarySize(ss),
interfaceBlock(0), interfaceBlock(0),
structure(0) structure(0),
mIsStructSpecifier(false)
{ {
} }
explicit TType(const TPublicType &p); explicit TType(const TPublicType &p);
...@@ -236,7 +239,8 @@ class TType ...@@ -236,7 +239,8 @@ class TType
primarySize(1), primarySize(1),
secondarySize(1), secondarySize(1),
interfaceBlock(0), interfaceBlock(0),
structure(userDef) structure(userDef),
mIsStructSpecifier(false)
{ {
} }
TType(TInterfaceBlock *interfaceBlockIn, TType(TInterfaceBlock *interfaceBlockIn,
...@@ -251,7 +255,8 @@ class TType ...@@ -251,7 +255,8 @@ class TType
primarySize(1), primarySize(1),
secondarySize(1), secondarySize(1),
interfaceBlock(interfaceBlockIn), interfaceBlock(interfaceBlockIn),
structure(0) structure(0),
mIsStructSpecifier(false)
{ {
} }
...@@ -477,6 +482,8 @@ class TType ...@@ -477,6 +482,8 @@ class TType
return structure ? structure->containsSamplers() : false; return structure ? structure->containsSamplers() : false;
} }
bool isStructSpecifier() const { return mIsStructSpecifier; }
void createSamplerSymbols(const TString &namePrefix, void createSamplerSymbols(const TString &namePrefix,
const TString &apiNamePrefix, const TString &apiNamePrefix,
TVector<TIntermSymbol *> *outputSymbols, TVector<TIntermSymbol *> *outputSymbols,
...@@ -511,6 +518,7 @@ class TType ...@@ -511,6 +518,7 @@ class TType
// 0 unless this is a struct // 0 unless this is a struct
TStructure *structure; TStructure *structure;
bool mIsStructSpecifier;
mutable TString mangled; mutable TString mangled;
}; };
......
...@@ -5222,3 +5222,55 @@ TEST_F(FragmentShaderValidationTest, EmptyStatementInSwitchBeforeFirstCase) ...@@ -5222,3 +5222,55 @@ TEST_F(FragmentShaderValidationTest, EmptyStatementInSwitchBeforeFirstCase)
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog; 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