oskarwirga updated this revision to Diff 521767.
oskarwirga added a comment.

Add full context


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148654/new/

https://reviews.llvm.org/D148654

Files:
  clang/lib/CodeGen/CGExpr.cpp
  clang/test/CodeGen/bounds-checking.c
  llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp

Index: llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
+++ llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp
@@ -39,6 +39,10 @@
 static cl::opt<bool> SingleTrapBB("bounds-checking-single-trap",
                                   cl::desc("Use one trap block per function"));
 
+static cl::opt<bool>
+    DebugTrapBB("bounds-checking-debug-trap",
+                cl::desc("Use one trap block per check despite optimizations"));
+
 STATISTIC(ChecksAdded, "Bounds checks added");
 STATISTIC(ChecksSkipped, "Bounds checks skipped");
 STATISTIC(ChecksUnable, "Bounds checks unable to add");
@@ -182,24 +186,39 @@
   // will create a fresh block every time it is called.
   BasicBlock *TrapBB = nullptr;
   auto GetTrapBB = [&TrapBB](BuilderTy &IRB) {
-    if (TrapBB && SingleTrapBB)
-      return TrapBB;
-
-    Function *Fn = IRB.GetInsertBlock()->getParent();
-    // FIXME: This debug location doesn't make a lot of sense in the
-    // `SingleTrapBB` case.
-    auto DebugLoc = IRB.getCurrentDebugLocation();
-    IRBuilder<>::InsertPointGuard Guard(IRB);
-    TrapBB = BasicBlock::Create(Fn->getContext(), "trap", Fn);
-    IRB.SetInsertPoint(TrapBB);
-
-    auto *F = Intrinsic::getDeclaration(Fn->getParent(), Intrinsic::trap);
-    CallInst *TrapCall = IRB.CreateCall(F, {});
-    TrapCall->setDoesNotReturn();
-    TrapCall->setDoesNotThrow();
-    TrapCall->setDebugLoc(DebugLoc);
-    IRB.CreateUnreachable();
-
+    if (DebugTrapBB) {
+      Function *Fn = IRB.GetInsertBlock()->getParent();
+      auto DebugLoc = IRB.getCurrentDebugLocation();
+      IRBuilder<>::InsertPointGuard Guard(IRB);
+      TrapBB = BasicBlock::Create(Fn->getContext(), "trap", Fn);
+      IRB.SetInsertPoint(TrapBB);
+      auto *F =
+          Intrinsic::getDeclaration(Fn->getParent(), Intrinsic::ubsantrap);
+      CallInst *TrapCall =
+          IRB.CreateCall(F, ConstantInt::get(IRB.getInt8Ty(), Fn->size()));
+      TrapCall->setDoesNotReturn();
+      TrapCall->setDoesNotThrow();
+      TrapCall->setDebugLoc(DebugLoc);
+      IRB.CreateUnreachable();
+    } else {
+      if (TrapBB && SingleTrapBB)
+        return TrapBB;
+
+      Function *Fn = IRB.GetInsertBlock()->getParent();
+      // FIXME: This debug location doesn't make a lot of sense in the
+      // `SingleTrapBB` case.
+      auto DebugLoc = IRB.getCurrentDebugLocation();
+      IRBuilder<>::InsertPointGuard Guard(IRB);
+      TrapBB = BasicBlock::Create(Fn->getContext(), "trap", Fn);
+      IRB.SetInsertPoint(TrapBB);
+
+      auto *F = Intrinsic::getDeclaration(Fn->getParent(), Intrinsic::trap);
+      CallInst *TrapCall = IRB.CreateCall(F, {});
+      TrapCall->setDoesNotReturn();
+      TrapCall->setDoesNotThrow();
+      TrapCall->setDebugLoc(DebugLoc);
+      IRB.CreateUnreachable();
+    }
     return TrapBB;
   };
 
Index: clang/test/CodeGen/bounds-checking.c
===================================================================
--- clang/test/CodeGen/bounds-checking.c
+++ clang/test/CodeGen/bounds-checking.c
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -fsanitize=local-bounds -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
 // RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=local-bounds -fsanitize-trap=local-bounds -O3 -mllvm -bounds-checking-debug-trap -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s --check-prefixes=NOOPTLOCAL
+// RUN: %clang_cc1 -fsanitize=array-bounds -fsanitize-trap=array-bounds -O3 -mllvm -sanitizer-de-opt-traps -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s --check-prefixes=NOOPTARRAY
 //
 // REQUIRES: x86-registered-target
 
@@ -66,3 +68,16 @@
   // CHECK-NOT: @llvm.ubsantrap
   return u->c[i];
 }
+
+char B[10];
+char B2[10];
+// CHECK-LABEL: @f8
+void f8(int i, int k) {
+  // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  B[i] = '\0';
+
+  // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  B2[k] = '\0';
+}
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -48,6 +48,11 @@
 using namespace clang;
 using namespace CodeGen;
 
+// Experiment to make sanitizers easier to debug
+static llvm::cl::opt<bool> ClSanitizeDebugDeoptimization(
+    "sanitizer-de-opt-traps", llvm::cl::Optional,
+    llvm::cl::desc("Deoptimize traps for sanitizers"), llvm::cl::init(false));
+
 //===--------------------------------------------------------------------===//
 //                        Miscellaneous Helper Methods
 //===--------------------------------------------------------------------===//
@@ -3542,23 +3547,16 @@
 
 void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
                                     SanitizerHandler CheckHandlerID) {
-  llvm::BasicBlock *Cont = createBasicBlock("cont");
-
-  // If we're optimizing, collapse all calls to trap down to just one per
-  // check-type per function to save on code size.
-  if (TrapBBs.size() <= CheckHandlerID)
-    TrapBBs.resize(CheckHandlerID + 1);
-  llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
+  if (ClSanitizeDebugDeoptimization) {
+    llvm::BasicBlock *Cont = createBasicBlock("cont");
 
-  if (!CGM.getCodeGenOpts().OptimizationLevel || !TrapBB ||
-      (CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>())) {
-    TrapBB = createBasicBlock("trap");
+    llvm::BasicBlock *TrapBB = createBasicBlock("trap");
     Builder.CreateCondBr(Checked, Cont, TrapBB);
     EmitBlock(TrapBB);
 
-    llvm::CallInst *TrapCall =
-        Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-                           llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
+    llvm::CallInst *TrapCall = Builder.CreateCall(
+        CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
+        llvm::ConstantInt::get(CGM.Int8Ty, TrapBB->getParent()->size()));
 
     if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
       auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
@@ -3568,16 +3566,46 @@
     TrapCall->setDoesNotReturn();
     TrapCall->setDoesNotThrow();
     Builder.CreateUnreachable();
+
+    EmitBlock(Cont);
   } else {
-    auto Call = TrapBB->begin();
-    assert(isa<llvm::CallInst>(Call) && "Expected call in trap BB");
+    llvm::BasicBlock *Cont = createBasicBlock("cont");
+
+    // If we're optimizing, collapse all calls to trap down to just one per
+    // check-type per function to save on code size.
+    if (TrapBBs.size() <= CheckHandlerID)
+      TrapBBs.resize(CheckHandlerID + 1);
+    llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
+
+    if (!CGM.getCodeGenOpts().OptimizationLevel || !TrapBB ||
+        (CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>())) {
+      TrapBB = createBasicBlock("trap");
+      Builder.CreateCondBr(Checked, Cont, TrapBB);
+      EmitBlock(TrapBB);
+
+      llvm::CallInst *TrapCall = Builder.CreateCall(
+          CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
+          llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
+
+      if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
+        auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
+                                      CGM.getCodeGenOpts().TrapFuncName);
+        TrapCall->addFnAttr(A);
+      }
+      TrapCall->setDoesNotReturn();
+      TrapCall->setDoesNotThrow();
+      Builder.CreateUnreachable();
+    } else {
+      auto Call = TrapBB->begin();
+      assert(isa<llvm::CallInst>(Call) && "Expected call in trap BB");
 
-    Call->applyMergedLocation(Call->getDebugLoc(),
-                              Builder.getCurrentDebugLocation());
-    Builder.CreateCondBr(Checked, Cont, TrapBB);
-  }
+      Call->applyMergedLocation(Call->getDebugLoc(),
+                                Builder.getCurrentDebugLocation());
+      Builder.CreateCondBr(Checked, Cont, TrapBB);
+    }
 
-  EmitBlock(Cont);
+    EmitBlock(Cont);
+  }
 }
 
 llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to