Disallow invariant(all) pragma in ESSL 3.00 fragment shaders

ESSL 3.00.4 section 4.6.1 says that using #pragma STDGL invariant(all)
in a fragment shader is an error, so make it an error. This spec
language is not found in ESSL 1.00, and it's been removed in ESSL 3.10.

BUG=angleproject:1276
TEST=angle_unittests

Change-Id: I2022f35475f867304b55dfb142f8568f6df28830
Reviewed-on: https://chromium-review.googlesource.com/321240
Tryjob-Request: Olli Etuaho <oetuaho@nvidia.com>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
diff --git a/src/compiler/translator/DirectiveHandler.cpp b/src/compiler/translator/DirectiveHandler.cpp
index 084c22d..ff8a69e 100644
--- a/src/compiler/translator/DirectiveHandler.cpp
+++ b/src/compiler/translator/DirectiveHandler.cpp
@@ -8,6 +8,7 @@
 
 #include <sstream>
 
+#include "angle_gl.h"
 #include "common/debug.h"
 #include "compiler/translator/Diagnostics.h"
 
@@ -25,13 +26,15 @@
     return EBhUndefined;
 }
 
-TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
-                                     TDiagnostics& diagnostics,
-                                     int& shaderVersion,
+TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
+                                     TDiagnostics &diagnostics,
+                                     int &shaderVersion,
+                                     sh::GLenum shaderType,
                                      bool debugShaderPrecisionSupported)
     : mExtensionBehavior(extBehavior),
       mDiagnostics(diagnostics),
       mShaderVersion(shaderVersion),
+      mShaderType(shaderType),
       mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
 {
 }
@@ -57,7 +60,16 @@
         const char kAll[] = "all";
 
         if (name == kInvariant && value == kAll)
+        {
+            if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
+            {
+                // ESSL 3.00.4 section 4.6.1
+                mDiagnostics.writeInfo(
+                    pp::Diagnostics::PP_ERROR, loc,
+                    "#pragma STDGL invariant(all) can not be used in fragment shader", name, value);
+            }
             mPragma.stdgl.invariantAll = true;
+        }
         // The STDGL pragma is used to reserve pragmas for use by future
         // revisions of GLSL.  Do not generate an error on unexpected
         // name and value.
diff --git a/src/compiler/translator/DirectiveHandler.h b/src/compiler/translator/DirectiveHandler.h
index 5f98ac7..00eb491 100644
--- a/src/compiler/translator/DirectiveHandler.h
+++ b/src/compiler/translator/DirectiveHandler.h
@@ -11,15 +11,17 @@
 #include "compiler/translator/ExtensionBehavior.h"
 #include "compiler/translator/Pragma.h"
 #include "compiler/preprocessor/DirectiveHandlerBase.h"
+#include "GLSLANG/ShaderLang.h"
 
 class TDiagnostics;
 
 class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
 {
   public:
-    TDirectiveHandler(TExtensionBehavior& extBehavior,
-                      TDiagnostics& diagnostics,
-                      int& shaderVersion,
+    TDirectiveHandler(TExtensionBehavior &extBehavior,
+                      TDiagnostics &diagnostics,
+                      int &shaderVersion,
+                      sh::GLenum shaderType,
                       bool debugShaderPrecisionSupported);
     ~TDirectiveHandler() override;
 
@@ -44,6 +46,7 @@
     TExtensionBehavior& mExtensionBehavior;
     TDiagnostics& mDiagnostics;
     int& mShaderVersion;
+    sh::GLenum mShaderType;
     bool mDebugShaderPrecisionSupported;
 };
 
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 97872de..1eaf1e5 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -57,6 +57,7 @@
           mDirectiveHandler(ext,
                             mDiagnostics,
                             mShaderVersion,
+                            mShaderType,
                             resources.WEBGL_debug_shader_precision == 1),
           mPreprocessor(&mDiagnostics, &mDirectiveHandler),
           mScanner(nullptr),
diff --git a/src/tests/compiler_tests/MalformedShader_test.cpp b/src/tests/compiler_tests/MalformedShader_test.cpp
index fde3a6f..b072834 100644
--- a/src/tests/compiler_tests/MalformedShader_test.cpp
+++ b/src/tests/compiler_tests/MalformedShader_test.cpp
@@ -1513,3 +1513,22 @@
         FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
     }
 }
+
+// ESSL 3.00 fragment shaders can not use #pragma STDGL invariant(all).
+// ESSL 3.00.4 section 4.6.1. Does not apply to other versions of ESSL.
+TEST_F(MalformedShaderTest, ESSL300FragmentInvariantAll)
+{
+    const std::string &shaderString =
+        "#version 300 es\n"
+        "#pragma STDGL invariant(all)\n"
+        "precision mediump float;\n"
+        "out vec4 my_FragColor;\n"
+        "void main()\n"
+        "{\n"
+        "    my_FragColor = vec4(0.0);\n"
+        "}\n";
+    if (compile(shaderString))
+    {
+        FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
+    }
+}