Skip to content

Commit 8f55cc6

Browse files
committed
SILOptimzer: correct a case of UB
The current `UpdatingInstructionIteratorRegistry` referenced `this` in the member initializer list. As per class.cdtor 11.9.5p1, this is UB as for any class with a non-trivial constructor, referencing the base class of the object before the constructor begins execution is not permitted. We attempted to capture `this` in the lambda that was used to initialise the member. This was being exploited by the MSVC compiler resulting in incorrect execution of the instruction deleter.
1 parent bf84d8d commit 8f55cc6

File tree

2 files changed

+9
-8
lines changed

2 files changed

+9
-8
lines changed

include/swift/SILOptimizer/Utils/UpdatingInstructionIterator.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,24 +177,24 @@ class UpdatingInstructionIteratorRegistry {
177177

178178

179179
public:
180-
UpdatingInstructionIteratorRegistry() :
181-
callbacks(InstModCallbacks()
180+
UpdatingInstructionIteratorRegistry() {
181+
callbacks = std::move(InstModCallbacks()
182182
.onDelete([this](SILInstruction *toDelete) {
183183
notifyDelete(toDelete);
184184
toDelete->eraseFromParent();
185185
})
186186
.onCreateNewInst(
187187
[this](SILInstruction *newlyCreatedInst) {
188188
notifyNew(newlyCreatedInst);
189-
}))
190-
{}
189+
}));
190+
}
191191

192192
UpdatingInstructionIteratorRegistry(InstModCallbacks &&chainedCallbacks) :
193193
// Copy the two std::functions that we need. The rest of the callbacks are
194194
// copied implicitly by assignment.
195195
chainedDelete(std::move(chainedCallbacks.deleteInstFunc)),
196-
chainedNew(std::move(chainedCallbacks.createdNewInstFunc)),
197-
callbacks(std::move(chainedCallbacks
196+
chainedNew(std::move(chainedCallbacks.createdNewInstFunc)) {
197+
callbacks = std::move(chainedCallbacks
198198
.onDelete([this](SILInstruction *toDelete) {
199199
notifyDelete(toDelete);
200200
if (chainedDelete) {
@@ -209,8 +209,8 @@ class UpdatingInstructionIteratorRegistry {
209209
if (chainedNew) {
210210
chainedNew(newlyCreatedInst);
211211
}
212-
})))
213-
{}
212+
}));
213+
}
214214

215215
// The callbacks capture 'this'. So copying is invalid.
216216
UpdatingInstructionIteratorRegistry(

lib/SILOptimizer/IPO/GlobalOpt.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ replaceLoadsByKnownValue(SILFunction *InitF, SILGlobalVariable *SILG,
401401
// Remove all instructions which are dead now.
402402
InstructionDeleter deleter;
403403
deleter.recursivelyDeleteUsersIfDead(initCall);
404+
404405
if (initCall->use_empty()) {
405406
// The call to the addressor is dead as well and can be removed.
406407
auto *callee = dyn_cast<FunctionRefInst>(initCall->getCallee());

0 commit comments

Comments
 (0)