diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -110,6 +110,11 @@ - Duplicate qualifiers on asm statements (ex. `asm volatile volatile ("")`) no longer produces a warning via -Wduplicate-decl-specifier, but now an error (this matches GCC's behavior). +- The deprecated argument ``-f[no-]sanitize-recover`` has changed to mean + ``-f[no-]sanitize-recover=all`` instead of + ``-f[no-]sanitize-recover=undefined,integer`` and is no longer deprecated. +- The argument to ``-f[no-]sanitize-trap=...`` is now optional and defaults to + ``all``. New Pragmas in Clang -------------------- diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst --- a/clang/docs/UndefinedBehaviorSanitizer.rst +++ b/clang/docs/UndefinedBehaviorSanitizer.rst @@ -54,6 +54,10 @@ * ``-fno-sanitize-recover=...``: print a verbose error report and exit the program; * ``-fsanitize-trap=...``: execute a trap instruction (doesn't require UBSan run-time support). +Note that the ``trap`` / ``recover`` options do not enable the corresponding +sanitizer, and in general need to be accompanied by a suitable ``-fsanitize=`` +flag. + For example if you compile/link your program as: .. code-block:: console diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1466,7 +1466,7 @@ **-f[no-]sanitize-recover=check1,check2,...** -**-f[no-]sanitize-recover=all** +**-f[no-]sanitize-recover[=all]** Controls which checks enabled by ``-fsanitize=`` flag are non-fatal. If the check is fatal, program will halt after the first error @@ -1492,6 +1492,8 @@ **-f[no-]sanitize-trap=check1,check2,...** +**-f[no-]sanitize-trap[=all]** + Controls which checks enabled by the ``-fsanitize=`` flag trap. This option is intended for use in cases where the sanitizer runtime cannot be used (for instance, when building libc or a kernel module), or where @@ -1499,9 +1501,7 @@ This flag is only compatible with :doc:`control flow integrity ` schemes and :doc:`UndefinedBehaviorSanitizer` - checks other than ``vptr``. If this flag - is supplied together with ``-fsanitize=undefined``, the ``vptr`` sanitizer - will be implicitly disabled. + checks other than ``vptr``. This flag is enabled by default for sanitizers in the ``cfi`` group. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1083,27 +1083,35 @@ : Joined<["-"], "fsanitize-hwaddress-abi=">, Group, HelpText<"Select the HWAddressSanitizer ABI to target (interceptor or platform, default interceptor). This option is currently unused.">; -def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group; -def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">, - Flags<[CoreOption, DriverOption]>, - Group; def fsanitize_recover_EQ : CommaJoined<["-"], "fsanitize-recover=">, Group, HelpText<"Enable recovery for specified sanitizers">; -def fno_sanitize_recover_EQ - : CommaJoined<["-"], "fno-sanitize-recover=">, - Group, - Flags<[CoreOption, DriverOption]>, - HelpText<"Disable recovery for specified sanitizers">; +def fno_sanitize_recover_EQ : CommaJoined<["-"], "fno-sanitize-recover=">, + Group, Flags<[CoreOption, DriverOption]>, + HelpText<"Disable recovery for specified sanitizers">; +def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group, + Alias, AliasArgs<["all"]>; +def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">, + Flags<[CoreOption, DriverOption]>, Group, + Alias, AliasArgs<["all"]>; def fsanitize_trap_EQ : CommaJoined<["-"], "fsanitize-trap=">, Group, HelpText<"Enable trapping for specified sanitizers">; def fno_sanitize_trap_EQ : CommaJoined<["-"], "fno-sanitize-trap=">, Group, Flags<[CoreOption, DriverOption]>, HelpText<"Disable trapping for specified sanitizers">; -def fsanitize_undefined_trap_on_error : Flag<["-"], "fsanitize-undefined-trap-on-error">, - Group; -def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-trap-on-error">, - Group; +def fsanitize_trap : Flag<["-"], "fsanitize-trap">, Group, + Alias, AliasArgs<["all"]>, + HelpText<"Enable trapping for all sanitizers">; +def fno_sanitize_trap : Flag<["-"], "fno-sanitize-trap">, Group, + Alias, AliasArgs<["all"]>, + Flags<[CoreOption, DriverOption]>, + HelpText<"Disable trapping for all sanitizers">; +def fsanitize_undefined_trap_on_error + : Flag<["-"], "fsanitize-undefined-trap-on-error">, Group, + Alias, AliasArgs<["undefined"]>; +def fno_sanitize_undefined_trap_on_error + : Flag<["-"], "fno-sanitize-undefined-trap-on-error">, Group, + Alias, AliasArgs<["undefined"]>; def fsanitize_minimal_runtime : Flag<["-"], "fsanitize-minimal-runtime">, Group; def fno_sanitize_minimal_runtime : Flag<["-"], "fno-sanitize-minimal-runtime">, diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -56,8 +56,6 @@ SanitizerKind::Unreachable | SanitizerKind::Return; static const SanitizerMask AlwaysRecoverable = SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress; -static const SanitizerMask LegacyFsanitizeRecoverMask = - SanitizerKind::Undefined | SanitizerKind::Integer; static const SanitizerMask NeedsLTO = SanitizerKind::CFI; static const SanitizerMask TrappingSupported = (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | @@ -221,16 +219,6 @@ } else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) { Arg->claim(); TrapRemove |= expandSanitizerGroups(parseArgValues(D, Arg, true)); - } else if (Arg->getOption().matches( - options::OPT_fsanitize_undefined_trap_on_error)) { - Arg->claim(); - TrappingKinds |= - expandSanitizerGroups(SanitizerKind::UndefinedGroup & ~TrapRemove) & - ~TrapRemove; - } else if (Arg->getOption().matches( - options::OPT_fno_sanitize_undefined_trap_on_error)) { - Arg->claim(); - TrapRemove |= expandSanitizerGroups(SanitizerKind::UndefinedGroup); } } @@ -541,18 +529,7 @@ SanitizerMask DiagnosedUnrecoverableKinds; SanitizerMask DiagnosedAlwaysRecoverableKinds; for (const auto *Arg : Args) { - const char *DeprecatedReplacement = nullptr; - if (Arg->getOption().matches(options::OPT_fsanitize_recover)) { - DeprecatedReplacement = - "-fsanitize-recover=undefined,integer' or '-fsanitize-recover=all"; - RecoverableKinds |= expandSanitizerGroups(LegacyFsanitizeRecoverMask); - Arg->claim(); - } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) { - DeprecatedReplacement = "-fno-sanitize-recover=undefined,integer' or " - "'-fno-sanitize-recover=all"; - RecoverableKinds &= ~expandSanitizerGroups(LegacyFsanitizeRecoverMask); - Arg->claim(); - } else if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) { + if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) { SanitizerMask Add = parseArgValues(D, Arg, true); // Report error if user explicitly tries to recover from unrecoverable // sanitizer. @@ -581,10 +558,6 @@ RecoverableKinds &= ~expandSanitizerGroups(Remove); Arg->claim(); } - if (DeprecatedReplacement) { - D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args) - << DeprecatedReplacement; - } } RecoverableKinds &= Kinds; RecoverableKinds &= ~Unrecoverable; diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -3,6 +3,7 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP // RUN: %clang -target x86_64-linux-gnu -fsanitize-undefined-trap-on-error -fsanitize=undefined-trap %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP +// RUN: %clang -target x86_64-linux-gnu -fsanitize-trap -fsanitize=undefined-trap %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP // CHECK-UNDEFINED-TRAP-NOT: -fsanitize-recover // CHECK-UNDEFINED-TRAP: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){18}"}} // CHECK-UNDEFINED-TRAP: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound" @@ -366,6 +367,7 @@ // CHECK-PARTIAL-RECOVER: "-fsanitize-recover={{((shift-base),?){1}"}} // RUN: %clang -target x86_64-linux-gnu %s -fsanitize=address -fsanitize-recover=all -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER-ASAN +// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=address -fsanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER-ASAN // CHECK-RECOVER-ASAN: "-fsanitize-recover=address" // RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fsanitize-recover=foobar,object-size,unreachable -### 2>&1 | FileCheck %s --check-prefix=CHECK-DIAG-RECOVER @@ -373,8 +375,6 @@ // CHECK-DIAG-RECOVER: unsupported argument 'unreachable' to option 'fsanitize-recover=' // RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fsanitize-recover -fno-sanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEPRECATED-RECOVER -// CHECK-DEPRECATED-RECOVER: argument '-fsanitize-recover' is deprecated, use '-fsanitize-recover=undefined,integer' or '-fsanitize-recover=all' instead -// CHECK-DEPRECATED-RECOVER: argument '-fno-sanitize-recover' is deprecated, use '-fno-sanitize-recover=undefined,integer' or '-fno-sanitize-recover=all' instead // CHECK-DEPRECATED-RECOVER-NOT: is deprecated // RUN: %clang -target x86_64-linux-gnu %s -fsanitize=kernel-address -fno-sanitize-recover=kernel-address -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-KASAN