diff --git a/gen/irstate.cpp b/gen/irstate.cpp index 4dc0e81c..644b7d2a 100644 --- a/gen/irstate.cpp +++ b/gen/irstate.cpp @@ -36,13 +36,14 @@ IRLoopScope::IRLoopScope() { } -IRLoopScope::IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e) +IRLoopScope::IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e, bool isSwitch) { begin = b; end = e; //builder.SetInsertPoint(b); this->s = s; this->enclosinghandler = enclosinghandler; + this->isSwitch = isSwitch; } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/irstate.h b/gen/irstate.h index f8cd69ab..7c67e4f2 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -45,9 +45,12 @@ struct IRLoopScope : IRScope Statement* s; // the try of a TryFinally that encloses the loop EnclosingHandler* enclosinghandler; + // if it is a switch, we are a possible target for break + // but not for continue + bool isSwitch; IRLoopScope(); - IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e); + IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e, bool isSwitch = false); }; struct IRBuilderHelper diff --git a/gen/statements.cpp b/gen/statements.cpp index 694ec525..34f7d57c 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -458,8 +458,15 @@ void ContinueStatement::toIR(IRState* p) assert(0); } else { - DtoEnclosingHandlers(enclosinghandler, gIR->loopbbs.back().enclosinghandler); - llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb()); + // can't 'continue' within switch, so omit them + IRState::LoopScopeVec::reverse_iterator it; + for(it = gIR->loopbbs.rbegin(); it != gIR->loopbbs.rend(); ++it) { + if(!it->isSwitch) { + break; + } + } + DtoEnclosingHandlers(enclosinghandler, it->enclosinghandler); + llvm::BranchInst::Create(it->begin, gIR->scopebb()); } } @@ -757,7 +764,7 @@ void SwitchStatement::toIR(IRState* p) assert(body); p->scope() = IRScope(bodybb, endbb); - p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb)); + p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb,true)); body->toIR(p); p->loopbbs.pop_back();