Fix HLSL for switch statements that don't end in a branch

In case the last case inside a switch statement is not terminated in
a branch statement, RemoveSwitchFallThrough needs to add it before
calling handlePreviousCase. This ensures that all preceding
fall-through cases will get a copy of the branch statement and so will
not fall through.

This also fixes running RemoveSwitchFallThrough so that it's only
executed once per each switch statement.

The error was not caught by the dEQP tests, so a new ANGLE test is
added.

BUG=angleproject:2178
TEST=angle_end2end_tests

Change-Id: I26b6989aa4d32de2d74cde56d72ee24f61195445
Reviewed-on: https://chromium-review.googlesource.com/709196
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index d5e1495..8773962 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -3499,6 +3499,45 @@
     ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
 }
 
+// Test that switch fall-through works correctly.
+// This is a regression test for http://anglebug.com/2178
+TEST_P(GLSLTest_ES3, SwitchFallThroughCodeDuplication)
+{
+    const std::string &fragmentShader =
+        R"(#version 300 es
+
+        precision highp float;
+
+        out vec4 my_FragColor;
+
+        uniform int u_zero;
+
+        void main()
+        {
+            int i = 0;
+            // switch should fall through both cases.
+            switch(u_zero)
+            {
+                case 0:
+                    i += 1;
+                case 1:
+                    i += 2;
+            }
+            if (i == 3)
+            {
+                my_FragColor = vec4(0, 1, 0, 1);
+            }
+            else
+            {
+                my_FragColor = vec4(1, 0, 0, 1);
+            }
+        })";
+
+    ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader);
+    drawQuad(program.get(), "inputAttribute", 0.5f);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(GLSLTest,
                        ES2_D3D9(),