Commit d05f964b by Olli Etuaho Committed by Commit Bot

Last case in switch statement can't be empty in ESSL 3.10

This is based on recent discussion in Khronos, though public specs have not yet been updated to reflect this. BUG=angleproject:2388 TEST=angle_unittests Change-Id: I66a0d03b3c2bb9740772a813b543f8f6c6bb2a28 Reviewed-on: https://chromium-review.googlesource.com/947977Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent dc0cdba8
...@@ -4840,7 +4840,7 @@ TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, ...@@ -4840,7 +4840,7 @@ TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
} }
ASSERT(statementList); ASSERT(statementList);
if (!ValidateSwitchStatementList(switchType, mShaderVersion, mDiagnostics, statementList, loc)) if (!ValidateSwitchStatementList(switchType, mDiagnostics, statementList, loc))
{ {
ASSERT(mDiagnostics->numErrors() > 0); ASSERT(mDiagnostics->numErrors() > 0);
return nullptr; return nullptr;
......
...@@ -19,7 +19,6 @@ class ValidateSwitch : public TIntermTraverser ...@@ -19,7 +19,6 @@ class ValidateSwitch : public TIntermTraverser
{ {
public: public:
static bool validate(TBasicType switchType, static bool validate(TBasicType switchType,
int shaderVersion,
TDiagnostics *diagnostics, TDiagnostics *diagnostics,
TIntermBlock *statementList, TIntermBlock *statementList,
const TSourceLoc &loc); const TSourceLoc &loc);
...@@ -40,12 +39,11 @@ class ValidateSwitch : public TIntermTraverser ...@@ -40,12 +39,11 @@ class ValidateSwitch : public TIntermTraverser
bool visitBranch(Visit, TIntermBranch *) override; bool visitBranch(Visit, TIntermBranch *) override;
private: private:
ValidateSwitch(TBasicType switchType, int shaderVersion, TDiagnostics *context); ValidateSwitch(TBasicType switchType, TDiagnostics *context);
bool validateInternal(const TSourceLoc &loc); bool validateInternal(const TSourceLoc &loc);
TBasicType mSwitchType; TBasicType mSwitchType;
int mShaderVersion;
TDiagnostics *mDiagnostics; TDiagnostics *mDiagnostics;
bool mCaseTypeMismatch; bool mCaseTypeMismatch;
bool mFirstCaseFound; bool mFirstCaseFound;
...@@ -60,21 +58,19 @@ class ValidateSwitch : public TIntermTraverser ...@@ -60,21 +58,19 @@ class ValidateSwitch : public TIntermTraverser
}; };
bool ValidateSwitch::validate(TBasicType switchType, bool ValidateSwitch::validate(TBasicType switchType,
int shaderVersion,
TDiagnostics *diagnostics, TDiagnostics *diagnostics,
TIntermBlock *statementList, TIntermBlock *statementList,
const TSourceLoc &loc) const TSourceLoc &loc)
{ {
ValidateSwitch validate(switchType, shaderVersion, diagnostics); ValidateSwitch validate(switchType, diagnostics);
ASSERT(statementList); ASSERT(statementList);
statementList->traverse(&validate); statementList->traverse(&validate);
return validate.validateInternal(loc); return validate.validateInternal(loc);
} }
ValidateSwitch::ValidateSwitch(TBasicType switchType, int shaderVersion, TDiagnostics *diagnostics) ValidateSwitch::ValidateSwitch(TBasicType switchType, TDiagnostics *diagnostics)
: TIntermTraverser(true, false, true), : TIntermTraverser(true, false, true),
mSwitchType(switchType), mSwitchType(switchType),
mShaderVersion(shaderVersion),
mDiagnostics(diagnostics), mDiagnostics(diagnostics),
mCaseTypeMismatch(false), mCaseTypeMismatch(false),
mFirstCaseFound(false), mFirstCaseFound(false),
...@@ -281,39 +277,27 @@ bool ValidateSwitch::validateInternal(const TSourceLoc &loc) ...@@ -281,39 +277,27 @@ bool ValidateSwitch::validateInternal(const TSourceLoc &loc)
{ {
mDiagnostics->error(loc, "statement before the first label", "switch"); mDiagnostics->error(loc, "statement before the first label", "switch");
} }
bool lastStatementWasCaseError = false;
if (mLastStatementWasCase) if (mLastStatementWasCase)
{ {
if (mShaderVersion == 300) // There have been some differences between versions of GLSL ES specs on whether this should
{ // be an error or not, but as of early 2018 the latest discussion is that this is an error
lastStatementWasCaseError = true; // also on GLSL ES versions newer than 3.00.
// This error has been proposed to be made optional in GLSL ES 3.00, but dEQP tests mDiagnostics->error(
// still require it. loc, "no statement between the last label and the end of the switch statement",
mDiagnostics->error( "switch");
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 && !lastStatementWasCaseError && !mCaseInsideControlFlow && return !mStatementBeforeCase && !mLastStatementWasCase && !mCaseInsideControlFlow &&
!mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases; !mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases;
} }
} // anonymous namespace } // anonymous namespace
bool ValidateSwitchStatementList(TBasicType switchType, bool ValidateSwitchStatementList(TBasicType switchType,
int shaderVersion,
TDiagnostics *diagnostics, TDiagnostics *diagnostics,
TIntermBlock *statementList, TIntermBlock *statementList,
const TSourceLoc &loc) const TSourceLoc &loc)
{ {
return ValidateSwitch::validate(switchType, shaderVersion, diagnostics, statementList, loc); return ValidateSwitch::validate(switchType, diagnostics, statementList, loc);
} }
} // namespace sh } // namespace sh
...@@ -18,7 +18,6 @@ class TIntermBlock; ...@@ -18,7 +18,6 @@ class TIntermBlock;
// Check for errors and output error messages on the context. // Check for errors and output error messages on the context.
// Returns true if there are no errors. // Returns true if there are no errors.
bool ValidateSwitchStatementList(TBasicType switchType, bool ValidateSwitchStatementList(TBasicType switchType,
int shaderVersion,
TDiagnostics *diagnostics, TDiagnostics *diagnostics,
TIntermBlock *statementList, TIntermBlock *statementList,
const TSourceLoc &loc); const TSourceLoc &loc);
......
...@@ -5069,7 +5069,8 @@ TEST_F(FragmentShaderValidationTest, SwitchFinalCaseHasEmptyDeclaration) ...@@ -5069,7 +5069,8 @@ TEST_F(FragmentShaderValidationTest, SwitchFinalCaseHasEmptyDeclaration)
} }
} }
// Test that nothing is needed after the final case in a switch statement in ESSL 3.10. // The final case in a switch statement can't be empty in ESSL 3.10 either. This is the intent of
// the spec though public spec in early 2018 didn't reflect this yet.
TEST_F(FragmentShaderValidationTest, SwitchFinalCaseEmptyESSL310) TEST_F(FragmentShaderValidationTest, SwitchFinalCaseEmptyESSL310)
{ {
const std::string &shaderString = const std::string &shaderString =
...@@ -5087,9 +5088,9 @@ TEST_F(FragmentShaderValidationTest, SwitchFinalCaseEmptyESSL310) ...@@ -5087,9 +5088,9 @@ TEST_F(FragmentShaderValidationTest, SwitchFinalCaseEmptyESSL310)
} }
})"; })";
if (!compile(shaderString)) if (compile(shaderString))
{ {
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog; 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