Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -14,6 +14,7 @@ #include "CGCall.h" #include "ABIInfo.h" +#include "CGBlocks.h" #include "CGCXXABI.h" #include "CGCleanup.h" #include "CodeGenFunction.h" @@ -2462,9 +2463,21 @@ // In ARC, end functions that return a retainable type with a call // to objc_autoreleaseReturnValue. if (AutoreleaseResult) { + QualType RT; + + if (auto *FD = dyn_cast(CurCodeDecl)) + RT = FD->getReturnType(); + else if (auto *MD = dyn_cast(CurCodeDecl)) + RT = MD->getReturnType(); + else if (isa(CurCodeDecl)) + RT = BlockInfo->BlockExpression->getFunctionType()->getReturnType(); + else + llvm_unreachable("Unexpected function/method type"); + + (void)RT; assert(getLangOpts().ObjCAutoRefCount && !FI.isReturnsRetained() && - RetTy->isObjCRetainableType()); + RT->isObjCRetainableType()); RV = emitAutoreleaseOfResult(*this, RV); } Index: test/CodeGenObjCXX/auto-release-result-assert.mm =================================================================== --- /dev/null +++ test/CodeGenObjCXX/auto-release-result-assert.mm @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -o - %s | FileCheck %s + +// CHECK-LABEL: define %struct.S1* @_Z4foo1i( +// CHECK: %[[CALL:[a-z0-9]+]] = call %struct.S1* @_Z4foo0i +// CHECK: ret %struct.S1* %[[CALL]] + +// CHECK-LABEL: define %struct.S1* @_ZN2S22m1Ev( +// CHECK: %[[CALL:[a-z0-9]+]] = call %struct.S1* @_Z4foo0i +// CHECK: ret %struct.S1* %[[CALL]] + +// CHECK-LABEL: define internal %struct.S1* @Block1_block_invoke( +// CHECK: %[[CALL:[a-z0-9]+]] = call %struct.S1* @_Z4foo0i +// CHECK: ret %struct.S1* %[[CALL]] + +struct S1; + +typedef __attribute__((NSObject)) struct __attribute__((objc_bridge(id))) S1 * S1Ref; + +S1Ref foo0(int); + +struct S2 { + S1Ref m1(); +}; + +S1Ref foo1(int a) { + return foo0(a); +} + +S1Ref S2::m1() { + return foo0(0); +} + +S1Ref (^Block1)(void) = ^{ + return foo0(0); +};