summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-01-31 04:12:50 +0000
committerChris Lattner <sabre@nondot.org>2008-01-31 04:12:50 +0000
commita94035bbb86ff5b239df7dcf6e7abe45852ea3d6 (patch)
tree4874546d22a4b1a5564f16eadbadad509f2ae6cd /clang
parent6332dbec69017aa9505468102775f6e7399dcb8c (diff)
downloadbcm5719-llvm-a94035bbb86ff5b239df7dcf6e7abe45852ea3d6.tar.gz
bcm5719-llvm-a94035bbb86ff5b239df7dcf6e7abe45852ea3d6.zip
Fix PR1921 by promoting negative indices to intptrty.
llvm-svn: 46599
Diffstat (limited to 'clang')
-rw-r--r--clang/CodeGen/CGExprScalar.cpp16
-rw-r--r--clang/test/CodeGen/exprs.c6
2 files changed, 20 insertions, 2 deletions
diff --git a/clang/CodeGen/CGExprScalar.cpp b/clang/CodeGen/CGExprScalar.cpp
index e7f58bb4689..820234033b0 100644
--- a/clang/CodeGen/CGExprScalar.cpp
+++ b/clang/CodeGen/CGExprScalar.cpp
@@ -767,8 +767,20 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
assert(!isa<llvm::PointerType>(Ops.RHS->getType()) &&
"ptr-ptr shouldn't get here");
// FIXME: The pointer could point to a VLA.
- Value *NegatedRHS = Builder.CreateNeg(Ops.RHS, "sub.ptr.neg");
- return Builder.CreateGEP(Ops.LHS, NegatedRHS, "sub.ptr");
+ Value *Idx = Builder.CreateNeg(Ops.RHS, "sub.ptr.neg");
+
+ unsigned Width = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
+ if (Width < CGF.LLVMPointerWidth) {
+ // Zero or sign extend the pointer value based on whether the index is
+ // signed or not.
+ const llvm::Type *IdxType = llvm::IntegerType::get(CGF.LLVMPointerWidth);
+ if (Ops.E->getRHS()->getType().getCanonicalType()->isSignedIntegerType())
+ Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
+ else
+ Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
+ }
+
+ return Builder.CreateGEP(Ops.LHS, Idx, "sub.ptr");
}
Value *ScalarExprEmitter::VisitBinSub(const BinaryOperator *E) {
diff --git a/clang/test/CodeGen/exprs.c b/clang/test/CodeGen/exprs.c
index 91153691733..16b63f8883b 100644
--- a/clang/test/CodeGen/exprs.c
+++ b/clang/test/CodeGen/exprs.c
@@ -17,3 +17,9 @@ void *test(int *i) {
_Bool test2b;
int test2() {if (test2b);}
+// PR1921
+int test3() {
+ const unsigned char *bp;
+ bp -= (short)1;
+}
+
OpenPOWER on IntegriCloud