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/compiler/translator/RemoveSwitchFallThrough.cpp b/src/compiler/translator/RemoveSwitchFallThrough.cpp
index 8a4a0be..b4a2468 100644
--- a/src/compiler/translator/RemoveSwitchFallThrough.cpp
+++ b/src/compiler/translator/RemoveSwitchFallThrough.cpp
@@ -56,14 +56,16 @@
RemoveSwitchFallThroughTraverser rm(statementList);
ASSERT(statementList);
statementList->traverse(&rm);
- bool lastStatementWasBreak = rm.mLastStatementWasBreak;
- rm.mLastStatementWasBreak = true;
- rm.handlePreviousCase();
- if (!lastStatementWasBreak)
+ ASSERT(rm.mPreviousCase || statementList->getSequence()->empty());
+ if (!rm.mLastStatementWasBreak && rm.mPreviousCase)
{
+ // Make sure that there's a branch at the end of the final case inside the switch statement.
+ // This also ensures that any cases that fall through to the final case will get the break.
TIntermBranch *finalBreak = new TIntermBranch(EOpBreak, nullptr);
- rm.mStatementListOut->getSequence()->push_back(finalBreak);
+ rm.mPreviousCase->getSequence()->push_back(finalBreak);
+ rm.mLastStatementWasBreak = true;
}
+ rm.handlePreviousCase();
return rm.mStatementListOut;
}