@@ -115,22 +115,26 @@ template <class Emitter> class LoopScope final : public LabelScope<Emitter> {
115
115
LoopScope (Compiler<Emitter> *Ctx, LabelTy BreakLabel, LabelTy ContinueLabel)
116
116
: LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
117
117
OldContinueLabel (Ctx->ContinueLabel),
118
- OldLabelVarScope (Ctx->LabelVarScope) {
118
+ OldBreakVarScope (Ctx->BreakVarScope),
119
+ OldContinueVarScope (Ctx->ContinueVarScope) {
119
120
this ->Ctx ->BreakLabel = BreakLabel;
120
121
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 ;
122
124
}
123
125
124
126
~LoopScope () {
125
127
this ->Ctx ->BreakLabel = OldBreakLabel;
126
128
this ->Ctx ->ContinueLabel = OldContinueLabel;
127
- this ->Ctx ->LabelVarScope = OldLabelVarScope;
129
+ this ->Ctx ->ContinueVarScope = OldContinueVarScope;
130
+ this ->Ctx ->BreakVarScope = OldBreakVarScope;
128
131
}
129
132
130
133
private:
131
134
OptLabelTy OldBreakLabel;
132
135
OptLabelTy OldContinueLabel;
133
- VariableScope<Emitter> *OldLabelVarScope;
136
+ VariableScope<Emitter> *OldBreakVarScope;
137
+ VariableScope<Emitter> *OldContinueVarScope;
134
138
};
135
139
136
140
// Sets the context for a switch scope, mapping labels.
@@ -145,18 +149,18 @@ template <class Emitter> class SwitchScope final : public LabelScope<Emitter> {
145
149
: LabelScope<Emitter>(Ctx), OldBreakLabel(Ctx->BreakLabel),
146
150
OldDefaultLabel (this ->Ctx->DefaultLabel),
147
151
OldCaseLabels (std::move(this ->Ctx->CaseLabels)),
148
- OldLabelVarScope (Ctx->LabelVarScope ) {
152
+ OldLabelVarScope (Ctx->BreakVarScope ) {
149
153
this ->Ctx ->BreakLabel = BreakLabel;
150
154
this ->Ctx ->DefaultLabel = DefaultLabel;
151
155
this ->Ctx ->CaseLabels = std::move (CaseLabels);
152
- this ->Ctx ->LabelVarScope = this ->Ctx ->VarScope ;
156
+ this ->Ctx ->BreakVarScope = this ->Ctx ->VarScope ;
153
157
}
154
158
155
159
~SwitchScope () {
156
160
this ->Ctx ->BreakLabel = OldBreakLabel;
157
161
this ->Ctx ->DefaultLabel = OldDefaultLabel;
158
162
this ->Ctx ->CaseLabels = std::move (OldCaseLabels);
159
- this ->Ctx ->LabelVarScope = OldLabelVarScope;
163
+ this ->Ctx ->BreakVarScope = OldLabelVarScope;
160
164
}
161
165
162
166
private:
@@ -4605,18 +4609,23 @@ bool Compiler<Emitter>::visitWhileStmt(const WhileStmt *S) {
4605
4609
this ->fallthrough (CondLabel);
4606
4610
this ->emitLabel (CondLabel);
4607
4611
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 ;
4611
4617
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 ;
4616
4622
4617
- if (!this ->visitStmt (Body))
4618
- return false ;
4623
+ if (!this ->visitStmt (Body))
4624
+ return false ;
4619
4625
4626
+ if (!CondScope.destroyLocals ())
4627
+ return false ;
4628
+ }
4620
4629
if (!this ->jump (CondLabel))
4621
4630
return false ;
4622
4631
this ->fallthrough (EndLabel);
@@ -4636,13 +4645,18 @@ template <class Emitter> bool Compiler<Emitter>::visitDoStmt(const DoStmt *S) {
4636
4645
4637
4646
this ->fallthrough (StartLabel);
4638
4647
this ->emitLabel (StartLabel);
4648
+
4639
4649
{
4650
+ LocalScope<Emitter> CondScope (this );
4640
4651
if (!this ->visitStmt (Body))
4641
4652
return false ;
4642
4653
this ->fallthrough (CondLabel);
4643
4654
this ->emitLabel (CondLabel);
4644
4655
if (!this ->visitBool (Cond))
4645
4656
return false ;
4657
+
4658
+ if (!CondScope.destroyLocals ())
4659
+ return false ;
4646
4660
}
4647
4661
if (!this ->jumpTrue (StartLabel))
4648
4662
return false ;
@@ -4671,29 +4685,33 @@ bool Compiler<Emitter>::visitForStmt(const ForStmt *S) {
4671
4685
this ->fallthrough (CondLabel);
4672
4686
this ->emitLabel (CondLabel);
4673
4687
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 ;
4677
4693
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
+ }
4684
4700
4685
- {
4686
4701
if (Body && !this ->visitStmt (Body))
4687
4702
return false ;
4688
4703
4689
4704
this ->fallthrough (IncLabel);
4690
4705
this ->emitLabel (IncLabel);
4691
4706
if (Inc && !this ->discard (Inc))
4692
4707
return false ;
4693
- }
4694
4708
4709
+ if (!CondScope.destroyLocals ())
4710
+ return false ;
4711
+ }
4695
4712
if (!this ->jump (CondLabel))
4696
4713
return false ;
4714
+
4697
4715
this ->fallthrough (EndLabel);
4698
4716
this ->emitLabel (EndLabel);
4699
4717
return true ;
@@ -4760,7 +4778,7 @@ bool Compiler<Emitter>::visitBreakStmt(const BreakStmt *S) {
4760
4778
if (!BreakLabel)
4761
4779
return false ;
4762
4780
4763
- for (VariableScope<Emitter> *C = VarScope; C != LabelVarScope ;
4781
+ for (VariableScope<Emitter> *C = VarScope; C != BreakVarScope ;
4764
4782
C = C->getParent ())
4765
4783
C->emitDestruction ();
4766
4784
return this ->jump (*BreakLabel);
@@ -4771,8 +4789,8 @@ bool Compiler<Emitter>::visitContinueStmt(const ContinueStmt *S) {
4771
4789
if (!ContinueLabel)
4772
4790
return false ;
4773
4791
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 ())
4776
4794
C->emitDestruction ();
4777
4795
return this ->jump (*ContinueLabel);
4778
4796
}
@@ -4781,6 +4799,7 @@ template <class Emitter>
4781
4799
bool Compiler<Emitter>::visitSwitchStmt(const SwitchStmt *S) {
4782
4800
const Expr *Cond = S->getCond ();
4783
4801
PrimType CondT = this ->classifyPrim (Cond->getType ());
4802
+ LocalScope<Emitter> LS (this );
4784
4803
4785
4804
LabelTy EndLabel = this ->getLabel ();
4786
4805
OptLabelTy DefaultLabel = std::nullopt;
@@ -4844,7 +4863,8 @@ bool Compiler<Emitter>::visitSwitchStmt(const SwitchStmt *S) {
4844
4863
if (!this ->visitStmt (S->getBody ()))
4845
4864
return false ;
4846
4865
this ->emitLabel (EndLabel);
4847
- return true ;
4866
+
4867
+ return LS.destroyLocals ();
4848
4868
}
4849
4869
4850
4870
template <class Emitter >
0 commit comments