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/727802
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ValidateSwitch.cpp b/src/compiler/translator/ValidateSwitch.cpp
index bc9ba34..9f7a264 100644
--- a/src/compiler/translator/ValidateSwitch.cpp
+++ b/src/compiler/translator/ValidateSwitch.cpp
@@ -19,6 +19,7 @@
 {
   public:
     static bool validate(TBasicType switchType,
+                         int shaderVersion,
                          TDiagnostics *diagnostics,
                          TIntermBlock *statementList,
                          const TSourceLoc &loc);
@@ -39,11 +40,12 @@
     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 @@
 };
 
 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 @@
     {
         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