]> granicus.if.org Git - clang/commitdiff
finish off codegen support for sub of pointer to functions,
authorChris Lattner <sabre@nondot.org>
Wed, 11 Feb 2009 07:21:43 +0000 (07:21 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 11 Feb 2009 07:21:43 +0000 (07:21 +0000)
finishing off rdar://6520707

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

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

index b9dcc078d4dbea0a2a4bd2c2c60125a335a49389..a94eef115117a689ea3a03c4d99e257f7694cc9a 100644 (file)
@@ -965,8 +965,9 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
   
     uint64_t ElementSize;
 
-    // Handle GCC extension for pointer arithmetic on void* types.
-    if (LHSElementType->isVoidType()) {
+    // Handle GCC extension for pointer arithmetic on void* and function pointer
+    // types.
+    if (LHSElementType->isVoidType() || LHSElementType->isFunctionType()) {
       ElementSize = 1;
     } else {
       ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8;
@@ -977,6 +978,10 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
     RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
     Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
     
+    // Optimize out the shift for element size of 1.
+    if (ElementSize == 1)
+      return BytesBetween;
+    
     // 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. See PR2247.
index 07a9158744bc7c6c37c96446bfdf606c8afed896..81742673c2aafe26c9ea7ba1cf70a7af0c313f35 100644 (file)
@@ -52,3 +52,10 @@ void eMaisUma() {
        if (*t)
                return;
 }
+
+// rdar://6520707
+void f0(void (*fp)(void), void (*fp2)(void)) {
+  int x = fp - fp2;
+}
+
+