@@ -115,6 +115,75 @@ RValue DominatingValue<RValue>::saved_type::restore(CIRGenFunction &CGF) {
115
115
llvm_unreachable (" bad saved r-value kind" );
116
116
}
117
117
118
+ static bool IsUsedAsEHCleanup (EHScopeStack &EHStack,
119
+ EHScopeStack::stable_iterator cleanup) {
120
+ // If we needed an EH block for any reason, that counts.
121
+ if (EHStack.find (cleanup)->hasEHBranches ())
122
+ return true ;
123
+
124
+ // Check whether any enclosed cleanups were needed.
125
+ for (EHScopeStack::stable_iterator i = EHStack.getInnermostEHScope ();
126
+ i != cleanup;) {
127
+ assert (cleanup.strictlyEncloses (i));
128
+
129
+ EHScope &scope = *EHStack.find (i);
130
+ if (scope.hasEHBranches ())
131
+ return true ;
132
+
133
+ i = scope.getEnclosingEHScope ();
134
+ }
135
+
136
+ return false ;
137
+ }
138
+
139
+ enum ForActivation_t { ForActivation, ForDeactivation };
140
+
141
+ // / The given cleanup block is changing activation state. Configure a
142
+ // / cleanup variable if necessary.
143
+ // /
144
+ // / It would be good if we had some way of determining if there were
145
+ // / extra uses *after* the change-over point.
146
+ static void setupCleanupBlockActivation (CIRGenFunction &CGF,
147
+ EHScopeStack::stable_iterator C,
148
+ ForActivation_t kind,
149
+ mlir::Operation *dominatingIP) {
150
+ EHCleanupScope &Scope = cast<EHCleanupScope>(*CGF.EHStack .find (C));
151
+
152
+ // We always need the flag if we're activating the cleanup in a
153
+ // conditional context, because we have to assume that the current
154
+ // location doesn't necessarily dominate the cleanup's code.
155
+ bool isActivatedInConditional =
156
+ (kind == ForActivation && CGF.isInConditionalBranch ());
157
+
158
+ bool needFlag = false ;
159
+
160
+ // Calculate whether the cleanup was used:
161
+
162
+ // - as a normal cleanup
163
+ if (Scope.isNormalCleanup ()) {
164
+ Scope.setTestFlagInNormalCleanup ();
165
+ needFlag = true ;
166
+ }
167
+
168
+ // - as an EH cleanup
169
+ if (Scope.isEHCleanup () &&
170
+ (isActivatedInConditional || IsUsedAsEHCleanup (CGF.EHStack , C))) {
171
+ Scope.setTestFlagInEHCleanup ();
172
+ needFlag = true ;
173
+ }
174
+
175
+ // If it hasn't yet been used as either, we're done.
176
+ if (!needFlag)
177
+ return ;
178
+
179
+ Address var = Scope.getActiveFlag ();
180
+ if (!var.isValid ()) {
181
+ llvm_unreachable (" NYI" );
182
+ }
183
+
184
+ llvm_unreachable (" NYI" );
185
+ }
186
+
118
187
// / Deactive a cleanup that was created in an active state.
119
188
void CIRGenFunction::DeactivateCleanupBlock (EHScopeStack::stable_iterator C,
120
189
mlir::Operation *dominatingIP) {
@@ -143,7 +212,9 @@ void CIRGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C,
143
212
return ;
144
213
}
145
214
146
- llvm_unreachable (" NYI" );
215
+ // Otherwise, follow the general case.
216
+ setupCleanupBlockActivation (*this , C, ForDeactivation, dominatingIP);
217
+ Scope.setActive (false );
147
218
}
148
219
149
220
void CIRGenFunction::initFullExprCleanupWithFlag (Address ActiveFlag) {
0 commit comments