From: John McCall Date: Tue, 31 Jul 2012 00:33:55 +0000 (+0000) Subject: Don't crash *or* insert a bogus autorelease when emitting a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bd9b65ae534cb11aa39737aa43ab82bb29e078f6;p=clang Don't crash *or* insert a bogus autorelease when emitting a this-adjustment thunk in ARC++. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161014 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 37a9a5eaff..9deec19bf8 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1405,7 +1405,8 @@ static llvm::Value *tryEmitFusedAutoreleaseOfResult(CodeGenFunction &CGF, static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF, llvm::Value *result) { // This is only applicable to a method with an immutable 'self'. - const ObjCMethodDecl *method = dyn_cast(CGF.CurCodeDecl); + const ObjCMethodDecl *method = + dyn_cast_or_null(CGF.CurCodeDecl); if (!method) return 0; const VarDecl *self = method->getSelfDecl(); if (!self->getType().isConstQualified()) return 0; diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index 3c0dd5d56b..cdaa26a2ba 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -387,6 +387,9 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, if (!ResultType->isVoidType() && Slot.isNull()) CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType); + // Disable the final ARC autorelease. + AutoreleaseResult = false; + FinishFunction(); // Set the right linkage. diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm index 45211a2c19..f31b993946 100644 --- a/test/CodeGenObjCXX/arc.mm +++ b/test/CodeGenObjCXX/arc.mm @@ -252,3 +252,19 @@ template class Test38 { }; // CHECK: define weak_odr void @_ZN6Test38IiE4testEi( template class Test38; + +// rdar://problem/11964832 +class Test39_base1 { + virtual void foo(); +}; +class Test39_base2 { + virtual id bar(); +}; +class Test39 : Test39_base1, Test39_base2 { // base2 is at non-zero offset + virtual id bar(); +}; +id Test39::bar() { return 0; } +// Note lack of autorelease. +// CHECK: define i8* @_ZThn8_N6Test393barEv( +// CHECK: call i8* @_ZN6Test393barEv( +// CHECK-NEXT: ret i8*