diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp index 626b5ecf49..5d2571c77a 100644 --- a/src/sksl/SkSLCompiler.cpp +++ b/src/sksl/SkSLCompiler.cpp @@ -1070,6 +1070,21 @@ static bool contains_unconditional_break(Statement& s) { } } +static void copy_all_but_break(std::unique_ptr& stmt, + std::vector*>* target) { + switch (stmt->fKind) { + case Statement::kBlock_Kind: + for (auto& s : ((Block&) *stmt).fStatements) { + copy_all_but_break(s, target); + } + break; + case Statement::kBreak_Kind: + return; + default: + target->push_back(&stmt); + } +} + // Returns a block containing all of the statements that will be run if the given case matches // (which, owing to the statements being owned by unique_ptrs, means the switch itself will be // broken by this call and must then be discarded). @@ -1089,6 +1104,7 @@ static std::unique_ptr block_for_case(SwitchStatement* s, SwitchCase* } if (contains_unconditional_break(*stmt)) { capturing = false; + copy_all_but_break(stmt, &statementPtrs); break; } statementPtrs.push_back(&stmt); diff --git a/tests/SkSLGLSLTest.cpp b/tests/SkSLGLSLTest.cpp index a83e2e88e6..b6dbe236e9 100644 --- a/tests/SkSLGLSLTest.cpp +++ b/tests/SkSLGLSLTest.cpp @@ -1635,6 +1635,75 @@ DEF_TEST(SkSLSwitch, r) { " }\n" " sk_FragColor = vec4(x);\n" "}\n"); + // static test w/ break in a block + test(r, + "void main() {" + " float x = 0.0;" + " switch (0) {" + " case 0: {" + " x = 0.0;" + " sk_FragColor = half4(half(x));" + " break;" + " }" + " case 1:" + " x = 1.0;" + " }" + "}", + *SkSL::ShaderCapsFactory::Default(), + "#version 400\n" + "out vec4 sk_FragColor;\n" + "void main() {\n" + " {\n" + " sk_FragColor = vec4(0.0);\n" + " }\n" + "}\n"); + // static test w/ static conditional break in a block + test(r, + "void main() {" + " float x = 0.0;" + " switch (0) {" + " case 0:" + " x = 0.0;" + " if (x < 1) { sk_FragColor = half4(half(x)); break; }" + " case 1:" + " x = 1.0;" + " }" + "}", + *SkSL::ShaderCapsFactory::Default(), + "#version 400\n" + "out vec4 sk_FragColor;\n" + "void main() {\n" + " {\n" + " sk_FragColor = vec4(0.0);\n" + " }\n" + "}\n"); + // static test w/ non-static conditional break in a block + test(r, + "void main() {" + " float x = 0.0;" + " switch (0) {" + " case 0:" + " x = 0.0;" + " if (x < sqrt(1)) { sk_FragColor = half4(half(x)); break; }" + " case 1:" + " x = 1.0;" + " }" + "}", + *SkSL::ShaderCapsFactory::Default(), + "#version 400\n" + "out vec4 sk_FragColor;\n" + "void main() {\n" + " switch (0) {\n" + " case 0:\n" + " ;\n" + " if (0.0 < sqrt(1.0)) {\n" + " sk_FragColor = vec4(0.0);\n" + " break;\n" + " }\n" + " case 1:\n" + " ;\n" + " }\n" + "}\n"); } DEF_TEST(SkSLRectangleTexture, r) {