[LLVMbugs] [Bug 9125] New: Different behaviour amongst Clang versions when sending a message to an assignment expression

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Wed Feb 2 09:27:29 PST 2011


http://llvm.org/bugs/show_bug.cgi?id=9125

           Summary: Different behaviour amongst Clang versions when
                    sending a message to an assignment expression
           Product: clang
           Version: unspecified
          Platform: PC
        OS/Version: MacOS X
            Status: NEW
          Severity: normal
          Priority: P
         Component: Frontend
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: macbavarious at gmail.com
                CC: llvmbugs at cs.uiuc.edu


Mike Ash’s proposed the following [1]:

‘One line property initialization with no autorelease: [self.property =
[[SomeClass alloc] init] release];’

This can be reduced to

[obj.property = rvalue method];

Clang 1.5 sends ‘method’ to obj.property whereas Clang 1.6 and GCC 4.2.1 send
‘method’ to rvalue. In the case of copy properties and assignment of a mutable
object to a property of immutable type, Mike Ash’s proposal leaks the mutable
object and releases the backing instance variable on Clang 1.5. In general, it
doesn’t work on Clang 1.5 unless the getter method returns the same object as
the argument that was passed to the setter method.

Reading the C standard, I’m tempted to think Clang 1.5 is correct:

‘6.5.16.3 (…) An assignment expression has the value of the left operand after
the assignment (…)’

On the other hand, sending the message to rvalue saves one objc_msgSend() call
for obj.property’s getter method. In fact, as David Smith’s pointed out, for
multiple assignments such as

obj.property = obj.property2 = obj.property3 = rvalue;

Clang 1.6 and GCC 4.2.1 send three ObjC messages (three setters) whereas Clang
1.5 sends five message (three setters, two getters).

The following program can be used to test this behaviour:

#import <Foundation/Foundation.h>

@interface Test : NSObject { id prop; }
@property (readwrite, nonatomic, retain) id prop;
@end

@implementation Test
@synthesize prop;

- (id)prop {
    NSLog(@"getter");
    return prop;
}
@end

int main()
{
    Test *t = [[Test alloc] init];
    NSLog(@"message to single assignment expression");
    [t.prop = t prop];
    NSLog(@"multiple assignments:");
    t.prop = t.prop = t.prop = t;
    return 0;
}

When built with Clang 1.5, the output is

message to single assignment expression
getter
getter
multiple assignments:
getter
getter

When built with Clang 1.6 or GCC 4.2.1, the output is

message to single assignment expression
getter
multiple assignments:

Since there’s no Objective-C specification, which behaviour is
expected/correct, or should this not be allowed at all?

This has been posted to objc-language at lists.apple.com [2].

[1] http://twitter.com/mikeash/status/32651143389642752
[2] http://lists.apple.com/archives/Objc-language/2011/Feb/msg00000.html

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list