Note that this is a 64-bit problem.  i386 works fine.  Code for reproducing is
included, as well as all system information.


correct output of program on 32-bit:

forwarding for selector display from 134536384 to 134536136
worked, self == receiver
foo is 1234567890, and should be 1234567890


incorrect output of program on 64-bit:

forwarding for selector display from 6330720 to 6330224
broken, self != receiver
foo is 6330224, and should be 1234567890


test program:

// Objective-C x86_64 bug:  self is wrong on forward;
// broken on gcc-4.1.2, 4.3.0, and 4.3.1

#include <stdio.h>
#include <stdlib.h>
#include <objc/Object.h>
#include <objc/objc-api.h>

id forwarder, receiver;

@interface Forwarder:Object
{
    id receiver;
}

-initWithReceiver:theReceiver;

@end

@interface Receiver:Object
{
    int foo;
}

-display;
-initWithFoo:(int)theFoo;

@end

@implementation Receiver

-initWithFoo:(int)theFoo
{
    foo = theFoo;
    return self;
}

-display
{
    if (self == receiver) {
        printf("worked, self == receiver\n");
    } else {
        printf("broken, self != receiver\n");
    }
    printf("foo is %d, and should be %d\n", foo, 1234567890);
    return self;
}

@end

@implementation Forwarder

-initWithReceiver:theReceiver
{
    [super init];
    receiver = theReceiver;
    return self;
}

-(retval_t) forward:(SEL)theSel:(arglist_t)theArgFrame
{
    if (receiver) {

        printf("forwarding for selector %s from %ld to %ld\n",
            sel_get_name(theSel), self, receiver);

        //return objc_msg_sendv(itsNextLink, theSel, theArgFrame);
        return [receiver performv:theSel:theArgFrame];

    } else {
        return [self doesNotRecognize:theSel];
    }
}

@end

int main()
{
    receiver = [[Receiver alloc] initWithFoo:1234567890];
    forwarder = [[Forwarder alloc] initWithReceiver:receiver];

    [forwarder display];

    exit(EXIT_SUCCESS);
    return 0;
}


I compiled gcc from the 4.3.1 tarball on ftp.gnu.org in order to avoid any
distro patches.  Here's the output of gcc -v:

Using built-in specs.
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-4.3.1/configure --prefix=/usr/local
--host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec
--enable-nls -
-without-included-gettext --with-system-zlib --disable-checking
--disable-werror --enable-secureplt --disable-multilib --enable-libmudflap
--disabl
e-libssp --disable-libgcj --enable-languages=c,objc --enable-shared
--enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu             
Thread model: posix
gcc version 4.3.1 (GCC)


-- 
           Summary: message forwarding broken on x86_64: self is not
                    receiver
           Product: gcc
           Version: 4.3.1
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: objc
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: hydrologiccycle at gmail dot com
 GCC build triplet: x86_64-pc-linux-gnu
  GCC host triplet: x86_64-pc-linux-gnu
GCC target triplet: x86_64-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36610

Reply via email to