From 0bb1fc410bf249ee9f8369e0219405804d68cba6 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 10 Jul 2015 22:25:44 +0000 Subject: [PATCH] Disable C++ EH by default for clang-cl and MSVC environments We don't need any more bug reports from users telling us that MSVC-style C++ exceptions are broken. Developers and adventurous users can still test the existing functionality by passing along -fexceptions to either clang or clang-cl. llvm-svn: 241952 --- clang/include/clang/Driver/Options.td | 2 +- clang/lib/Driver/Tools.cpp | 37 +++++++++++++++------------ clang/test/Driver/cl-eh.cpp | 14 ++++++---- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 436c9001d617..6cc92f61fb7a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -506,7 +506,7 @@ def femit_all_decls : Flag<["-"], "femit-all-decls">, Group, Flags<[CC1 HelpText<"Emit all declarations, even if unused">; def fencoding_EQ : Joined<["-"], "fencoding=">, Group; def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group, Flags<[CoreOption]>; -def fexceptions : Flag<["-"], "fexceptions">, Group, Flags<[CC1Option]>, +def fexceptions : Flag<["-"], "fexceptions">, Group, Flags<[CC1Option, CoreOption]>, HelpText<"Enable support for exception handling">; def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">, Group; diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 38c3d5cdec14..180533396c18 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -2041,17 +2041,6 @@ shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime, Triple.getArch() == llvm::Triple::arm)); } -// exceptionSettings() exists to share the logic between -cc1 and linker -// invocations. -static bool exceptionSettings(const ArgList &Args, const llvm::Triple &Triple) { - if (Arg *A = Args.getLastArg(options::OPT_fexceptions, - options::OPT_fno_exceptions)) - if (A->getOption().matches(options::OPT_fexceptions)) - return true; - - return false; -} - /// Adds exception related arguments to the driver command arguments. There's a /// master flag, -fexceptions and also language specific flags to enable/disable /// C++ and Objective-C exceptions. This makes it possible to for example @@ -2075,8 +2064,9 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType, return; } - // Gather the exception settings from the command line arguments. - bool EH = exceptionSettings(Args, Triple); + // See if the user explicitly enabled exceptions. + bool EH = Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, + false); // Obj-C exceptions are enabled by default, regardless of -fexceptions. This // is not necessarily sensible, but follows GCC. @@ -2089,8 +2079,11 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType, } if (types::isCXX(InputType)) { - bool CXXExceptionsEnabled = - Triple.getArch() != llvm::Triple::xcore && !Triple.isPS4CPU(); + // Disable C++ EH by default on XCore, PS4, and MSVC. + // FIXME: Remove MSVC from this list once things work. + bool CXXExceptionsEnabled = Triple.getArch() != llvm::Triple::xcore && + !Triple.isPS4CPU() && + !Triple.isWindowsMSVCEnvironment(); Arg *ExceptionArg = Args.getLastArg( options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions, options::OPT_fexceptions, options::OPT_fno_exceptions); @@ -5040,6 +5033,7 @@ struct EHFlags { /// The default is /EHs-c-, meaning cleanups are disabled. static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) { EHFlags EH; + std::vector EHArgs = Args.getAllArgValues(options::OPT__SLASH_EH); for (auto EHVal : EHArgs) { @@ -5061,6 +5055,15 @@ static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) { break; } } + + // Only enable C++ exceptions if the user opts into it by passing + // -fexceptions. Lots of build systems implicitly pass /EHsc when users don't + // actually need it. + // FIXME: Remove this when they work out of the box. + if (!Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, + /*default=*/false)) + EH = EHFlags(); + return EH; } @@ -9102,7 +9105,9 @@ void XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_v)) CmdArgs.push_back("-v"); - if (exceptionSettings(Args, getToolChain().getTriple())) + // Pass -fexceptions through to the linker if it was present. + if (Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, + false)) CmdArgs.push_back("-fexceptions"); AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs); diff --git a/clang/test/Driver/cl-eh.cpp b/clang/test/Driver/cl-eh.cpp index a71491edeaf3..e80d39b9419a 100644 --- a/clang/test/Driver/cl-eh.cpp +++ b/clang/test/Driver/cl-eh.cpp @@ -4,9 +4,13 @@ // Note: %s must be preceded by --, otherwise it may be interpreted as a // command-line option, e.g. on Mac where %s is commonly under /Users. +// RUN: %clang_cl /c /EHsc -fexceptions -### -- %s 2>&1 | FileCheck -check-prefix=EHscfex %s +// EHscfex: "-fcxx-exceptions" +// EHscfex: "-fexceptions" + // RUN: %clang_cl /c /EHsc -### -- %s 2>&1 | FileCheck -check-prefix=EHsc %s -// EHsc: "-fcxx-exceptions" -// EHsc: "-fexceptions" +// EHsc-NOT: "-fcxx-exceptions" +// EHsc-NOT: "-fexceptions" // RUN: %clang_cl /c /EHs-c- -### -- %s 2>&1 | FileCheck -check-prefix=EHs_c_ %s // EHs_c_-NOT: "-fcxx-exceptions" @@ -16,14 +20,14 @@ // EHs_EHc_-NOT: "-fcxx-exceptions" // EHs_EHc_-NOT: "-fexceptions" -// RUN: %clang_cl /c /EHs- /EHs -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHs %s +// RUN: %clang_cl /c /EHs- /EHs -fexceptions -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHs %s // EHs_EHs: "-fcxx-exceptions" // EHs_EHs: "-fexceptions" -// RUN: %clang_cl /c /EHs- /EHsa -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHa %s +// RUN: %clang_cl /c /EHs- /EHsa -fexceptions -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHa %s // EHs_EHa: "-fcxx-exceptions" // EHs_EHa: "-fexceptions" -// RUN: %clang_cl /c /EHinvalid -### -- %s 2>&1 | FileCheck -check-prefix=EHinvalid %s +// RUN: %clang_cl /c /EHinvalid -fexceptions -### -- %s 2>&1 | FileCheck -check-prefix=EHinvalid %s // EHinvalid: error: invalid value 'invalid' in '/EH' // EHinvalid-NOT: error: