forked from OSchip/llvm-project
Call objc_terminate() instead of abort() when a cleanup throws an
exception in Objective-C; in Objective-C++ we still use std::terminate(). This is only available in very recent runtimes. llvm-svn: 134456
This commit is contained in:
parent
6dd2417dbe
commit
9de1978f6e
|
@ -500,6 +500,8 @@ def fobjc_runtime_has_arc : Flag<"-fobjc-runtime-has-arc">,
|
|||
HelpText<"The target Objective-C runtime provides ARC entrypoints">;
|
||||
def fobjc_runtime_has_weak : Flag<"-fobjc-runtime-has-weak">,
|
||||
HelpText<"The target Objective-C runtime supports ARC weak operations">;
|
||||
def fobjc_runtime_has_terminate : Flag<"-fobjc-runtime-has-terminate">,
|
||||
HelpText<"The target Objective-C runtime provides an objc_terminate entrypoint">;
|
||||
def fobjc_gc : Flag<"-fobjc-gc">,
|
||||
HelpText<"Enable Objective-C garbage collection">;
|
||||
def fobjc_gc_only : Flag<"-fobjc-gc-only">,
|
||||
|
|
|
@ -30,7 +30,14 @@ public:
|
|||
/// True if the runtime supports ARC zeroing __weak.
|
||||
unsigned HasWeak : 1;
|
||||
|
||||
ObjCRuntime() : RuntimeKind(NeXT), HasARC(false), HasWeak(false) {}
|
||||
/// True if the runtime provides the following entrypoint:
|
||||
/// void objc_terminate(void);
|
||||
/// If available, this will be called instead of abort() when an
|
||||
/// exception is thrown out of an EH cleanup.
|
||||
unsigned HasTerminate : 1;
|
||||
|
||||
ObjCRuntime() : RuntimeKind(NeXT), HasARC(false), HasWeak(false),
|
||||
HasTerminate(false) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ public:
|
|||
unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
|
||||
unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use.
|
||||
unsigned ObjCRuntimeHasARC : 1; /// The target runtime supports ARC natively
|
||||
unsigned ObjCRuntimeHasTerminate : 1; /// The ObjC runtime has objc_terminate
|
||||
unsigned OmitLeafFramePointer : 1; /// Set when -momit-leaf-frame-pointer is
|
||||
/// enabled.
|
||||
unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
|
||||
|
@ -141,7 +142,6 @@ public:
|
|||
public:
|
||||
CodeGenOptions() {
|
||||
AsmVerbose = 0;
|
||||
ObjCAutoRefCountExceptions = 0;
|
||||
CXAAtExit = 1;
|
||||
CXXCtorDtorAliases = 0;
|
||||
DataSections = 0;
|
||||
|
@ -168,7 +168,10 @@ public:
|
|||
NoNaNsFPMath = 0;
|
||||
NoZeroInitializedInBSS = 0;
|
||||
NumRegisterParameters = 0;
|
||||
ObjCAutoRefCountExceptions = 0;
|
||||
ObjCDispatchMethod = Legacy;
|
||||
ObjCRuntimeHasARC = 0;
|
||||
ObjCRuntimeHasTerminate = 0;
|
||||
OmitLeafFramePointer = 0;
|
||||
OptimizationLevel = 0;
|
||||
OptimizeSize = 0;
|
||||
|
|
|
@ -137,8 +137,17 @@ static llvm::Constant *getTerminateFn(CodeGenFunction &CGF) {
|
|||
llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
|
||||
/*IsVarArgs=*/false);
|
||||
|
||||
return CGF.CGM.CreateRuntimeFunction(FTy,
|
||||
CGF.CGM.getLangOptions().CPlusPlus ? "_ZSt9terminatev" : "abort");
|
||||
llvm::StringRef name;
|
||||
|
||||
// In C++, use std::terminate().
|
||||
if (CGF.getLangOptions().CPlusPlus)
|
||||
name = "_ZSt9terminatev"; // FIXME: mangling!
|
||||
else if (CGF.getLangOptions().ObjC1 &&
|
||||
CGF.CGM.getCodeGenOpts().ObjCRuntimeHasTerminate)
|
||||
name = "objc_terminate";
|
||||
else
|
||||
name = "abort";
|
||||
return CGF.CGM.CreateRuntimeFunction(FTy, name);
|
||||
}
|
||||
|
||||
static llvm::Constant *getCatchallRethrowFn(CodeGenFunction &CGF,
|
||||
|
|
|
@ -55,12 +55,14 @@ void ToolChain::configureObjCRuntime(ObjCRuntime &runtime) const {
|
|||
// Assume a minimal NeXT runtime.
|
||||
runtime.HasARC = false;
|
||||
runtime.HasWeak = false;
|
||||
runtime.HasTerminate = false;
|
||||
return;
|
||||
|
||||
case ObjCRuntime::GNU:
|
||||
// Assume a maximal GNU runtime.
|
||||
runtime.HasARC = true;
|
||||
runtime.HasWeak = true;
|
||||
runtime.HasTerminate = false; // to be added
|
||||
return;
|
||||
}
|
||||
llvm_unreachable("invalid runtime kind!");
|
||||
|
|
|
@ -99,6 +99,13 @@ void Darwin::configureObjCRuntime(ObjCRuntime &runtime) const {
|
|||
return ToolChain::configureObjCRuntime(runtime);
|
||||
|
||||
runtime.HasARC = runtime.HasWeak = hasARCRuntime();
|
||||
|
||||
// So far, objc_terminate is only available in iOS 5.
|
||||
// FIXME: do the simulator logic properly.
|
||||
if (!ARCRuntimeForSimulator && isTargetIPhoneOS())
|
||||
runtime.HasTerminate = !isIPhoneOSVersionLT(5);
|
||||
else
|
||||
runtime.HasTerminate = false;
|
||||
}
|
||||
|
||||
// FIXME: Can we tablegen this?
|
||||
|
|
|
@ -1781,6 +1781,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
CmdArgs.push_back("-fobjc-runtime-has-arc");
|
||||
if (objCRuntime.HasWeak)
|
||||
CmdArgs.push_back("-fobjc-runtime-has-weak");
|
||||
if (objCRuntime.HasTerminate)
|
||||
CmdArgs.push_back("-fobjc-runtime-has-terminate");
|
||||
|
||||
// Compute the Objective-C ABI "version" to use. Version numbers are
|
||||
// slightly confusing for historical reasons:
|
||||
|
|
|
@ -125,6 +125,8 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
|
|||
}
|
||||
if (Opts.ObjCRuntimeHasARC)
|
||||
Res.push_back("-fobjc-runtime-has-arc");
|
||||
if (Opts.ObjCRuntimeHasTerminate)
|
||||
Res.push_back("-fobjc-runtime-has-terminate");
|
||||
if (Opts.EmitGcovArcs)
|
||||
Res.push_back("-femit-coverage-data");
|
||||
if (Opts.EmitGcovNotes)
|
||||
|
@ -979,6 +981,7 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
|
|||
Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
|
||||
Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);
|
||||
Opts.ObjCRuntimeHasARC = Args.hasArg(OPT_fobjc_runtime_has_arc);
|
||||
Opts.ObjCRuntimeHasTerminate = Args.hasArg(OPT_fobjc_runtime_has_terminate);
|
||||
Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
|
||||
Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
|
||||
Opts.CodeModel = Args.getLastArgValue(OPT_mcode_model);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -fobjc-exceptions -fobjc-runtime-has-terminate -o - %s | FileCheck %s -check-prefix=CHECK-WITH
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -fobjc-exceptions -o - %s | FileCheck %s -check-prefix=CHECK-WITHOUT
|
||||
|
||||
void destroy(void**);
|
||||
|
||||
// rdar://problem/9519113
|
||||
void test0(void) {
|
||||
void test0_helper(void);
|
||||
void *ptr __attribute__((cleanup(destroy)));
|
||||
test0_helper();
|
||||
|
||||
// CHECK-WITH: define void @test0()
|
||||
// CHECK-WITH: [[PTR:%.*]] = alloca i8*,
|
||||
// CHECK-WITH: call void @destroy(i8** [[PTR]])
|
||||
// CHECK-WITH-NEXT: ret void
|
||||
// CHECK-WITH: invoke void @destroy(i8** [[PTR]])
|
||||
// CHECK-WITH: call i8* @llvm.eh.exception()
|
||||
// CHECK-WITH-NEXT: @llvm.eh.selector
|
||||
// CHECK-WITH-NEXT: call void @objc_terminate()
|
||||
|
||||
// CHECK-WITHOUT: define void @test0()
|
||||
// CHECK-WITHOUT: [[PTR:%.*]] = alloca i8*,
|
||||
// CHECK-WITHOUT: call void @destroy(i8** [[PTR]])
|
||||
// CHECK-WITHOUT-NEXT: ret void
|
||||
// CHECK-WITHOUT: invoke void @destroy(i8** [[PTR]])
|
||||
// CHECK-WITHOUT: call i8* @llvm.eh.exception()
|
||||
// CHECK-WITHOUT-NEXT: @llvm.eh.selector
|
||||
// CHECK-WITHOUT-NEXT: call void @abort()
|
||||
}
|
Loading…
Reference in New Issue