diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 2 | ||||
-rw-r--r-- | lib/Driver/SanitizerArgs.h | 18 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 32 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 2 |
6 files changed, 57 insertions, 8 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 9bef08b4a5..aad877134d 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1975,6 +1975,13 @@ void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName, ArrayRef<llvm::Value *> DynamicArgs, CheckRecoverableKind RecoverKind) { assert(SanOpts != &SanitizerOptions::Disabled); + + if (CGM.getCodeGenOpts().SanitizeUndefinedTrapOnError) { + assert (RecoverKind != CRK_AlwaysRecoverable && + "Runtime call required for AlwaysRecoverable kind!"); + return EmitTrapCheck(Checked); + } + llvm::BasicBlock *Cont = createBasicBlock("cont"); llvm::BasicBlock *Handler = createBasicBlock("handler." + CheckName); @@ -2043,7 +2050,7 @@ void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName, EmitBlock(Cont); } -void CodeGenFunction::EmitTrapvCheck(llvm::Value *Checked) { +void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) { llvm::BasicBlock *Cont = createBasicBlock("cont"); // If we're optimizing, collapse all calls to trap down to just one per diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 7f0eda8993..49494be901 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -2044,7 +2044,7 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { if (!isSigned || CGF.SanOpts->SignedIntegerOverflow) EmitBinOpCheck(Builder.CreateNot(overflow), Ops); else - CGF.EmitTrapvCheck(Builder.CreateNot(overflow)); + CGF.EmitTrapCheck(Builder.CreateNot(overflow)); return result; } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 6f06b3bc26..ce3db3f4ec 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2606,7 +2606,7 @@ public: /// \brief Create a basic block that will call the trap intrinsic, and emit a /// conditional branch to it, for the -ftrapv checks. - void EmitTrapvCheck(llvm::Value *Checked); + void EmitTrapCheck(llvm::Value *Checked); /// EmitCallArg - Emit a single call argument. void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType); diff --git a/lib/Driver/SanitizerArgs.h b/lib/Driver/SanitizerArgs.h index a281959891..bc3aa58331 100644 --- a/lib/Driver/SanitizerArgs.h +++ b/lib/Driver/SanitizerArgs.h @@ -36,25 +36,32 @@ class SanitizerArgs { NeedsAsanRt = Address, NeedsTsanRt = Thread, NeedsMsanRt = Memory, - NeedsUbsanRt = (Undefined & ~Bounds) | Integer + NeedsUbsanRt = (Undefined & ~Bounds) | Integer, + NotAllowedWithTrap = Vptr }; unsigned Kind; std::string BlacklistFile; bool MsanTrackOrigins; bool AsanZeroBaseShadow; + bool UbsanTrapOnError; public: SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false), - AsanZeroBaseShadow(false) {} + AsanZeroBaseShadow(false), UbsanTrapOnError(false) {} /// Parses the sanitizer arguments from an argument list. SanitizerArgs(const Driver &D, const ArgList &Args); bool needsAsanRt() const { return Kind & NeedsAsanRt; } bool needsTsanRt() const { return Kind & NeedsTsanRt; } bool needsMsanRt() const { return Kind & NeedsMsanRt; } - bool needsUbsanRt() const { return Kind & NeedsUbsanRt; } + bool needsUbsanRt() const { + if (UbsanTrapOnError) + return false; + return Kind & NeedsUbsanRt; + } bool sanitizesVptr() const { return Kind & Vptr; } + bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; } void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const { if (!Kind) @@ -127,8 +134,9 @@ class SanitizerArgs { Remove = Thread; DeprecatedReplacement = "-fno-sanitize=thread"; } else if (A->getOption().matches(options::OPT_fcatch_undefined_behavior)) { - Add = Undefined; - DeprecatedReplacement = "-fsanitize=undefined"; + Add = UndefinedTrap; + DeprecatedReplacement = + "-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error"; } else if (A->getOption().matches(options::OPT_fbounds_checking) || A->getOption().matches(options::OPT_fbounds_checking_EQ)) { Add = Bounds; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index e4be6935ea..f925f762e5 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1459,6 +1459,33 @@ SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) AllKinds |= Add; } + UbsanTrapOnError = + Args.hasArg(options::OPT_fcatch_undefined_behavior) || + Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error, + options::OPT_fno_sanitize_undefined_trap_on_error, false); + + if (Args.hasArg(options::OPT_fcatch_undefined_behavior) && + !Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error, + options::OPT_fno_sanitize_undefined_trap_on_error, true)) { + D.Diag(diag::err_drv_argument_not_allowed_with) + << "-fcatch-undefined-behavior" + << "-fno-sanitize-undefined-trap-on-error"; + } + + // Warn about undefined sanitizer options that require runtime support. + if (UbsanTrapOnError && notAllowedWithTrap()) { + if (Args.hasArg(options::OPT_fcatch_undefined_behavior)) + D.Diag(diag::err_drv_argument_not_allowed_with) + << lastArgumentForKind(D, Args, NotAllowedWithTrap) + << "-fcatch-undefined-behavior"; + else if (Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error, + options::OPT_fno_sanitize_undefined_trap_on_error, + false)) + D.Diag(diag::err_drv_argument_not_allowed_with) + << lastArgumentForKind(D, Args, NotAllowedWithTrap) + << "-fsanitize-undefined-trap-on-error"; + } + // Only one runtime library can be used at once. bool NeedsAsan = needsAsanRt(); bool NeedsTsan = needsTsanRt(); @@ -2501,6 +2528,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, true)) CmdArgs.push_back("-fno-sanitize-recover"); + if (Args.hasArg(options::OPT_fcatch_undefined_behavior) || + Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error, + options::OPT_fno_sanitize_undefined_trap_on_error, false)) + CmdArgs.push_back("-fsanitize-undefined-trap-on-error"); + // Report and error for -faltivec on anything other then PowerPC. if (const Arg *A = Args.getLastArg(options::OPT_faltivec)) if (!(getToolChain().getTriple().getArch() == llvm::Triple::ppc || diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index b200637cb5..245de3416f 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -392,6 +392,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_fsanitize_memory_track_origins); Opts.SanitizeAddressZeroBaseShadow = Args.hasArg(OPT_fsanitize_address_zero_base_shadow); + Opts.SanitizeUndefinedTrapOnError = + Args.hasArg(OPT_fsanitize_undefined_trap_on_error); Opts.SSPBufferSize = Args.getLastArgIntValue(OPT_stack_protector_buffer_size, 8, Diags); Opts.StackRealignment = Args.hasArg(OPT_mstackrealign); |