Recognize more non-fallthrough cases in switch/case
RemoveSwitchFallThrough now treats cases where break; or return; is
nested inside a block as non-fallthrough to avoid unnecessary
duplication of code. For example, the case 1 below would previously
get treated as fall-through:
switch(foo)
{
case 1:
{
break;
}
default:
break;
}
Now RemoveSwitchFallThrough doesn't do anything to this code.
BUG=chromium:772695
TEST=angle_end2end_tests
Change-Id: Iafab6d8b05c63bcdb5f54834dbc1f41192c31dd4
Reviewed-on: https://chromium-review.googlesource.com/709197
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/RemoveSwitchFallThrough.cpp b/src/compiler/translator/RemoveSwitchFallThrough.cpp
index b4a2468..10da1df 100644
--- a/src/compiler/translator/RemoveSwitchFallThrough.cpp
+++ b/src/compiler/translator/RemoveSwitchFallThrough.cpp
@@ -203,12 +203,29 @@
return false;
}
+bool DoesBlockAlwaysBreak(TIntermBlock *node)
+{
+ if (node->getSequence()->empty())
+ {
+ return false;
+ }
+
+ TIntermBlock *lastStatementAsBlock = node->getSequence()->back()->getAsBlock();
+ if (lastStatementAsBlock)
+ {
+ return DoesBlockAlwaysBreak(lastStatementAsBlock);
+ }
+
+ TIntermBranch *lastStatementAsBranch = node->getSequence()->back()->getAsBranchNode();
+ return lastStatementAsBranch != nullptr;
+}
+
bool RemoveSwitchFallThroughTraverser::visitBlock(Visit, TIntermBlock *node)
{
if (node != mStatementList)
{
mPreviousCase->getSequence()->push_back(node);
- mLastStatementWasBreak = false;
+ mLastStatementWasBreak = DoesBlockAlwaysBreak(node);
return false;
}
return true;