diff options
-rw-r--r-- | include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | include/clang/Driver/ObjCRuntime.h | 9 | ||||
-rw-r--r-- | include/clang/Frontend/CodeGenOptions.h | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGException.cpp | 13 | ||||
-rw-r--r-- | lib/Driver/ToolChain.cpp | 2 | ||||
-rw-r--r-- | lib/Driver/ToolChains.cpp | 7 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | test/CodeGenObjC/terminate.m | 29 |
9 files changed, 68 insertions, 4 deletions
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index aab0213b95..6f38ea5199 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -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">, diff --git a/include/clang/Driver/ObjCRuntime.h b/include/clang/Driver/ObjCRuntime.h index 241354f15e..5516460433 100644 --- a/include/clang/Driver/ObjCRuntime.h +++ b/include/clang/Driver/ObjCRuntime.h @@ -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) {} }; } diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index d415d0a889..5d040b4f26 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -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; diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 1a4a5f988a..af54f39686 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -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, diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 0cce517549..74b65918f3 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -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!"); diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 68ebc1b6b3..1619ef8f84 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -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? diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index d0fd914bf0..d4d41d28d5 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -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: diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 31c86432b7..fd57f59e64 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -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); diff --git a/test/CodeGenObjC/terminate.m b/test/CodeGenObjC/terminate.m new file mode 100644 index 0000000000..f04eb6a92b --- /dev/null +++ b/test/CodeGenObjC/terminate.m @@ -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() +} |