| /* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */ |
| /* { dg-do run } */ |
| /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ |
| |
| /* Test dot-syntax with more tricky assignments. */ |
| |
| #include <stdlib.h> |
| #include <objc/objc.h> |
| #include <objc/runtime.h> |
| |
| @interface MyRootClass |
| { |
| Class isa; |
| id a; |
| id b; |
| int p1; |
| float p2; |
| } |
| + (id) initialize; |
| + (id) alloc; |
| - (id) init; |
| |
| @property (assign) id object1; |
| @property (assign) id object2; |
| - (id) test; |
| - (id) myself; |
| - (id) nilObject; |
| |
| @property int p1; |
| @property float p2; |
| @end |
| |
| @implementation MyRootClass |
| + (id) initialize { return self; } |
| + (id) alloc { return class_createInstance (self, 0); } |
| - (id) init { return self; } |
| @synthesize object1 = a; |
| @synthesize object2 = b; |
| - (id) test |
| { |
| /* Test multiple assignments with 'self'. */ |
| self.object1 = self.object2 = self; |
| |
| if (self.object1 != self || self.object2 != self) |
| abort (); |
| |
| /* Test multiple assignments with a conditional and method calls. */ |
| self.object1 = self.object2 = (self ? [self myself] : [self nilObject]); |
| |
| if (self.object1 != self || self.object2 != self) |
| abort (); |
| |
| self.object1 = self.object2 = (self ? [self nilObject] : [self myself]); |
| |
| if (self.object1 != nil || self.object2 != nil) |
| abort (); |
| |
| return self.object1; |
| } |
| - (id) myself |
| { |
| return self; |
| } |
| - (id) nilObject |
| { |
| return nil; |
| } |
| |
| @synthesize p1; |
| @synthesize p2; |
| @end |
| |
| int main (void) |
| { |
| MyRootClass *object = [[MyRootClass alloc] init]; |
| MyRootClass *object1 = [[MyRootClass alloc] init]; |
| |
| [object test]; |
| |
| /* Now, test multiple assignments with different types. Use |
| int/float as they seem to happily crash the compiler in gimplify |
| if proper conversions are not being generated by the |
| frontend. ;-) */ |
| object.p1 = object.p2 = 12; |
| |
| if (object.p1 != 12 || object.p2 != 12) |
| abort (); |
| |
| object.p1 = object.p2 = 2.7; |
| |
| if (object.p1 != 2) |
| abort (); |
| |
| /* Just try a different loop, mixing in a few different standard C |
| constructs to cover a few other cases. */ |
| object.p1 = 10; |
| object1.p1 = 0; |
| while (object.p1) |
| { |
| object1.p1 += ((object.p2 = 4.56) ? 0 : object.p1); |
| object.p1--; |
| } |
| |
| if (object.p1 != 0 || object1.p1 != 0) |
| abort (); |
| |
| if ((object.p1 = 0)) |
| abort (); |
| |
| return 0; |
| } |
| |
| |