Author: rjmccall Date: Thu Oct 29 19:56:02 2015 New Revision: 251677 URL: http://llvm.org/viewvc/llvm-project?rev=251677&view=rev Log: Initialize @catch variables correctly in fragile-runtime ARC.
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp cfe/trunk/lib/CodeGen/CGObjCRuntime.h cfe/trunk/test/CodeGenObjC/fragile-arc.m Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=251677&r1=251676&r2=251677&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original) +++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Thu Oct 29 19:56:02 2015 @@ -4135,7 +4135,7 @@ void CGObjCMac::EmitTryOrSynchronizedStm assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); // These types work out because ConvertType(id) == i8*. - CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam)); + EmitInitOfCatchParam(CGF, Caught, CatchParam); } CGF.EmitStmt(CatchStmt->getCatchBody()); @@ -4182,7 +4182,7 @@ void CGObjCMac::EmitTryOrSynchronizedStm llvm::Value *Tmp = CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(CatchParam->getType())); - CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam)); + EmitInitOfCatchParam(CGF, Tmp, CatchParam); CGF.EmitStmt(CatchStmt->getCatchBody()); Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp?rev=251677&r1=251676&r2=251677&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp (original) +++ cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp Thu Oct 29 19:56:02 2015 @@ -256,24 +256,7 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType); CGF.EmitAutoVarDecl(*CatchParam); - - Address CatchParamAddr = CGF.GetAddrOfLocalVar(CatchParam); - - switch (CatchParam->getType().getQualifiers().getObjCLifetime()) { - case Qualifiers::OCL_Strong: - CastExn = CGF.EmitARCRetainNonBlock(CastExn); - // fallthrough - - case Qualifiers::OCL_None: - case Qualifiers::OCL_ExplicitNone: - case Qualifiers::OCL_Autoreleasing: - CGF.Builder.CreateStore(CastExn, CatchParamAddr); - break; - - case Qualifiers::OCL_Weak: - CGF.EmitARCInitWeak(CatchParamAddr, CastExn); - break; - } + EmitInitOfCatchParam(CGF, CastExn, CatchParam); } CGF.ObjCEHValueStack.push_back(Exn); @@ -297,6 +280,30 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod CGF.EmitBlock(Cont.getBlock()); } +void CGObjCRuntime::EmitInitOfCatchParam(CodeGenFunction &CGF, + llvm::Value *exn, + const VarDecl *paramDecl) { + + Address paramAddr = CGF.GetAddrOfLocalVar(paramDecl); + + switch (paramDecl->getType().getQualifiers().getObjCLifetime()) { + case Qualifiers::OCL_Strong: + exn = CGF.EmitARCRetainNonBlock(exn); + // fallthrough + + case Qualifiers::OCL_None: + case Qualifiers::OCL_ExplicitNone: + case Qualifiers::OCL_Autoreleasing: + CGF.Builder.CreateStore(exn, paramAddr); + return; + + case Qualifiers::OCL_Weak: + CGF.EmitARCInitWeak(paramAddr, exn); + return; + } + llvm_unreachable("invalid ownership qualifier"); +} + namespace { struct CallSyncExit final : EHScopeStack::Cleanup { llvm::Value *SyncExitFn; Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.h?rev=251677&r1=251676&r2=251677&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjCRuntime.h (original) +++ cfe/trunk/lib/CodeGen/CGObjCRuntime.h Thu Oct 29 19:56:02 2015 @@ -100,6 +100,10 @@ protected: llvm::Constant *beginCatchFn, llvm::Constant *endCatchFn, llvm::Constant *exceptionRethrowFn); + + void EmitInitOfCatchParam(CodeGenFunction &CGF, llvm::Value *exn, + const VarDecl *paramDecl); + /// Emits an \@synchronize() statement, using the \p syncEnterFn and /// \p syncExitFn arguments as the functions called to lock and unlock /// the object. This function can be called by subclasses that use Modified: cfe/trunk/test/CodeGenObjC/fragile-arc.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/fragile-arc.m?rev=251677&r1=251676&r2=251677&view=diff ============================================================================== --- cfe/trunk/test/CodeGenObjC/fragile-arc.m (original) +++ cfe/trunk/test/CodeGenObjC/fragile-arc.m Thu Oct 29 19:56:02 2015 @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s -check-prefix=GLOBALS +// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-exceptions -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-exceptions -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s -check-prefix=GLOBALS @class Opaque; @@ -136,3 +136,40 @@ void testBlockLayoutStrong(id x) { void testBlockLayoutWeak(__weak id x) { useBlock(^{ (void) x; }); } + +// CHECK-LABEL: define void @testCatch() +// CHECK: [[X:%.*]] = alloca [[A:%.*]]*, align 4 +// CHECK: [[Y:%.*]] = alloca i8*, align 4 +// CHECK: call void @objc_exception_try_enter +// CHECK: br i1 +// CHECK: call void @checkpoint(i32 0) +// CHECK: call void @objc_exception_try_exit +// CHECK: br label +// CHECK: call void @checkpoint(i32 3) +// CHECK: [[EXN:%.*]] = call i8* @objc_exception_extract +// CHECK: call i32 @objc_exception_match( +// CHECK: br i1 +// CHECK: [[T0:%.*]] = bitcast i8* [[EXN]] to [[A]]* +// CHECK: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* +// CHECK: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) +// CHECK: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* +// CHECK: store [[A]]* [[T3]], [[A]]** [[X]] +// CHECK: call void @checkpoint(i32 1) +// CHECK: [[T0:%.*]] = bitcast [[A]]** [[X]] to i8** +// CHECK: call void @objc_storeStrong(i8** [[T0]], i8* null) +// CHECK: br label +// CHECK: [[T0:%.*]] = call i8* @objc_retain(i8* [[EXN]]) +// CHECK: store i8* [[T0]], i8** [[Y]] +// CHECK: call void @checkpoint(i32 2) +// CHECK: call void @objc_storeStrong(i8** [[Y]], i8* null) +extern void checkpoint(int n); +void testCatch() { + @try { + checkpoint(0); + } @catch (A *x) { + checkpoint(1); + } @catch (id y) { + checkpoint(2); + } + checkpoint(3); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits