From: Richard Smith Date: Thu, 1 Nov 2012 22:15:34 +0000 (+0000) Subject: Split emission of -ftrapv checks and -fcatch-undefined-behavior checks into X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=de67068fc1726f7c9c4ae89d3f3f47b2da512d48;p=platform%2Fupstream%2Fllvm.git Split emission of -ftrapv checks and -fcatch-undefined-behavior checks into separate functions, since they share essentially no code. llvm-svn: 167259 --- diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index d59a72d..e52a9ab 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2017,29 +2017,6 @@ void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName, bool Recoverable) { llvm::BasicBlock *Cont = createBasicBlock("cont"); - // If -fcatch-undefined-behavior is not enabled, just emit a trap. This - // happens when using -ftrapv. - // FIXME: Should -ftrapv require the ubsan runtime library? - if (!CatchUndefined) { - // 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::Value *F = CGM.getIntrinsic(llvm::Intrinsic::trap); - llvm::CallInst *TrapCall = Builder.CreateCall(F); - TrapCall->setDoesNotReturn(); - TrapCall->setDoesNotThrow(); - Builder.CreateUnreachable(); - } else { - Builder.CreateCondBr(Checked, Cont, TrapBB); - } - - EmitBlock(Cont); - return; - } - llvm::BasicBlock *Handler = createBasicBlock("handler." + CheckName); Builder.CreateCondBr(Checked, Cont, Handler); EmitBlock(Handler); @@ -2089,6 +2066,27 @@ void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName, EmitBlock(Cont); } +void CodeGenFunction::EmitTrapvCheck(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) { + TrapBB = createBasicBlock("trap"); + Builder.CreateCondBr(Checked, Cont, TrapBB); + EmitBlock(TrapBB); + llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::trap); + llvm::CallInst *TrapCall = Builder.CreateCall(F); + TrapCall->setDoesNotReturn(); + TrapCall->setDoesNotThrow(); + Builder.CreateUnreachable(); + } else { + Builder.CreateCondBr(Checked, Cont, TrapBB); + } + + EmitBlock(Cont); +} + /// isSimpleArrayDecayOperand - If the specified expr is a simple decay from an /// array to pointer, return the array subexpression. static const Expr *isSimpleArrayDecayOperand(const Expr *E) { diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 2354f31..31ec7ea 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2021,6 +2021,12 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { const std::string *handlerName = &CGF.getContext().getLangOpts().OverflowHandler; if (handlerName->empty()) { + // If -fcatch-undefined-behavior is enabled, emit a call to its + // runtime. Otherwise, this is a -ftrapv check, so just emit a trap. + if (CGF.CatchUndefined) + EmitBinOpCheck(Builder.CreateNot(overflow), Ops); + else + CGF.EmitTrapvCheck(Builder.CreateNot(overflow)); EmitBinOpCheck(Builder.CreateNot(overflow), Ops); return result; } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index c3f6c8e..1e9fd00 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2574,13 +2574,18 @@ public: /// passing to a runtime sanitizer handler. llvm::Constant *EmitCheckSourceLocation(SourceLocation Loc); - /// \brief Create a basic block that will call the trap intrinsic, and emit a - /// conditional branch to it. + /// \brief Create a basic block that will call a handler function in a + /// sanitizer runtime with the provided arguments, and create a conditional + /// branch to it. void EmitCheck(llvm::Value *Checked, StringRef CheckName, llvm::ArrayRef StaticArgs, llvm::ArrayRef DynamicArgs, bool Recoverable = false); + /// \brief Create a basic block that will call the trap intrinsic, and emit a + /// conditional branch to it, for the -ftrapv checks. + void EmitTrapvCheck(llvm::Value *Checked); + /// EmitCallArg - Emit a single call argument. void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);