@@ -115,6 +115,75 @@ RValue DominatingValue<RValue>::saved_type::restore(CIRGenFunction &CGF) {
115115 llvm_unreachable (" bad saved r-value kind" );
116116}
117117
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+
118187// / Deactive a cleanup that was created in an active state.
119188void CIRGenFunction::DeactivateCleanupBlock (EHScopeStack::stable_iterator C,
120189 mlir::Operation *dominatingIP) {
@@ -143,7 +212,9 @@ void CIRGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C,
143212 return ;
144213 }
145214
146- llvm_unreachable (" NYI" );
215+ // Otherwise, follow the general case.
216+ setupCleanupBlockActivation (*this , C, ForDeactivation, dominatingIP);
217+ Scope.setActive (false );
147218}
148219
149220void CIRGenFunction::initFullExprCleanupWithFlag (Address ActiveFlag) {
0 commit comments