From: Mike Stump Date: Mon, 14 Dec 2009 21:58:14 +0000 (+0000) Subject: Add support for detecting undefined shift behavior. WIP. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=be07f60131bc6f8d6696f4644df1ef667a1730d5;p=clang Add support for detecting undefined shift behavior. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91341 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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(Ops.LHS->getType())) { + unsigned Width = cast(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(Ops.LHS->getType())) { + unsigned Width = cast(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(); };