@@ -2094,21 +2094,47 @@ void CodeGenFunction::pushStackRestore(CleanupKind Kind, Address SPMem) {
2094
2094
EHStack.pushCleanup <CallStackRestore>(Kind, SPMem);
2095
2095
}
2096
2096
2097
- void CodeGenFunction::pushLifetimeExtendedDestroy (
2098
- CleanupKind cleanupKind, Address addr, QualType type,
2099
- Destroyer *destroyer, bool useEHCleanupForArray) {
2100
- // Push an EH-only cleanup for the object now.
2101
- // FIXME: When popping normal cleanups, we need to keep this EH cleanup
2102
- // around in case a temporary's destructor throws an exception.
2103
- if (cleanupKind & EHCleanup)
2104
- EHStack.pushCleanup <DestroyObject>(
2105
- static_cast <CleanupKind>(cleanupKind & ~NormalCleanup), addr, type,
2097
+ void CodeGenFunction::pushLifetimeExtendedDestroy (CleanupKind cleanupKind,
2098
+ Address addr, QualType type,
2099
+ Destroyer *destroyer,
2100
+ bool useEHCleanupForArray) {
2101
+ // If we're not in a conditional branch, we don't need to bother generating a
2102
+ // conditional cleanup.
2103
+ if (!isInConditionalBranch ()) {
2104
+ // Push an EH-only cleanup for the object now.
2105
+ // FIXME: When popping normal cleanups, we need to keep this EH cleanup
2106
+ // around in case a temporary's destructor throws an exception.
2107
+ if (cleanupKind & EHCleanup)
2108
+ EHStack.pushCleanup <DestroyObject>(
2109
+ static_cast <CleanupKind>(cleanupKind & ~NormalCleanup), addr, type,
2110
+ destroyer, useEHCleanupForArray);
2111
+
2112
+ return pushCleanupAfterFullExprWithActiveFlag<DestroyObject>(
2113
+ cleanupKind, Address::invalid (), addr, type, destroyer, useEHCleanupForArray);
2114
+ }
2115
+
2116
+ // Otherwise, we should only destroy the object if it's been initialized.
2117
+ // Re-use the active flag and saved address across both the EH and end of
2118
+ // scope cleanups.
2119
+
2120
+ using SavedType = typename DominatingValue<Address>::saved_type;
2121
+ using ConditionalCleanupType =
2122
+ EHScopeStack::ConditionalCleanup<DestroyObject, Address, QualType,
2123
+ Destroyer *, bool >;
2124
+
2125
+ Address ActiveFlag = createCleanupActiveFlag ();
2126
+ SavedType SavedAddr = saveValueInCond (addr);
2127
+
2128
+ if (cleanupKind & EHCleanup) {
2129
+ EHStack.pushCleanup <ConditionalCleanupType>(
2130
+ static_cast <CleanupKind>(cleanupKind & ~NormalCleanup), SavedAddr, type,
2106
2131
destroyer, useEHCleanupForArray);
2132
+ initFullExprCleanupWithFlag (ActiveFlag);
2133
+ }
2107
2134
2108
- // Remember that we need to push a full cleanup for the object at the
2109
- // end of the full-expression.
2110
- pushCleanupAfterFullExpr<DestroyObject>(
2111
- cleanupKind, addr, type, destroyer, useEHCleanupForArray);
2135
+ pushCleanupAfterFullExprWithActiveFlag<ConditionalCleanupType>(
2136
+ cleanupKind, ActiveFlag, SavedAddr, type, destroyer,
2137
+ useEHCleanupForArray);
2112
2138
}
2113
2139
2114
2140
// / emitDestroy - Immediately perform the destruction of the given
0 commit comments