diff options
Diffstat (limited to 'clang/lib/Driver/Tools.cpp')
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 97 |
1 files changed, 34 insertions, 63 deletions
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 6be4f51bace..f47a92b7c39 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1931,16 +1931,17 @@ static bool exceptionSettings(const ArgList &Args, const llvm::Triple &Triple) { return false; } -/// addExceptionArgs - 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 disable C++ exceptions but enable -/// Objective-C exceptions. +/// 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 +/// disable C++ exceptions but enable Objective-C exceptions. static void addExceptionArgs(const ArgList &Args, types::ID InputType, - const llvm::Triple &Triple, - bool KernelOrKext, + const ToolChain &TC, bool KernelOrKext, const ObjCRuntime &objcRuntime, ArgStringList &CmdArgs) { + const Driver &D = TC.getDriver(); + const llvm::Triple &Triple = TC.getTriple(); + if (KernelOrKext) { // -mkernel and -fapple-kext imply no exceptions, so claim exception related // arguments now to avoid warnings about unused arguments. @@ -1970,15 +1971,30 @@ static void addExceptionArgs(const ArgList &Args, types::ID InputType, if (types::isCXX(InputType)) { bool CXXExceptionsEnabled = Triple.getArch() != llvm::Triple::xcore && !Triple.isPS4CPU(); - if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions, - options::OPT_fno_cxx_exceptions, - options::OPT_fexceptions, - options::OPT_fno_exceptions)) + Arg *ExceptionArg = Args.getLastArg( + options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions, + options::OPT_fexceptions, options::OPT_fno_exceptions); + if (ExceptionArg) CXXExceptionsEnabled = - A->getOption().matches(options::OPT_fcxx_exceptions) || - A->getOption().matches(options::OPT_fexceptions); + ExceptionArg->getOption().matches(options::OPT_fcxx_exceptions) || + ExceptionArg->getOption().matches(options::OPT_fexceptions); if (CXXExceptionsEnabled) { + if (Triple.isPS4CPU()) { + ToolChain::RTTIMode RTTIMode = TC.getRTTIMode(); + assert(ExceptionArg && + "On the PS4 exceptions should only be enabled if passing " + "an argument"); + if (RTTIMode == ToolChain::RM_DisabledExplicitly) { + const Arg *RTTIArg = TC.getRTTIArg(); + assert(RTTIArg && "RTTI disabled explicitly but no RTTIArg!"); + D.Diag(diag::err_drv_argument_not_allowed_with) + << RTTIArg->getAsString(Args) << ExceptionArg->getAsString(Args); + } else if (RTTIMode == ToolChain::RM_EnabledImplicitly) + D.Diag(diag::warn_drv_enabling_rtti_with_exceptions); + } else + assert(TC.getRTTIMode() != ToolChain::RM_DisabledImplicitly); + CmdArgs.push_back("-fcxx-exceptions"); EH = true; @@ -4004,56 +4020,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, false)) CmdArgs.push_back("-fno-elide-constructors"); - // -frtti is default, except for the PS4 CPU. - if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti, - !Triple.isPS4CPU()) || - KernelOrKext) { - bool IsCXX = types::isCXX(InputType); - bool RTTIEnabled = false; - Arg *NoRTTIArg = Args.getLastArg( - options::OPT_mkernel, options::OPT_fapple_kext, options::OPT_fno_rtti); - - // PS4 requires rtti when exceptions are enabled. If -fno-rtti was - // explicitly passed, error out. Otherwise enable rtti and emit a - // warning. - Arg *Exceptions = Args.getLastArg( - options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions, - options::OPT_fexceptions, options::OPT_fno_exceptions); - if (Triple.isPS4CPU() && Exceptions) { - bool CXXExceptions = - (IsCXX && - Exceptions->getOption().matches(options::OPT_fexceptions)) || - Exceptions->getOption().matches(options::OPT_fcxx_exceptions); - if (CXXExceptions) { - if (NoRTTIArg) - D.Diag(diag::err_drv_argument_not_allowed_with) - << NoRTTIArg->getAsString(Args) << Exceptions->getAsString(Args); - else { - RTTIEnabled = true; - D.Diag(diag::warn_drv_enabling_rtti_with_exceptions); - } - } - } - - // -fno-rtti cannot usefully be combined with -fsanitize=vptr. - if (Sanitize.sanitizesVptr()) { - // If rtti was explicitly disabled and the vptr sanitizer is on, error - // out. Otherwise, warn that vptr will be disabled unless -frtti is - // passed. - if (NoRTTIArg) { - D.Diag(diag::err_drv_argument_not_allowed_with) - << "-fsanitize=vptr" << NoRTTIArg->getAsString(Args); - } else { - D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default); - // All sanitizer switches have been pushed. This -fno-sanitize - // will override any -fsanitize={vptr,undefined} passed before it. - CmdArgs.push_back("-fno-sanitize=vptr"); - } - } + ToolChain::RTTIMode RTTIMode = getToolChain().getRTTIMode(); - if (!RTTIEnabled) - CmdArgs.push_back("-fno-rtti"); - } + if (RTTIMode == ToolChain::RM_DisabledExplicitly || + RTTIMode == ToolChain::RM_DisabledImplicitly) + CmdArgs.push_back("-fno-rtti"); // -fshort-enums=0 is default for all architectures except Hexagon. if (Args.hasFlag(options::OPT_fshort_enums, @@ -4231,7 +4202,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Handle GCC-style exception args. if (!C.getDriver().IsCLMode()) - addExceptionArgs(Args, InputType, getToolChain().getTriple(), KernelOrKext, + addExceptionArgs(Args, InputType, getToolChain(), KernelOrKext, objcRuntime, CmdArgs); if (getToolChain().UseSjLjExceptions()) |