Index: include/clang/Basic/Sanitizers.def =================================================================== --- include/clang/Basic/Sanitizers.def +++ include/clang/Basic/Sanitizers.def @@ -37,6 +37,8 @@ #define SANITIZER_GROUP(NAME, ID, ALIAS) #endif +// Debug mode for sanitizers +SANITIZER("debug-mode", DebugMode) // AddressSanitizer SANITIZER("address", Address) Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -27,6 +27,7 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/InlineAsm.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" @@ -2535,9 +2536,25 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) { 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) { + // Collapsing all calls to trap down to one per function makes debugging + // these issues much more difficult. Eliminating this optimization + // for debugging purposes. + // RE: Bug: 25682 + if(SanOpts.has(SanitizerKind::DebugMode)) { + llvm::InlineAsm *EmptyAsm = llvm::InlineAsm::get(llvm::FunctionType::get(CGM.VoidTy, false), + StringRef(""), StringRef(""), true); + TrapBB = createBasicBlock("trap"); + Builder.CreateCondBr(Checked, Cont, TrapBB); + EmitBlock(TrapBB); + llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); + TrapCall->setDoesNotReturn(); + TrapCall->setDoesNotThrow(); + Builder.CreateUnreachable(); + //this stops the trap calls from being merged at the end of the function + Builder.CreateCall(EmptyAsm, {}); + } else if(!CGM.getCodeGenOpts().OptimizationLevel || !TrapBB) { + // If we're optimizing, collapse all calls to trap down to just one per + // function to save on code size. TrapBB = createBasicBlock("trap"); Builder.CreateCondBr(Checked, Cont, TrapBB); EmitBlock(TrapBB); @@ -2548,7 +2565,7 @@ } else { Builder.CreateCondBr(Checked, Cont, TrapBB); } - + EmitBlock(Cont); } Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -657,7 +657,8 @@ // platform dependent. using namespace SanitizerKind; SanitizerMask Res = (Undefined & ~Vptr & ~Function) | (CFI & ~CFIICall) | - CFICastStrict | UnsignedIntegerOverflow | LocalBounds; + CFICastStrict | UnsignedIntegerOverflow | LocalBounds | + DebugMode; if (getTriple().getArch() == llvm::Triple::x86 || getTriple().getArch() == llvm::Triple::x86_64) Res |= CFIICall;