@@ -115,22 +115,26 @@ template <class Emitter> class LoopScope final : public LabelScope<Emitter> {
115115 LoopScope (Compiler<Emitter> *Ctx, LabelTy BreakLabel, LabelTy ContinueLabel)
116116 : LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
117117 OldContinueLabel (Ctx->ContinueLabel),
118- OldLabelVarScope (Ctx->LabelVarScope) {
118+ OldBreakVarScope (Ctx->BreakVarScope),
119+ OldContinueVarScope (Ctx->ContinueVarScope) {
119120 this ->Ctx ->BreakLabel = BreakLabel;
120121 this ->Ctx ->ContinueLabel = ContinueLabel;
121- this ->Ctx ->LabelVarScope = this ->Ctx ->VarScope ;
122+ this ->Ctx ->BreakVarScope = this ->Ctx ->VarScope ;
123+ this ->Ctx ->ContinueVarScope = this ->Ctx ->VarScope ;
122124 }
123125
124126 ~LoopScope () {
125127 this ->Ctx ->BreakLabel = OldBreakLabel;
126128 this ->Ctx ->ContinueLabel = OldContinueLabel;
127- this ->Ctx ->LabelVarScope = OldLabelVarScope;
129+ this ->Ctx ->ContinueVarScope = OldContinueVarScope;
130+ this ->Ctx ->BreakVarScope = OldBreakVarScope;
128131 }
129132
130133private:
131134 OptLabelTy OldBreakLabel;
132135 OptLabelTy OldContinueLabel;
133- VariableScope<Emitter> *OldLabelVarScope;
136+ VariableScope<Emitter> *OldBreakVarScope;
137+ VariableScope<Emitter> *OldContinueVarScope;
134138};
135139
136140// Sets the context for a switch scope, mapping labels.
@@ -145,18 +149,18 @@ template <class Emitter> class SwitchScope final : public LabelScope<Emitter> {
145149 : LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
146150 OldDefaultLabel (this ->Ctx->DefaultLabel),
147151 OldCaseLabels (std::move(this ->Ctx->CaseLabels)),
148- OldLabelVarScope (Ctx->LabelVarScope ) {
152+ OldLabelVarScope (Ctx->BreakVarScope ) {
149153 this ->Ctx ->BreakLabel = BreakLabel;
150154 this ->Ctx ->DefaultLabel = DefaultLabel;
151155 this ->Ctx ->CaseLabels = std::move (CaseLabels);
152- this ->Ctx ->LabelVarScope = this ->Ctx ->VarScope ;
156+ this ->Ctx ->BreakVarScope = this ->Ctx ->VarScope ;
153157 }
154158
155159 ~SwitchScope () {
156160 this ->Ctx ->BreakLabel = OldBreakLabel;
157161 this ->Ctx ->DefaultLabel = OldDefaultLabel;
158162 this ->Ctx ->CaseLabels = std::move (OldCaseLabels);
159- this ->Ctx ->LabelVarScope = OldLabelVarScope;
163+ this ->Ctx ->BreakVarScope = OldLabelVarScope;
160164 }
161165
162166private:
@@ -4605,18 +4609,23 @@ bool Compiler<Emitter>::visitWhileStmt(const WhileStmt *S) {
46054609 this ->fallthrough (CondLabel);
46064610 this ->emitLabel (CondLabel);
46074611
4608- if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt ())
4609- if (!visitDeclStmt (CondDecl))
4610- return false ;
4612+ {
4613+ LocalScope<Emitter> CondScope (this );
4614+ if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt ())
4615+ if (!visitDeclStmt (CondDecl))
4616+ return false ;
46114617
4612- if (!this ->visitBool (Cond))
4613- return false ;
4614- if (!this ->jumpFalse (EndLabel))
4615- return false ;
4618+ if (!this ->visitBool (Cond))
4619+ return false ;
4620+ if (!this ->jumpFalse (EndLabel))
4621+ return false ;
46164622
4617- if (!this ->visitStmt (Body))
4618- return false ;
4623+ if (!this ->visitStmt (Body))
4624+ return false ;
46194625
4626+ if (!CondScope.destroyLocals ())
4627+ return false ;
4628+ }
46204629 if (!this ->jump (CondLabel))
46214630 return false ;
46224631 this ->fallthrough (EndLabel);
@@ -4636,13 +4645,18 @@ template <class Emitter> bool Compiler<Emitter>::visitDoStmt(const DoStmt *S) {
46364645
46374646 this ->fallthrough (StartLabel);
46384647 this ->emitLabel (StartLabel);
4648+
46394649 {
4650+ LocalScope<Emitter> CondScope (this );
46404651 if (!this ->visitStmt (Body))
46414652 return false ;
46424653 this ->fallthrough (CondLabel);
46434654 this ->emitLabel (CondLabel);
46444655 if (!this ->visitBool (Cond))
46454656 return false ;
4657+
4658+ if (!CondScope.destroyLocals ())
4659+ return false ;
46464660 }
46474661 if (!this ->jumpTrue (StartLabel))
46484662 return false ;
@@ -4671,29 +4685,33 @@ bool Compiler<Emitter>::visitForStmt(const ForStmt *S) {
46714685 this ->fallthrough (CondLabel);
46724686 this ->emitLabel (CondLabel);
46734687
4674- if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt ())
4675- if (!visitDeclStmt (CondDecl))
4676- return false ;
4688+ {
4689+ LocalScope<Emitter> CondScope (this );
4690+ if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt ())
4691+ if (!visitDeclStmt (CondDecl))
4692+ return false ;
46774693
4678- if (Cond) {
4679- if (!this ->visitBool (Cond))
4680- return false ;
4681- if (!this ->jumpFalse (EndLabel))
4682- return false ;
4683- }
4694+ if (Cond) {
4695+ if (!this ->visitBool (Cond))
4696+ return false ;
4697+ if (!this ->jumpFalse (EndLabel))
4698+ return false ;
4699+ }
46844700
4685- {
46864701 if (Body && !this ->visitStmt (Body))
46874702 return false ;
46884703
46894704 this ->fallthrough (IncLabel);
46904705 this ->emitLabel (IncLabel);
46914706 if (Inc && !this ->discard (Inc))
46924707 return false ;
4693- }
46944708
4709+ if (!CondScope.destroyLocals ())
4710+ return false ;
4711+ }
46954712 if (!this ->jump (CondLabel))
46964713 return false ;
4714+
46974715 this ->fallthrough (EndLabel);
46984716 this ->emitLabel (EndLabel);
46994717 return true ;
@@ -4760,7 +4778,7 @@ bool Compiler<Emitter>::visitBreakStmt(const BreakStmt *S) {
47604778 if (!BreakLabel)
47614779 return false ;
47624780
4763- for (VariableScope<Emitter> *C = VarScope; C != LabelVarScope ;
4781+ for (VariableScope<Emitter> *C = VarScope; C != BreakVarScope ;
47644782 C = C->getParent ())
47654783 C->emitDestruction ();
47664784 return this ->jump (*BreakLabel);
@@ -4771,8 +4789,8 @@ bool Compiler<Emitter>::visitContinueStmt(const ContinueStmt *S) {
47714789 if (!ContinueLabel)
47724790 return false ;
47734791
4774- for (VariableScope<Emitter> *C = VarScope; C != LabelVarScope;
4775- C = C->getParent ())
4792+ for (VariableScope<Emitter> *C = VarScope;
4793+ C && C-> getParent () != ContinueVarScope; C = C->getParent ())
47764794 C->emitDestruction ();
47774795 return this ->jump (*ContinueLabel);
47784796}
@@ -4781,6 +4799,7 @@ template <class Emitter>
47814799bool Compiler<Emitter>::visitSwitchStmt(const SwitchStmt *S) {
47824800 const Expr *Cond = S->getCond ();
47834801 PrimType CondT = this ->classifyPrim (Cond->getType ());
4802+ LocalScope<Emitter> LS (this );
47844803
47854804 LabelTy EndLabel = this ->getLabel ();
47864805 OptLabelTy DefaultLabel = std::nullopt ;
@@ -4844,7 +4863,8 @@ bool Compiler<Emitter>::visitSwitchStmt(const SwitchStmt *S) {
48444863 if (!this ->visitStmt (S->getBody ()))
48454864 return false ;
48464865 this ->emitLabel (EndLabel);
4847- return true ;
4866+
4867+ return LS.destroyLocals ();
48484868}
48494869
48504870template <class Emitter >
0 commit comments