summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver/Tools.cpp
diff options
context:
space:
mode:
authorFilipe Cabecinhas <me@filcab.net>2015-02-19 01:04:49 +0000
committerFilipe Cabecinhas <me@filcab.net>2015-02-19 01:04:49 +0000
commitec5d0e6423f934768290269512ec942829a9e5a4 (patch)
treec97320d01df5e13d7b6f4f3d990623068ec41eb4 /clang/lib/Driver/Tools.cpp
parentfb8002cbe03de16225732c7a5a5875be6d538014 (diff)
downloadbcm5719-llvm-ec5d0e6423f934768290269512ec942829a9e5a4.tar.gz
bcm5719-llvm-ec5d0e6423f934768290269512ec942829a9e5a4.zip
Improve our handling of rtti/sanitize=vptr/sanitize=undefined
This patch removes the huge blob of code that is dealing with rtti/exceptions/sanitizers and replaces it with: A ToolChain function which, for a given set of Args, figures out if rtti should be: - enabled - disabled implicitly - disabled explicitly A change in the way SanitizerArgs figures out what sanitizers to enable (or if it should error out, or warn); And a check for exceptions/rtti interaction inside addExceptionArgs. The RTTIMode algorithm is: - If -mkernel, -fapple-kext, or -fno-rtti are passed, rtti was disabled explicitly; - If -frtti was passed or we're not targetting the PS4, rtti is enabled; - If -fexceptions or -fcxx-exceptions was passed and we're targetting the PS4, rtti was enabled implicitly; - If we're targetting the PS4, rtti is disabled implicitly; - Otherwise, rtti is enabled; Since the only flag needed to pass to -cc1 is -fno-rtti if we want to disable it, there's no problem in saying rtti is enabled if we're compiling C code, so we don't look at the input file type. addExceptionArgs now looks at the RTTIMode and warns that rtti is being enabled implicitly if targetting the PS4 and exceptions are on. It also errors out if, targetting the PS4, -fno-rtti was passed, and exceptions were turned on. SanitizerArgs now errors out if rtti was disabled explicitly and the vptr sanitizer was enabled implicitly, but just turns off vptr if rtti is disabled but -fsanitize=undefined was passed. Also fixed tests, removed duplicate name from addExceptionArgs comment, and added one or two surrounding lines when running clang-format. This changes test/Driver/fsanitize.c to make it not expect a warning when passed -fsanitize=undefined -fno-rtti, but expect vptr to not be on. Removed all users and definition of SanitizerArgs::sanitizesVptr(). Reviewers: samsonov Subscribers: llvm-commits, samsonov, rsmith Differential Revision: http://reviews.llvm.org/D7525 llvm-svn: 229801
Diffstat (limited to 'clang/lib/Driver/Tools.cpp')
-rw-r--r--clang/lib/Driver/Tools.cpp97
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())
OpenPOWER on IntegriCloud