From 9881b78b53dd295f7ee63bf33c99d68b73c2f289 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 18 Jun 2015 23:59:22 +0000 Subject: Introduce -fsanitize-trap= flag. This flag controls whether a given sanitizer traps upon detecting an error. It currently only supports UBSan. The existing flag -fsanitize-undefined-trap-on-error has been made an alias of -fsanitize-trap=undefined. This change also cleans up some awkward behavior around the combination of -fsanitize-trap=undefined and -fsanitize=undefined. Previously we would reject command lines containing the combination of these two flags, as -fsanitize=vptr is not compatible with trapping. This required the creation of -fsanitize=undefined-trap, which excluded -fsanitize=vptr (and -fsanitize=function, but this seems like an oversight). Now, -fsanitize=undefined is an alias for -fsanitize=undefined-trap, and if -fsanitize-trap=undefined is specified, we treat -fsanitize=vptr as an "unsupported" flag, which means that we error out if the flag is specified explicitly, but implicitly disable it if the flag was implied by -fsanitize=undefined. Differential Revision: http://reviews.llvm.org/D10464 llvm-svn: 240105 --- clang/lib/CodeGen/CGExpr.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'clang/lib/CodeGen') diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 1ed45a33d0f..85746aea04b 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2300,15 +2300,24 @@ void CodeGenFunction::EmitCheck( llvm::Value *FatalCond = nullptr; llvm::Value *RecoverableCond = nullptr; + llvm::Value *TrapCond = nullptr; for (int i = 0, n = Checked.size(); i < n; ++i) { llvm::Value *Check = Checked[i].first; + // -fsanitize-trap= overrides -fsanitize-recover=. llvm::Value *&Cond = - CGM.getCodeGenOpts().SanitizeRecover.has(Checked[i].second) - ? RecoverableCond - : FatalCond; + CGM.getCodeGenOpts().SanitizeTrap.has(Checked[i].second) + ? TrapCond + : CGM.getCodeGenOpts().SanitizeRecover.has(Checked[i].second) + ? RecoverableCond + : FatalCond; Cond = Cond ? Builder.CreateAnd(Cond, Check) : Check; } + if (TrapCond) + EmitTrapCheck(TrapCond); + if (!FatalCond && !RecoverableCond) + return; + llvm::Value *JointCond; if (FatalCond && RecoverableCond) JointCond = Builder.CreateAnd(FatalCond, RecoverableCond); @@ -2326,15 +2335,6 @@ void CodeGenFunction::EmitCheck( } #endif - if (CGM.getCodeGenOpts().SanitizeUndefinedTrapOnError) { - assert(RecoverKind != CheckRecoverableKind::AlwaysRecoverable && - "Runtime call required for AlwaysRecoverable kind!"); - // Assume that -fsanitize-undefined-trap-on-error overrides - // -fsanitize-recover= options, as we can only print meaningful error - // message and recover if we have a runtime support. - return EmitTrapCheck(JointCond); - } - llvm::BasicBlock *Cont = createBasicBlock("cont"); llvm::BasicBlock *Handlers = createBasicBlock("handler." + CheckName); llvm::Instruction *Branch = Builder.CreateCondBr(JointCond, Cont, Handlers); -- cgit v1.2.3