diff options
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 20 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 10 |
3 files changed, 27 insertions, 7 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index afb7a798ef..a25e369766 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1526,6 +1526,16 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { if (Ops.LHS->getType() != RHS->getType()) RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom"); + if (CGF.CatchUndefined + && isa<llvm::IntegerType>(Ops.LHS->getType())) { + unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth(); + llvm::BasicBlock *Cont = CGF.createBasicBlock("cont"); + CGF.Builder.CreateCondBr(Builder.CreateICmpULT(RHS, + llvm::ConstantInt::get(RHS->getType(), Width)), + Cont, CGF.getAbortBB()); + CGF.EmitBlock(Cont); + } + return Builder.CreateShl(Ops.LHS, RHS, "shl"); } @@ -1536,6 +1546,16 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) { if (Ops.LHS->getType() != RHS->getType()) RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom"); + if (CGF.CatchUndefined + && isa<llvm::IntegerType>(Ops.LHS->getType())) { + unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth(); + llvm::BasicBlock *Cont = CGF.createBasicBlock("cont"); + CGF.Builder.CreateCondBr(Builder.CreateICmpULT(RHS, + llvm::ConstantInt::get(RHS->getType(), Width)), + Cont, CGF.getAbortBB()); + CGF.EmitBlock(Cont); + } + if (Ops.Ty->isUnsignedIntegerType()) return Builder.CreateLShr(Ops.LHS, RHS, "shr"); return Builder.CreateAShr(Ops.LHS, RHS, "shr"); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index db604f63b1..c3bae0768c 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -31,8 +31,8 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) DebugInfo(0), IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0), CXXThisDecl(0), CXXVTTDecl(0), - ConditionalBranchLevel(0), TerminateHandler(0), - UniqueAggrDestructorCount(0), AbortBB(0) { + ConditionalBranchLevel(0), TerminateHandler(0), AbortBB(0), + UniqueAggrDestructorCount(0) { LLVMIntTy = ConvertType(getContext().IntTy); LLVMPointerWidth = Target.getPointerWidth(0); Exceptions = getContext().getLangOptions().Exceptions; diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 8820e6ec8b..a44e53b4e3 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -425,6 +425,7 @@ private: unsigned getByRefValueLLVMField(const ValueDecl *VD) const; llvm::BasicBlock *TerminateHandler; + llvm::BasicBlock *AbortBB; int UniqueAggrDestructorCount; public: @@ -1194,6 +1195,10 @@ public: /// try to simplify the codegen of the conditional based on the branch. void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock); + + /// getAbortBB - Create a basic block that will call abort. We'll generate + /// a branch around the created basic block as necessary. + llvm::BasicBlock* getAbortBB(); private: void EmitReturnOfRValue(RValue RV, QualType Ty); @@ -1267,11 +1272,6 @@ private: ArgType)); } } - - llvm::BasicBlock *AbortBB; - /// getAbortBB - Create a basic block that will call abort. We'll generate - /// a branch around the created basic block as necessary. - llvm::BasicBlock* getAbortBB(); }; |