]> granicus.if.org Git - clang/commitdiff
Bug fix, CodeGen of (void*) - (void*) was broken.
authorDaniel Dunbar <daniel@zuster.org>
Tue, 5 Aug 2008 00:47:03 +0000 (00:47 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 5 Aug 2008 00:47:03 +0000 (00:47 +0000)
 - <rdar://problem/6122967>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54338 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprScalar.cpp
test/CodeGen/2008-08-04-void-pointer-arithmetic.c [new file with mode: 0644]

index e8adc59e9fd9a32e3b7ea30412fc55861757e2cf..1f5324d71d74ea2bf94f04b39751e9027a84e92a 100644 (file)
@@ -851,6 +851,8 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
       Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
   }
   
+  // The GNU void* - int case is automatically handled here because
+  // our LLVM type for void* is i8*.
   return Builder.CreateGEP(Ops.LHS, Idx, "sub.ptr");
 }
 
@@ -866,19 +868,26 @@ Value *ScalarExprEmitter::VisitBinSub(const BinaryOperator *E) {
   
   const QualType LHSType = E->getLHS()->getType();
   const QualType LHSElementType = LHSType->getAsPointerType()->getPointeeType();
-  uint64_t ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8;
+  uint64_t ElementSize;
+
+  // Handle GCC extension for pointer arithmetic on void* types.
+  if (LHSElementType->isVoidType()) {
+    ElementSize = 1;
+  } else {
+    ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8;
+  }
   
   const llvm::Type *ResultType = ConvertType(E->getType());
   LHS = Builder.CreatePtrToInt(LHS, ResultType, "sub.ptr.lhs.cast");
   RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
   Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
-  
+
   // HACK: LLVM doesn't have an divide instruction that 'knows' there is no
   // remainder.  As such, we handle common power-of-two cases here to generate
   // better code.
   if (llvm::isPowerOf2_64(ElementSize)) {
     Value *ShAmt =
-    llvm::ConstantInt::get(ResultType, llvm::Log2_64(ElementSize));
+      llvm::ConstantInt::get(ResultType, llvm::Log2_64(ElementSize));
     return Builder.CreateAShr(BytesBetween, ShAmt, "sub.ptr.shr");
   }
   
diff --git a/test/CodeGen/2008-08-04-void-pointer-arithmetic.c b/test/CodeGen/2008-08-04-void-pointer-arithmetic.c
new file mode 100644 (file)
index 0000000..fc54dca
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: clang --emit-llvm -o - %s
+// <rdar://problem/6122967>
+
+int f0(void *a, void *b) {
+  return a - b;
+}