From: Chris Lattner Date: Thu, 31 Jan 2008 04:12:50 +0000 (+0000) Subject: Fix PR1921 by promoting negative indices to intptrty. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6860f3cef7d5ed22cf7626e357c202124c43c899;p=clang Fix PR1921 by promoting negative indices to intptrty. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46599 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CodeGen/CGExprScalar.cpp b/CodeGen/CGExprScalar.cpp index e7f58bb468..820234033b 100644 --- a/CodeGen/CGExprScalar.cpp +++ b/CodeGen/CGExprScalar.cpp @@ -767,8 +767,20 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) { assert(!isa(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(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/test/CodeGen/exprs.c b/test/CodeGen/exprs.c index 9115369173..16b63f8883 100644 --- a/test/CodeGen/exprs.c +++ b/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; +} +