From d816be98bb6273f653377c8ed75efecccff51ad8 Mon Sep 17 00:00:00 2001 From: Filipe Cabecinhas Date: Thu, 29 Jan 2015 23:56:43 +0000 Subject: [PATCH] Add some more PS4 driver settings related to rtti and exceptions. Summary: The PS4 defaults to -fno-rtti, and has to have rtti enabled when enabling exceptions. This commit makes clang add the -fno-rtti by default on the PS4, unless -frtti was passed in. It also diagnoses misuses for the PS4: - Exceptions need rtti. Warn and enable rtti if no rtti flag was passed, error if -fno-rtti was passed. I also added a more general warning for when -fno-rtti is the default (currently it's only on the PS4) and the vptr sanitizer is on. Fixed a few tests, due to different flag order when passing cc1 arguments. Reviewers: chandlerc Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D7250 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@227518 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticDriverKinds.td | 6 +++ lib/Driver/Tools.cpp | 46 +++++++++++++---- test/Driver/rtti-options.cpp | 52 ++++++++++++++++++++ 3 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 test/Driver/rtti-options.cpp diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index 41c78ee669..76853d8810 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -160,6 +160,12 @@ def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">, InGroup>; def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (zlib not installed)">, InGroup>; +def warn_drv_enabling_rtti_with_exceptions : Warning< + "implicitly enabling rtti for exception handling">, + InGroup>; +def warn_drv_disabling_vptr_no_rtti_default : Warning< + "implicitly disabling vptr sanitizer because rtti wasn't enabled">, + InGroup>; def note_drv_command_failed_diag_msg : Note< "diagnostic msg: %0">; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 2258f69ef8..91cf841577 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -3956,20 +3956,48 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, false)) CmdArgs.push_back("-fno-elide-constructors"); - // -frtti is default. - if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti) || + // -frtti is default, except for the PS4 CPU. + if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti, + !Triple.isPS4CPU()) || KernelOrKext) { - CmdArgs.push_back("-fno-rtti"); + 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. + if (Triple.isPS4CPU()) { + if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions, + options::OPT_fexceptions)) { + if (NoRTTIArg) + D.Diag(diag::err_drv_argument_not_allowed_with) + << NoRTTIArg->getAsString(Args) << A->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()) { - std::string NoRttiArg = - Args.getLastArg(options::OPT_mkernel, - options::OPT_fapple_kext, - options::OPT_fno_rtti)->getAsString(Args); - D.Diag(diag::err_drv_argument_not_allowed_with) - << "-fsanitize=vptr" << NoRttiArg; + // 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"); + } } + + if (!RTTIEnabled) + CmdArgs.push_back("-fno-rtti"); } // -fshort-enums=0 is default for all architectures except Hexagon. diff --git a/test/Driver/rtti-options.cpp b/test/Driver/rtti-options.cpp new file mode 100644 index 0000000000..d116ba34cd --- /dev/null +++ b/test/Driver/rtti-options.cpp @@ -0,0 +1,52 @@ +// Check that we emit warnings/errors for different combinations of +// exceptions, rtti, and vptr sanitizer flags when targetting the PS4. +// No warnings/errors should be emitted for unknown, except if combining +// the vptr sanitizer with -fno-rtti + +// -fsanitize=vptr +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-WARN %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=undefined %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-WARN %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=undefined -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=undefined -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=vptr %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=vptr -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=vptr -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=undefined %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=undefined -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fsanitize=undefined -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s + +// Exceptions + no/default rtti +// RUN: %clang -### -c -target x86_64-scei-ps4 -fexceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-EXC-ERROR %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fcxx-exceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-EXC-ERROR-CXX %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fexceptions %s 2>&1 | FileCheck -check-prefix=CHECK-EXC-WARN %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-EXC-WARN %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fexceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fcxx-exceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fexceptions %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s + +// -frtti + exceptions +// RUN: %clang -### -c -target x86_64-scei-ps4 -fexceptions -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fcxx-exceptions -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fexceptions -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fcxx-exceptions -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s + +// -f{no-,}rtti/default +// RUN: %clang -### -c -target x86_64-scei-ps4 -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-RTTI %s +// RUN: %clang -### -c -target x86_64-scei-ps4 -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-NO-RTTI %s +// RUN: %clang -### -c -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=CHECK-NO-RTTI %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-RTTI %s +// RUN: %clang -### -c -target x86_64-unknown-unknown -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-NO-RTTI %s +// RUN: %clang -### -c -target x86_64-unknown-unknown %s 2>&1 | FileCheck -check-prefix=CHECK-RTTI %s + +// CHECK-SAN-WARN: implicitly disabling vptr sanitizer because rtti wasn't enabled +// CHECK-SAN-ERROR: invalid argument '-fsanitize=vptr' not allowed with '-fno-rtti' +// CHECK-EXC-WARN: implicitly enabling rtti for exception handling +// CHECK-EXC-ERROR: invalid argument '-fno-rtti' not allowed with '-fexceptions' +// CHECK-EXC-ERROR-CXX: invalid argument '-fno-rtti' not allowed with '-fcxx-exceptions' +// CHECK-RTTI-NOT: "-fno-rtti" +// CHECK-NO-RTTI-NOT: "-frtti" + +// CHECK-OK-NOT: {{warning:|error:}} -- 2.40.0