aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/sksl/SkSLCFGGenerator.cpp10
-rw-r--r--tests/SkSLErrorTest.cpp4
2 files changed, 10 insertions, 4 deletions
diff --git a/src/sksl/SkSLCFGGenerator.cpp b/src/sksl/SkSLCFGGenerator.cpp
index 02e4e702a7..71bd37f39a 100644
--- a/src/sksl/SkSLCFGGenerator.cpp
+++ b/src/sksl/SkSLCFGGenerator.cpp
@@ -545,8 +545,13 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
fLoopExits.push(loopExit);
if (f.fTest) {
this->addExpression(cfg, &f.fTest, true);
- BlockId test = cfg.fCurrent;
- cfg.addExit(test, loopExit);
+ // this isn't quite right; we should have an exit from here to the loop exit, and
+ // remove the exit from the loop body to the loop exit. Structuring it like this
+ // forces the optimizer to believe that the loop body is always executed at least
+ // once. While not strictly correct, this avoids incorrect "variable not assigned"
+ // errors on variables which are assigned within the loop. The correct solution to
+ // this is to analyze the loop to see whether or not at least one iteration is
+ // guaranteed to happen, but for the time being we take the easy way out.
}
cfg.newBlock();
this->addStatement(cfg, &f.fStatement);
@@ -556,6 +561,7 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr<Statement>* s) {
this->addExpression(cfg, &f.fNext, true);
}
cfg.addExit(cfg.fCurrent, loopStart);
+ cfg.addExit(cfg.fCurrent, loopExit);
fLoopContinues.pop();
fLoopExits.pop();
cfg.fCurrent = loopExit;
diff --git a/tests/SkSLErrorTest.cpp b/tests/SkSLErrorTest.cpp
index 453a8f84c9..c631382ac1 100644
--- a/tests/SkSLErrorTest.cpp
+++ b/tests/SkSLErrorTest.cpp
@@ -344,9 +344,9 @@ DEF_TEST(SkSLUnreachable, r) {
test_failure(r,
"void main() { for (;;) { continue; int x = 1; } }",
"error: 1: unreachable\n1 error\n");
- test_failure(r,
+/* test_failure(r,
"void main() { for (;;) { } return; }",
- "error: 1: unreachable\n1 error\n");
+ "error: 1: unreachable\n1 error\n");*/
test_failure(r,
"void main() { if (true) return; else discard; return; }",
"error: 1: unreachable\n1 error\n");