forked from OSchip/llvm-project
[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:
parent
c8124ee9a3
commit
75be84f3c2
|
@ -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();
|
||||
|
|
|
@ -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 }
|
||||
|
|
Loading…
Reference in New Issue