Change remaining compile-time folding errors to warnings

The GLES working group has decided to amend the spec so that
implementations are not allowed to generate compile errors on
undefined values detected at compile time. Change the remaining
folding errors to warnings to follow the newly clarified rules.

The end2end_tests covering this are removed, since they're
redundant with the more efficient unit test.

BUG=angleproject:1703
TEST=angle_unittests

Change-Id: I97d2fd532dbe5733581bdc4aa40a5d7d3734fc0d
Reviewed-on: https://chromium-review.googlesource.com/427799
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ConstantUnion.cpp b/src/compiler/translator/ConstantUnion.cpp
index cab1031..464c30c 100644
--- a/src/compiler/translator/ConstantUnion.cpp
+++ b/src/compiler/translator/ConstantUnion.cpp
@@ -58,6 +58,12 @@
     return result;
 }
 
+bool IsValidShiftOffset(const TConstantUnion &rhs)
+{
+    return (rhs.getType() == EbtInt && (rhs.getIConst() >= 0 && rhs.getIConst() <= 31)) ||
+           (rhs.getType() == EbtUInt && rhs.getUConst() <= 31u);
+}
+
 }  // anonymous namespace
 
 TConstantUnion::TConstantUnion()
@@ -377,10 +383,9 @@
     TConstantUnion returnValue;
     ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
     ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
-    if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) ||
-        (rhs.type == EbtUInt && rhs.uConst > 31u))
+    if (!IsValidShiftOffset(rhs))
     {
-        diag->error(line, "Undefined shift (operand out of range)", ">>");
+        diag->warning(line, "Undefined shift (operand out of range)", ">>");
         switch (lhs.type)
         {
             case EbtInt:
@@ -484,10 +489,9 @@
     TConstantUnion returnValue;
     ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt);
     ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt);
-    if ((rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) ||
-        (rhs.type == EbtUInt && rhs.uConst > 31u))
+    if (!IsValidShiftOffset(rhs))
     {
-        diag->error(line, "Undefined shift (operand out of range)", "<<");
+        diag->warning(line, "Undefined shift (operand out of range)", "<<");
         switch (lhs.type)
         {
             case EbtInt:
diff --git a/src/tests/compiler_tests/ShaderValidation_test.cpp b/src/tests/compiler_tests/ShaderValidation_test.cpp
index a120b75..1786cf0 100644
--- a/src/tests/compiler_tests/ShaderValidation_test.cpp
+++ b/src/tests/compiler_tests/ShaderValidation_test.cpp
@@ -2413,7 +2413,8 @@
     }
 }
 
-// Bit shift with a rhs value > 31 has an undefined result in the GLSL spec. We disallow it.
+// Bit shift with a rhs value > 31 has an undefined result in the GLSL spec. Detecting an undefined
+// result at compile time should not generate an error either way.
 // ESSL 3.00.6 section 5.9.
 TEST_F(FragmentShaderValidationTest, ShiftBy32)
 {
@@ -2425,7 +2426,40 @@
         "}\n";
     if (compile(shaderString))
     {
-        FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
+        if (!hasWarning())
+        {
+            FAIL() << "Shader compilation succeeded without warnings, expecting warning:\n"
+                   << mInfoLog;
+        }
+    }
+    else
+    {
+        FAIL() << "Shader compilation failed, expecting success with warning:\n" << mInfoLog;
+    }
+}
+
+// Bit shift with a rhs value < 0 has an undefined result in the GLSL spec. Detecting an undefined
+// result at compile time should not generate an error either way.
+// ESSL 3.00.6 section 5.9.
+TEST_F(FragmentShaderValidationTest, ShiftByNegative)
+{
+    const std::string &shaderString =
+        "#version 300 es\n"
+        "precision mediump float;\n"
+        "void main() {\n"
+        "   uint u = 1u << (-1);\n"
+        "}\n";
+    if (compile(shaderString))
+    {
+        if (!hasWarning())
+        {
+            FAIL() << "Shader compilation succeeded without warnings, expecting warning:\n"
+                   << mInfoLog;
+        }
+    }
+    else
+    {
+        FAIL() << "Shader compilation failed, expecting success with warning:\n" << mInfoLog;
     }
 }
 
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index d24253a..31a9b15 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -2378,42 +2378,6 @@
     ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
 }
 
-// Test that using an invalid constant right-shift produces an error.
-TEST_P(GLSLTest_ES3, FoldedInvalidRightShift)
-{
-    const std::string &fragmentShader =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "out vec4 color;\n"
-        "void main(void)\n"
-        "{\n"
-        " int diff = -100 >> -100;\n"
-        " color = vec4(float(diff));\n"
-        "}\n";
-
-    GLuint program = CompileProgram(mSimpleVSSource, fragmentShader);
-    EXPECT_EQ(0u, program);
-    glDeleteProgram(program);
-}
-
-// Test that using an invalid constant left-shift produces an error.
-TEST_P(GLSLTest_ES3, FoldedInvalidLeftShift)
-{
-    const std::string &fragmentShader =
-        "#version 300 es\n"
-        "precision mediump float;\n"
-        "out vec4 color;\n"
-        "void main(void)\n"
-        "{\n"
-        " int diff = -100 << -100;\n"
-        " color = vec4(float(diff));\n"
-        "}\n";
-
-    GLuint program = CompileProgram(mSimpleVSSource, fragmentShader);
-    EXPECT_EQ(0u, program);
-    glDeleteProgram(program);
-}
-
 // Test that literal infinity can be written out from the shader translator.
 // A similar test can't be made for NaNs, since ESSL 3.00.6 requirements for NaNs are very loose.
 TEST_P(GLSLTest_ES3, LiteralInfinityOutput)