[ObjCArc] Do not dereference an invalidated iterator.

Fix a bug in ARC contract pass where an iterator that pointed to a
deleted instruction was dereferenced.

It appears that tryToContractReleaseIntoStoreStrong was incorrectly
assuming that a call to objc_retain would not immediately follow a call
to objc_release.

rdar://problem/25276306

llvm-svn: 299507
This commit is contained in:
Akira Hatanaka 2017-04-05 03:44:09 +00:00
parent c8124ee9a3
commit 75be84f3c2
2 changed files with 14 additions and 0 deletions

View File

@ -394,6 +394,7 @@ void ObjCARCContract::tryToContractReleaseIntoStoreStrong(Instruction *Release,
DEBUG(llvm::dbgs() << " New Store Strong: " << *StoreStrong << "\n");
if (&*Iter == Retain) ++Iter;
if (&*Iter == Store) ++Iter;
Store->eraseFromParent();
Release->eraseFromParent();

View File

@ -243,6 +243,19 @@ entry:
ret void
}
; This used to crash.
; CHECK-LABEL: define i8* @test13(
; CHECK: tail call void @objc_storeStrong(i8** %{{.*}}, i8* %[[NEW:.*]])
; CHECK-NEXT: ret i8* %[[NEW]]
define i8* @test13(i8* %a0, i8* %a1, i8** %addr, i8* %new) {
%old = load i8*, i8** %addr, align 8
call void @objc_release(i8* %old)
%retained = call i8* @objc_retain(i8* %new)
store i8* %retained, i8** %addr, align 8
ret i8* %retained
}
!0 = !{}
; CHECK: attributes [[NUW]] = { nounwind }