]> granicus.if.org Git - clang/commitdiff
Fix PR1921 by promoting negative indices to intptrty.
authorChris Lattner <sabre@nondot.org>
Thu, 31 Jan 2008 04:12:50 +0000 (04:12 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 31 Jan 2008 04:12:50 +0000 (04:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46599 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGExprScalar.cpp
test/CodeGen/exprs.c

index e7f58bb4689a27400bd7697a9411c03bac49c709..820234033b0bb4aa03b94fb81bbe595a16588752 100644 (file)
@@ -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) {
index 9115369173322925ddcc6d25f6aafdaf2d54f271..16b63f8883bb6681761c72f9135c23662afeacb5 100644 (file)
@@ -17,3 +17,9 @@ void *test(int *i) {
 _Bool test2b; 
 int test2() {if (test2b);}
 
+// PR1921
+int test3() {
+  const unsigned char *bp;
+  bp -= (short)1;
+}
+