Commit bb7e5a7c by Olli Etuaho Committed by Commit Bot

GLSL parser: Fix empty declaration qualifier checks

The shader validation now does the same checks for qualifier combinations regardless of if a declaration is empty, as is specified. Some of these checks used to be in singleDeclarationErrorCheck, and have now been moved to a new function declarationQualifierErrorCheck. The other parts of singleDeclarationErrorCheck are under a renamed nonEmptyDeclarationErrorCheck. The patch also contains another related cleanup: Unnecessary symbol nodes won't be created for empty declarations any more. BUG=angleproject:2020 TEST=angle_unittests Change-Id: I1c864a5e151c52703926d8c550450b2561bfcbb2 Reviewed-on: https://chromium-review.googlesource.com/493227 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 6ba99e3d
...@@ -136,9 +136,17 @@ class TParseContext : angle::NonCopyable ...@@ -136,9 +136,17 @@ class TParseContext : angle::NonCopyable
const TTypeQualifierBuilder &typeQualifierBuilder, const TTypeQualifierBuilder &typeQualifierBuilder,
TType *type); TType *type);
bool checkCanUseExtension(const TSourceLoc &line, const TString &extension); bool checkCanUseExtension(const TSourceLoc &line, const TString &extension);
void singleDeclarationErrorCheck(const TPublicType &publicType,
const TSourceLoc &identifierLocation); // Done for all declarations, whether empty or not.
void declarationQualifierErrorCheck(const sh::TQualifier qualifier,
const sh::TLayoutQualifier &layoutQualifier,
const TSourceLoc &location);
// Done for the first non-empty declarator in a declaration.
void nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
const TSourceLoc &identifierLocation);
// Done only for empty declarations.
void emptyDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &location); void emptyDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &location);
void checkLayoutQualifierSupported(const TSourceLoc &location, void checkLayoutQualifierSupported(const TSourceLoc &location,
const TString &layoutQualifierName, const TString &layoutQualifierName,
int versionRequired); int versionRequired);
...@@ -433,8 +441,10 @@ class TParseContext : angle::NonCopyable ...@@ -433,8 +441,10 @@ class TParseContext : angle::NonCopyable
const TSourceLoc &location, const TSourceLoc &location,
bool insertParametersToSymbolTable); bool insertParametersToSymbolTable);
// Set to true when the last/current declarator list was started with an empty declaration. // Set to true when the last/current declarator list was started with an empty declaration. The
bool mDeferredSingleDeclarationErrorCheck; // non-empty declaration error check will need to be performed if the empty declaration is
// followed by a declarator.
bool mDeferredNonEmptyDeclarationErrorCheck;
sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack) sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack)
ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
......
...@@ -2345,6 +2345,22 @@ TEST_F(FragmentShaderValidationTest, InvariantNonOuput) ...@@ -2345,6 +2345,22 @@ TEST_F(FragmentShaderValidationTest, InvariantNonOuput)
} }
} }
// Invariant cannot be used with a non-output variable in ESSL3.
// ESSL 3.00.6 section 4.8: This applies even if the declaration is empty.
TEST_F(FragmentShaderValidationTest, InvariantNonOuputEmptyDeclaration)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"invariant in float;\n"
"void main() {}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Invariant declaration should follow the following format "invariant <out variable name>". // Invariant declaration should follow the following format "invariant <out variable name>".
// Test having an incorrect qualifier in the invariant declaration. // Test having an incorrect qualifier in the invariant declaration.
TEST_F(FragmentShaderValidationTest, InvariantDeclarationWithStorageQualifier) TEST_F(FragmentShaderValidationTest, InvariantDeclarationWithStorageQualifier)
...@@ -3729,3 +3745,20 @@ TEST_F(FragmentShaderValidationTest, ConstructStructContainingVoidArray) ...@@ -3729,3 +3745,20 @@ TEST_F(FragmentShaderValidationTest, ConstructStructContainingVoidArray)
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog; FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
} }
} }
// Uniforms can't have location in ESSL 3.00.
// Test this with an empty declaration (ESSL 3.00.6 section 4.8: The combinations of qualifiers that
// cause compile-time or link-time errors are the same whether or not the declaration is empty).
TEST_F(FragmentShaderValidationTest, UniformLocationEmptyDeclaration)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"layout(location=0) uniform float;\n"
"void main() {}\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