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 afb7a79..a25e369 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1526,6 +1526,16 @@
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 @@
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 db604f6..c3bae07 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -31,8 +31,8 @@
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 8820e6e..a44e53b 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -425,6 +425,7 @@
unsigned getByRefValueLLVMField(const ValueDecl *VD) const;
llvm::BasicBlock *TerminateHandler;
+ llvm::BasicBlock *AbortBB;
int UniqueAggrDestructorCount;
public:
@@ -1194,6 +1195,10 @@
/// 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 @@
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();
};