jmgao updated this revision to Diff 32736.
jmgao added a comment.
Uploading diff with arcanist.
http://reviews.llvm.org/D12181
Files:
include/clang/Driver/Options.td
include/clang/Frontend/CodeGenOptions.h
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CodeGenFunction.h
lib/Frontend/CompilerInvocation.cpp
test/CodeGen/sanitize-trap-function.c
Index: test/CodeGen/sanitize-trap-function.c
===================================================================
--- /dev/null
+++ test/CodeGen/sanitize-trap-function.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=integer-divide-by-zero -fsanitize-trap=integer-divide-by-zero | FileCheck %s -check-prefix=NONE -check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=integer-divide-by-zero -fsanitize-trap=integer-divide-by-zero -ftrap-function=foo | FileCheck %s -check-prefix=TRAP -check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=integer-divide-by-zero -fsanitize-trap=integer-divide-by-zero -fsanitize-trap-function=bar | FileCheck %s -check-prefix=SANITIZE -check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=integer-divide-by-zero -fsanitize-trap=integer-divide-by-zero -ftrap-function=foo -fsanitize-trap-function=bar | FileCheck %s -check-prefix=SANITIZE -check-prefix=CHECK
+
+int f(int x, int y) {
+ // CHECK: call void @llvm.trap() #[[N:[0-9]+]],
+ // CHECK-NEXT: unreachable
+
+ // NONE-NOT: trap-func-name
+ // TRAP: attributes #[[N]] {{.+}} "trap-func-name"="foo"
+ // SANITIZE: attributes #[[N]] {{.+}} "trap-func-name"="bar"
+ return x / y;
+}
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -504,6 +504,7 @@
<< Args.getLastArg(OPT_mthread_model)->getAsString(Args)
<< Opts.ThreadModel;
Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ);
+ Opts.SanitizeTrapFuncName = Args.getLastArgValue(OPT_fsanitize_trap_function_EQ);
Opts.UseInitArray = Args.hasArg(OPT_fuse_init_array);
Opts.FunctionSections = Args.hasFlag(OPT_ffunction_sections,
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -2886,11 +2886,16 @@
/// \brief Create a basic block that will call the trap intrinsic, and emit a
/// conditional branch to it, for the -ftrapv checks.
+ void EmitSanitizeTrapCheck(llvm::Value *Checked);
void EmitTrapCheck(llvm::Value *Checked);
+ void EmitTrapCheck(llvm::Value *Checked, const std::string &TrapFuncName);
/// \brief Emit a call to trap or debugtrap and attach function attribute
/// "trap-func-name" if specified.
+ llvm::CallInst *EmitSanitizeTrapCall(llvm::Intrinsic::ID IntrID);
llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID);
+ llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID,
+ const std::string &TrapFuncName);
/// \brief Create a check for a function parameter that may potentially be
/// declared as non-null.
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -2383,7 +2383,7 @@
: SanitizerKind::UnsignedIntegerOverflow;
EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
} else
- CGF.EmitTrapCheck(Builder.CreateNot(overflow));
+ CGF.EmitSanitizeTrapCheck(Builder.CreateNot(overflow));
return result;
}
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -2301,7 +2301,7 @@
}
if (TrapCond)
- EmitTrapCheck(TrapCond);
+ EmitSanitizeTrapCheck(TrapCond);
if (!FatalCond && !RecoverableCond)
return;
@@ -2381,16 +2381,27 @@
EmitBlock(Cont);
}
+void CodeGenFunction::EmitSanitizeTrapCheck(llvm::Value *Checked) {
+ if (!CGM.getCodeGenOpts().SanitizeTrapFuncName.empty()) {
+ return EmitTrapCheck(Checked, CGM.getCodeGenOpts().SanitizeTrapFuncName);
+ }
+ return EmitTrapCheck(Checked);
+}
+
void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) {
+ return EmitTrapCheck(Checked, CGM.getCodeGenOpts().TrapFuncName);
+}
+
+void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked, const std::string &TrapFuncName) {
llvm::BasicBlock *Cont = createBasicBlock("cont");
// If we're optimizing, collapse all calls to trap down to just one per
// function to save on code size.
if (!CGM.getCodeGenOpts().OptimizationLevel || !TrapBB) {
TrapBB = createBasicBlock("trap");
Builder.CreateCondBr(Checked, Cont, TrapBB);
EmitBlock(TrapBB);
- llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
+ llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap, TrapFuncName);
TrapCall->setDoesNotReturn();
TrapCall->setDoesNotThrow();
Builder.CreateUnreachable();
@@ -2401,13 +2412,24 @@
EmitBlock(Cont);
}
+llvm::CallInst *CodeGenFunction::EmitSanitizeTrapCall(llvm::Intrinsic::ID IntrID) {
+ if (!CGM.getCodeGenOpts().SanitizeTrapFuncName.empty()) {
+ return EmitTrapCall(IntrID, CGM.getCodeGenOpts().SanitizeTrapFuncName);
+ }
+ return EmitTrapCall(IntrID);
+}
+
llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
+ return EmitTrapCall(IntrID, CGM.getCodeGenOpts().TrapFuncName);
+}
+
+llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID, const std::string &TrapFuncName) {
llvm::CallInst *TrapCall = Builder.CreateCall(CGM.getIntrinsic(IntrID));
- if (!CGM.getCodeGenOpts().TrapFuncName.empty())
+ if (!TrapFuncName.empty())
TrapCall->addAttribute(llvm::AttributeSet::FunctionIndex,
"trap-func-name",
- CGM.getCodeGenOpts().TrapFuncName);
+ TrapFuncName);
return TrapCall;
}
Index: include/clang/Frontend/CodeGenOptions.h
===================================================================
--- include/clang/Frontend/CodeGenOptions.h
+++ include/clang/Frontend/CodeGenOptions.h
@@ -201,6 +201,10 @@
/// Set of sanitizer checks that trap rather than diagnose.
SanitizerSet SanitizeTrap;
+ /// If not an empty string, trap intrinsics are lowered to calls to this
+ /// function instead of to trap instructions.
+ std::string SanitizeTrapFuncName;
+
public:
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -605,6 +605,9 @@
def fno_sanitize_trap_EQ : CommaJoined<["-"], "fno-sanitize-trap=">, Group<f_clang_Group>,
Flags<[CoreOption]>,
HelpText<"Disable trapping for specified sanitizers">;
+def fsanitize_trap_function_EQ : Joined<["-"], "fsanitize-trap-function=">, Group<f_clang_Group>,
+ Flags<[CC1Option, CoreOption]>,
+ HelpText<"Issue call to specified function rather than a trap instruction">;
def fsanitize_undefined_trap_on_error : Flag<["-"], "fsanitize-undefined-trap-on-error">,
Group<f_clang_Group>;
def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-trap-on-error">,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits