jmgao updated this revision to Diff 32756.
jmgao added a comment.

Improve comment


http://reviews.llvm.org/D12181

Files:
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/CGExpr.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
@@ -681,6 +681,7 @@
   parseSanitizerKinds("-fsanitize-trap=",
                       Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
                       Opts.SanitizeTrap);
+  Opts.SanitizeTrapFuncName = Args.getLastArgValue(OPT_fsanitize_trap_function_EQ);
 
   Opts.CudaGpuBinaryFileNames =
       Args.getAllArgValues(OPT_fcuda_include_gpubinary);
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -2885,13 +2885,26 @@
                  ArrayRef<llvm::Value *> DynamicArgs);
 
   /// \brief Create a basic block that will call the trap intrinsic, and emit a
+  /// conditional branch to it, for the -fsanitize checks.
+  void EmitSanitizeTrapCheck(llvm::Value *Checked);
+
+  /// \brief Create a basic block that will call the trap intrinsic, and emit a
   /// conditional branch to it, for the -ftrapv checks.
   void EmitTrapCheck(llvm::Value *Checked);
 
+  /// \brief Create a basic block that will call the specified trap function,
+  /// and emit a conditional branch to it.
+  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.
+  /// "trap-func-name" if -ftrap-function is specified.
   llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID);
 
+  /// \brief Emit a call to trap or debugtrap and attach function attribute
+  /// "trap-func-name" if nonempty.
+  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.
   void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc,
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();
@@ -2402,12 +2413,16 @@
 }
 
 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, trapping sanitizers will issue calls to this
+  /// function instead of 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<"Make trapping sanitizers issue a 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">,
Index: docs/UsersManual.rst
===================================================================
--- docs/UsersManual.rst
+++ docs/UsersManual.rst
@@ -1115,6 +1115,14 @@
 
    This flag is enabled by default for sanitizers in the ``cfi`` group.
 
+**-fsanitize-trap-function=[name]**
+
+   Instruct code generator to emit a function call to the specified
+   function name instead of a trap instruction for checks configured to trap.
+
+   If this flag is not specified, clang will use the value of ``-ftrap-function``
+   if specified.
+
 **-f[no-]sanitize-coverage=[type,features,...]**
 
    Enable simple code coverage in addition to certain sanitizers.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to