From e070b99b84e1a6bd31498333b1c3fa6fb356e6be Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 14 Nov 2014 02:01:10 +0000 Subject: [PATCH] Remove -fseh-exceptions in favor of checking the triple This option was misleading because it looked like it enabled the language feature of SEH (__try / __except), when this option was really controlling which EH personality function to use. Mingw only supports SEH and SjLj EH on x86_64, so we can simply do away with this flag. llvm-svn: 221963 --- clang/include/clang/Basic/LangOptions.def | 1 - clang/include/clang/Driver/CC1Options.td | 2 - clang/include/clang/Driver/ToolChain.h | 3 -- clang/lib/Basic/Targets.cpp | 4 ++ clang/lib/CodeGen/CGException.cpp | 54 +++++++++++++--------- clang/lib/Driver/Tools.cpp | 2 - clang/lib/Frontend/CompilerInvocation.cpp | 1 - clang/lib/Frontend/InitPreprocessor.cpp | 2 - clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp | 13 ++++-- 9 files changed, 46 insertions(+), 36 deletions(-) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 9a77f9d..8fbfe96 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -107,7 +107,6 @@ LANGOPT(Exceptions , 1, 0, "exception handling") LANGOPT(ObjCExceptions , 1, 0, "Objective-C exceptions") LANGOPT(CXXExceptions , 1, 0, "C++ exceptions") LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling") -LANGOPT(SEHExceptions , 1, 0, "SEH exception handling") LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation") LANGOPT(RTTI , 1, 1, "run-time type information") LANGOPT(RTTIData , 1, 1, "emit run-time type information data") diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index 689b384..fbab14b 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -437,8 +437,6 @@ def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">, HelpText<"Weakly link in the blocks runtime">; def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">, HelpText<"Use SjLj style exceptions">; -def fseh_exceptions : Flag<["-"], "fseh-exceptions">, - HelpText<"Use SEH style exceptions">; def split_dwarf_file : Separate<["-"], "split-dwarf-file">, HelpText<"File name to use for split dwarf debug info output">; def fno_wchar : Flag<["-"], "fno-wchar">, diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 9b23b47..7279951 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -248,9 +248,6 @@ public: /// UseSjLjExceptions - Does this tool chain use SjLj exceptions. virtual bool UseSjLjExceptions() const { return false; } - /// UseSEHExceptions - Does this tool chain use SEH exceptions. - virtual bool UseSEHExceptions() const { return false; } - /// getThreadModel() - Which thread model does this target use? virtual std::string getThreadModel() const { return "posix"; } diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 171ea58..a9cbfb8 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -3546,6 +3546,10 @@ public: DefineStd(Builder, "WIN64", Opts); Builder.defineMacro("__MINGW64__"); addMinGWDefines(Opts, Builder); + + // GCC defines this macro when it is using __gxx_personality_seh0. + if (!Opts.SjLjExceptions) + Builder.defineMacro("__SEH__"); } }; } // end anonymous namespace diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 9da910d..2e8f1ed 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -134,7 +134,7 @@ namespace { // This function must have prototype void(void*). const char *CatchallRethrowFn; - static const EHPersonality &get(const LangOptions &Lang); + static const EHPersonality &get(CodeGenModule &CGM); static const EHPersonality GNU_C; static const EHPersonality GNU_C_SJLJ; static const EHPersonality GNU_C_SEH; @@ -168,18 +168,26 @@ EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr }; const EHPersonality EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr }; -static const EHPersonality &getCPersonality(const LangOptions &L) { +/// On Win64, use libgcc's SEH personality function. We fall back to dwarf on +/// other platforms, unless the user asked for SjLj exceptions. +static bool useLibGCCSEHPersonality(const llvm::Triple &T) { + return T.isOSWindows() && T.getArch() == llvm::Triple::x86_64; +} + +static const EHPersonality &getCPersonality(const llvm::Triple &T, + const LangOptions &L) { if (L.SjLjExceptions) return EHPersonality::GNU_C_SJLJ; - if (L.SEHExceptions) + else if (useLibGCCSEHPersonality(T)) return EHPersonality::GNU_C_SEH; return EHPersonality::GNU_C; } -static const EHPersonality &getObjCPersonality(const LangOptions &L) { +static const EHPersonality &getObjCPersonality(const llvm::Triple &T, + const LangOptions &L) { switch (L.ObjCRuntime.getKind()) { case ObjCRuntime::FragileMacOSX: - return getCPersonality(L); + return getCPersonality(T, L); case ObjCRuntime::MacOSX: case ObjCRuntime::iOS: return EHPersonality::NeXT_ObjC; @@ -194,18 +202,19 @@ static const EHPersonality &getObjCPersonality(const LangOptions &L) { llvm_unreachable("bad runtime kind"); } -static const EHPersonality &getCXXPersonality(const LangOptions &L) { +static const EHPersonality &getCXXPersonality(const llvm::Triple &T, + const LangOptions &L) { if (L.SjLjExceptions) return EHPersonality::GNU_CPlusPlus_SJLJ; - else if (L.SEHExceptions) + else if (useLibGCCSEHPersonality(T)) return EHPersonality::GNU_CPlusPlus_SEH; - else - return EHPersonality::GNU_CPlusPlus; + return EHPersonality::GNU_CPlusPlus; } /// Determines the personality function to use when both C++ /// and Objective-C exceptions are being caught. -static const EHPersonality &getObjCXXPersonality(const LangOptions &L) { +static const EHPersonality &getObjCXXPersonality(const llvm::Triple &T, + const LangOptions &L) { switch (L.ObjCRuntime.getKind()) { // The ObjC personality defers to the C++ personality for non-ObjC // handlers. Unlike the C++ case, we use the same personality @@ -217,7 +226,7 @@ static const EHPersonality &getObjCXXPersonality(const LangOptions &L) { // In the fragile ABI, just use C++ exception handling and hope // they're not doing crazy exception mixing. case ObjCRuntime::FragileMacOSX: - return getCXXPersonality(L); + return getCXXPersonality(T, L); // The GCC runtime's personality function inherently doesn't support // mixed EH. Use the C++ personality just to avoid returning null. @@ -230,15 +239,17 @@ static const EHPersonality &getObjCXXPersonality(const LangOptions &L) { llvm_unreachable("bad runtime kind"); } -const EHPersonality &EHPersonality::get(const LangOptions &L) { +const EHPersonality &EHPersonality::get(CodeGenModule &CGM) { + const llvm::Triple &T = CGM.getTarget().getTriple(); + const LangOptions &L = CGM.getLangOpts(); if (L.CPlusPlus && L.ObjC1) - return getObjCXXPersonality(L); + return getObjCXXPersonality(T, L); else if (L.CPlusPlus) - return getCXXPersonality(L); + return getCXXPersonality(T, L); else if (L.ObjC1) - return getObjCPersonality(L); + return getObjCPersonality(T, L); else - return getCPersonality(L); + return getCPersonality(T, L); } static llvm::Constant *getPersonalityFn(CodeGenModule &CGM, @@ -315,8 +326,9 @@ void CodeGenModule::SimplifyPersonality() { if (!LangOpts.ObjCRuntime.isNeXTFamily()) return; - const EHPersonality &ObjCXX = EHPersonality::get(LangOpts); - const EHPersonality &CXX = getCXXPersonality(LangOpts); + const EHPersonality &ObjCXX = EHPersonality::get(*this); + const EHPersonality &CXX = + getCXXPersonality(getTarget().getTriple(), LangOpts); if (&ObjCXX == &CXX) return; @@ -734,7 +746,7 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { if (CGDebugInfo *DI = getDebugInfo()) DI->EmitLocation(Builder, CurEHLocation); - const EHPersonality &personality = EHPersonality::get(getLangOpts()); + const EHPersonality &personality = EHPersonality::get(CGM); // Create and configure the landing pad. llvm::BasicBlock *lpad = createBasicBlock("lpad"); @@ -1551,7 +1563,7 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() { Builder.SetInsertPoint(TerminateLandingPad); // Tell the backend that this is a landing pad. - const EHPersonality &Personality = EHPersonality::get(CGM.getLangOpts()); + const EHPersonality &Personality = EHPersonality::get(CGM); llvm::LandingPadInst *LPadInst = Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, NULL), getOpaquePersonalityFn(CGM, Personality), 0); @@ -1610,7 +1622,7 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) { EHResumeBlock = createBasicBlock("eh.resume"); Builder.SetInsertPoint(EHResumeBlock); - const EHPersonality &Personality = EHPersonality::get(CGM.getLangOpts()); + const EHPersonality &Personality = EHPersonality::get(CGM); // This can always be a call because we necessarily didn't find // anything on the EH stack which needs our help. diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index a648d61..7b87f2e 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -4140,8 +4140,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().UseSjLjExceptions()) CmdArgs.push_back("-fsjlj-exceptions"); - else if (getToolChain().UseSEHExceptions()) - CmdArgs.push_back("-fseh-exceptions"); // C++ "sane" operator new. if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 6531a40..a57c8b5 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1448,7 +1448,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions); Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions); Opts.SjLjExceptions = Args.hasArg(OPT_fsjlj_exceptions); - Opts.SEHExceptions = Args.hasArg(OPT_fseh_exceptions); Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp); Opts.RTTI = !Args.hasArg(OPT_fno_rtti); diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 75ac60f..f671a2f 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -572,8 +572,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__GXX_RTTI"); if (LangOpts.SjLjExceptions) Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__"); - if (LangOpts.SEHExceptions) - Builder.defineMacro("__SEH__"); if (LangOpts.Deprecated) Builder.defineMacro("__DEPRECATED"); diff --git a/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp b/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp index f247e99..bacddb2 100644 --- a/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp +++ b/clang/test/CodeGenCXX/mingw-w64-seh-exceptions.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 %s -fexceptions -fseh-exceptions -emit-llvm -triple x86_64-w64-windows-gnu -o - | FileCheck %s +// RUN: %clang_cc1 %s -fexceptions -emit-llvm -triple x86_64-w64-windows-gnu -o - | FileCheck %s --check-prefix=X64 +// RUN: %clang_cc1 %s -fexceptions -emit-llvm -triple i686-w64-windows-gnu -o - | FileCheck %s --check-prefix=X86 extern "C" void foo(); extern "C" void bar(); @@ -14,6 +15,10 @@ extern "C" void test() { foo(); } -// CHECK: define void @test() -// CHECK: invoke void @foo() -// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_seh0 to i8*) +// X64: define void @test() +// X64: invoke void @foo() +// X64: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_seh0 to i8*) + +// X86: define void @test() +// X86: invoke void @foo() +// X86: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) -- 2.7.4