diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 52360b67b306c..76a6463881c6f 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -270,6 +270,8 @@ CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0, Benign) ///< Enable use-after-delet CODEGENOPT(SanitizeCfiCrossDso, 1, 0, Benign) ///< Enable cross-dso support in CFI. CODEGENOPT(SanitizeMinimalRuntime, 1, 0, Benign) ///< Use "_minimal" sanitizer runtime for ///< diagnostics. +CODEGENOPT(SanitizeHandlerPreserveAllRegs, 1, 0, Benign) ///< Use "_preserve" sanitizer runtime for + ///< diagnostics. CODEGENOPT(SanitizeCfiICallGeneralizePointers, 1, 0, Benign) ///< Generalize pointer types in ///< CFI icall function signatures CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0, Benign) ///< Normalize integer types in diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index eea7897e96afd..6fd059263fb4d 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -67,6 +67,7 @@ class SanitizerArgs { bool TsanFuncEntryExit = true; bool TsanAtomics = true; bool MinimalRuntime = false; + bool HandlerPreserveAllRegs = false; // True if cross-dso CFI support if provided by the system (i.e. Android). bool ImplicitCfiRuntime = false; bool NeedsMemProfRt = false; diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 786acd6abbd21..794d0448b158c 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -2660,6 +2660,15 @@ defm sanitize_minimal_runtime : BoolOption<"f", "sanitize-minimal-runtime", PosFlag, NegFlag>, Group; +defm sanitize_handler_preserve_all_regs + : BoolOption< + "f", "sanitize-handler-preserve-all-regs", + CodeGenOpts<"SanitizeHandlerPreserveAllRegs">, DefaultFalse, + PosFlag, + NegFlag>, + Group; def fsanitize_link_runtime : Flag<["-"], "fsanitize-link-runtime">, Group; def fno_sanitize_link_runtime : Flag<["-"], "fno-sanitize-link-runtime">, diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 420c4cddbc8dd..10f85b6bd1651 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -423,6 +423,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, MinimalRuntime = Args.hasFlag(options::OPT_fsanitize_minimal_runtime, options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime); + HandlerPreserveAllRegs = + Args.hasFlag(options::OPT_fsanitize_handler_preserve_all_regs, + options::OPT_fno_sanitize_handler_preserve_all_regs, + HandlerPreserveAllRegs); // The object size sanitizer should not be enabled at -O0. Arg *OptLevel = Args.getLastArg(options::OPT_O_Group); @@ -1469,6 +1473,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, if (MinimalRuntime) CmdArgs.push_back("-fsanitize-minimal-runtime"); + if (HandlerPreserveAllRegs) + CmdArgs.push_back("-fsanitize-handler-preserve-all-regs"); + if (AsanFieldPadding) CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" + Twine(AsanFieldPadding))); diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index 263301ad4466a..f2a4d8c50ec23 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -984,6 +984,11 @@ // CHECK-UBSAN-MINIMAL: "-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-UBSAN-MINIMAL: "-fsanitize-minimal-runtime" +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-minimal-runtime -fsanitize-handler-preserve-all-regs %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-MINIMAL-PRESERVE +// CHECK-UBSAN-MINIMAL-PRESERVE: "-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-UBSAN-MINIMAL-PRESERVE: "-fsanitize-minimal-runtime" +// CHECK-UBSAN-MINIMAL-PRESERVE: "-fsanitize-handler-preserve-all-regs + // RUN: %clang --target=x86_64-linux-gnu -fsanitize=integer -fsanitize-trap=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTSAN-TRAP // CHECK-INTSAN-TRAP: "-fsanitize-trap=integer-divide-by-zero,shift-base,shift-exponent,signed-integer-overflow,unsigned-integer-overflow,unsigned-shift-base,implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change"