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
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 1ed45a3..85746ae 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2300,15 +2300,24 @@
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 @@
}
#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);