Commit cbcb96fc by Olli Etuaho Committed by Commit Bot

Fix switch/case last case validation for ESSL 3.10

No statement should be required after the last case label of a switch statement in ESSL 3.10. The validation is still kept for ESSL 3.00 for dEQP compatibility. If the dEQP tests are changed in the future, we might consider just issuing a warning regardless of shader version. BUG=angleproject:2189 TEST=angle_unittests Change-Id: Ic53e71e0176668a7dbffa315712885846e217f03 Reviewed-on: https://chromium-review.googlesource.com/727802Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 6dee4d8c
......@@ -4640,8 +4640,9 @@ TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
}
ASSERT(statementList);
if (!ValidateSwitchStatementList(switchType, mDiagnostics, statementList, loc))
if (!ValidateSwitchStatementList(switchType, mShaderVersion, mDiagnostics, statementList, loc))
{
ASSERT(mDiagnostics->numErrors() > 0);
return nullptr;
}
......
......@@ -19,6 +19,7 @@ class ValidateSwitch : public TIntermTraverser
{
public:
static bool validate(TBasicType switchType,
int shaderVersion,
TDiagnostics *diagnostics,
TIntermBlock *statementList,
const TSourceLoc &loc);
......@@ -39,11 +40,12 @@ class ValidateSwitch : public TIntermTraverser
bool visitBranch(Visit, TIntermBranch *) override;
private:
ValidateSwitch(TBasicType switchType, TDiagnostics *context);
ValidateSwitch(TBasicType switchType, int shaderVersion, TDiagnostics *context);
bool validateInternal(const TSourceLoc &loc);
TBasicType mSwitchType;
int mShaderVersion;
TDiagnostics *mDiagnostics;
bool mCaseTypeMismatch;
bool mFirstCaseFound;
......@@ -58,19 +60,21 @@ class ValidateSwitch : public TIntermTraverser
};
bool ValidateSwitch::validate(TBasicType switchType,
int shaderVersion,
TDiagnostics *diagnostics,
TIntermBlock *statementList,
const TSourceLoc &loc)
{
ValidateSwitch validate(switchType, diagnostics);
ValidateSwitch validate(switchType, shaderVersion, diagnostics);
ASSERT(statementList);
statementList->traverse(&validate);
return validate.validateInternal(loc);
}
ValidateSwitch::ValidateSwitch(TBasicType switchType, TDiagnostics *diagnostics)
ValidateSwitch::ValidateSwitch(TBasicType switchType, int shaderVersion, TDiagnostics *diagnostics)
: TIntermTraverser(true, false, true),
mSwitchType(switchType),
mShaderVersion(shaderVersion),
mDiagnostics(diagnostics),
mCaseTypeMismatch(false),
mFirstCaseFound(false),
......@@ -277,24 +281,39 @@ bool ValidateSwitch::validateInternal(const TSourceLoc &loc)
{
mDiagnostics->error(loc, "statement before the first label", "switch");
}
bool lastStatementWasCaseError = false;
if (mLastStatementWasCase)
{
mDiagnostics->error(
loc, "no statement between the last label and the end of the switch statement",
"switch");
if (mShaderVersion == 300)
{
lastStatementWasCaseError = true;
// This error has been proposed to be made optional in GLSL ES 3.00, but dEQP tests
// still require it.
mDiagnostics->error(
loc, "no statement between the last label and the end of the switch statement",
"switch");
}
else
{
// The error has been removed from GLSL ES 3.10.
mDiagnostics->warning(
loc, "no statement between the last label and the end of the switch statement",
"switch");
}
}
return !mStatementBeforeCase && !mLastStatementWasCase && !mCaseInsideControlFlow &&
return !mStatementBeforeCase && !lastStatementWasCaseError && !mCaseInsideControlFlow &&
!mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases;
}
} // anonymous namespace
bool ValidateSwitchStatementList(TBasicType switchType,
int shaderVersion,
TDiagnostics *diagnostics,
TIntermBlock *statementList,
const TSourceLoc &loc)
{
return ValidateSwitch::validate(switchType, diagnostics, statementList, loc);
return ValidateSwitch::validate(switchType, shaderVersion, diagnostics, statementList, loc);
}
} // namespace sh
......@@ -18,6 +18,7 @@ class TIntermBlock;
// Check for errors and output error messages on the context.
// Returns true if there are no errors.
bool ValidateSwitchStatementList(TBasicType switchType,
int shaderVersion,
TDiagnostics *diagnostics,
TIntermBlock *statementList,
const TSourceLoc &loc);
......
......@@ -5063,3 +5063,27 @@ TEST_F(FragmentShaderValidationTest, SwitchFinalCaseHasEmptyDeclaration)
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
}
}
// Test that nothing is needed after the final case in a switch statement in ESSL 3.10.
TEST_F(FragmentShaderValidationTest, SwitchFinalCaseEmptyESSL310)
{
const std::string &shaderString =
R"(#version 310 es
precision mediump float;
uniform int i;
void main()
{
switch (i)
{
case 0:
break;
default:
}
})";
if (!compile(shaderString))
{
FAIL() << "Shader compilation failed, expecting success:\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