In gcc/objc/: 2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>

In gcc/objc/:
2010-11-08  Nicola Pero  <nicola.pero@meta-innovation.com>

        * objc-act.c (objc_add_dynamic_declaration_for_property): Do not
        search for the @property declation only in the current context,
        but also in inherited properties.  Do not mark the original
        PROPERTY_DECL in the @interface or @protocol with
        PROPERTY_DYNAMIC.
        (check_methods): To check if a method is associated with a
        @dynamic property, search for the property in IMPL_PROPERTY_DECL.
        (check_accessible_methods): Same change.
        * objc-act.h: Updated comment.

In gcc/testsuite/:
2010-11-08  Nicola Pero  <nicola.pero@meta-innovation.com>

        * objc.dg/property/dynamic-4.m: New.
        * objc.dg/property/dynamic-5.m: New.
        * objc.dg/property/dynamic-6.m: New.    
        * obj-c++.dg/property/dynamic-4.mm: New.
        * obj-c++.dg/property/dynamic-5.mm: New.
        * obj-c++.dg/property/dynamic-6.mm: New.

2010-11-08  Nicola Pero  <nicola.pero@meta-innovation.com>

        * objc.dg/property/dotsyntax-13.m: New.
        * objc.dg/property/dotsyntax-14.m: New.
        * objc.dg/property/dotsyntax-15.m: New. 
        * objc.dg/property/synthesize-7.m: New.
        * obj-c++.dg/property/dotsyntax-13.mm: New.
        * obj-c++.dg/property/dotsyntax-14.mm: New.
        * obj-c++.dg/property/dotsyntax-15.mm: New.     
        * obj-c++.dg/property/synthesize-7.mm: New.

From-SVN: r166457
This commit is contained in:
Nicola Pero 2010-11-08 22:38:04 +00:00 committed by Nicola Pero
parent 4741888d03
commit d36dba0739
18 changed files with 902 additions and 25 deletions

View File

@ -1,3 +1,15 @@
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-act.c (objc_add_dynamic_declaration_for_property): Do not
search for the @property declation only in the current context,
but also in inherited properties. Do not mark the original
PROPERTY_DECL in the @interface or @protocol with
PROPERTY_DYNAMIC.
(check_methods): To check if a method is associated with a
@dynamic property, search for the property in IMPL_PROPERTY_DECL.
(check_accessible_methods): Same change.
* objc-act.h: Updated comment.
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-act.c (objc_add_synthesize_declaration_for_property):

View File

@ -8738,9 +8738,19 @@ check_methods (tree chain, tree implementation, int mtype)
{
/* If the method is associated with a dynamic property, then it
is Ok not to have the method implementation, as it will be
generated dynamically at runtime. */
tree property = METHOD_PROPERTY_CONTEXT (chain);
if (property != NULL_TREE && PROPERTY_DYNAMIC (property))
generated dynamically at runtime. To decide if the method is
associated with a @dynamic property, we search the list of
@synthesize and @dynamic for this implementation, and look
for any @dynamic property with the same setter or getter name
as this method. */
tree x;
for (x = IMPL_PROPERTY_DECL (implementation); x; x = TREE_CHAIN (x))
if (PROPERTY_DYNAMIC (x)
&& (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
|| PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
break;
if (x != NULL_TREE)
{
chain = TREE_CHAIN (chain); /* next method... */
continue;
@ -8751,6 +8761,7 @@ check_methods (tree chain, tree implementation, int mtype)
/* If the method is a property setter/getter, we'll still
allow it to be missing if it is implemented by
'interface' or any of its superclasses. */
tree property = METHOD_PROPERTY_CONTEXT (chain);
if (property)
{
/* Note that since this is a property getter/setter, it
@ -8864,13 +8875,21 @@ check_methods_accessible (tree chain, tree context, int mtype)
{
/* If the method is associated with a dynamic property, then it
is Ok not to have the method implementation, as it will be
generated dynamically at runtime. */
tree property = METHOD_PROPERTY_CONTEXT (chain);
if (property != NULL_TREE && PROPERTY_DYNAMIC (property))
generated dynamically at runtime. Search for any @dynamic
property with the same setter or getter name as this
method. TODO: Use a hashtable lookup. */
tree x;
for (x = IMPL_PROPERTY_DECL (base_context); x; x = TREE_CHAIN (x))
if (PROPERTY_DYNAMIC (x)
&& (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
|| PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
break;
if (x != NULL_TREE)
{
chain = TREE_CHAIN (chain); /* next method... */
continue;
}
}
context = base_context;
while (context)
@ -9910,11 +9929,9 @@ objc_add_dynamic_declaration_for_property (location_t location, tree interface,
return;
}
/* Check that the property is declared in the corresponding
interface. */
for (property = CLASS_PROPERTY_DECL (interface); property; property = TREE_CHAIN (property))
if (PROPERTY_NAME (property) == property_name)
break;
/* Check that the property is declared in the interface. It could
also be declared in a superclass or protocol. */
property = lookup_property (interface, property_name);
if (!property)
{
@ -9924,17 +9941,6 @@ objc_add_dynamic_declaration_for_property (location_t location, tree interface,
}
else
{
/* Mark the original PROPERTY_DECL as dynamic. The reason is
that the setter and getter methods in the interface have a
METHOD_PROPERTY_CONTEXT that points to the original
PROPERTY_DECL; when we check that these methods have been
implemented, we need to easily find that they are associated
with a dynamic property. TODO: Remove this hack; it will not
work with properties in a protocol that may be implemented by
different classes and be @dynamic in some, and non-@dynamic
in other ones. */
PROPERTY_DYNAMIC (property) = 1;
/* We have to copy the property, because we want to chain it to
the implementation context, and we want to store the source
location of the @synthesize, not of the original

View File

@ -100,8 +100,7 @@ typedef enum objc_property_assign_semantics {
#define PROPERTY_IVAR_NAME(DECL) ((DECL)->decl_common.initial)
/* PROPERTY_DYNAMIC can be 0 or 1. This is 1 if the PROPERTY_DECL
represents a @dynamic (or if it is a @property for which a @dynamic
declaration has been parsed); otherwise, it is set to 0. */
represents a @dynamic; otherwise, it is set to 0. */
#define PROPERTY_DYNAMIC(DECL) DECL_LANG_FLAG_2 (DECL)
/* PROPERTY_HAS_NO_GETTER can be 0 or 1. Normally it is 0, but if

View File

@ -1,3 +1,23 @@
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
* objc.dg/property/dotsyntax-13.m: New.
* objc.dg/property/dotsyntax-14.m: New.
* objc.dg/property/dotsyntax-15.m: New.
* objc.dg/property/synthesize-7.m: New.
* obj-c++.dg/property/dotsyntax-13.mm: New.
* obj-c++.dg/property/dotsyntax-14.mm: New.
* obj-c++.dg/property/dotsyntax-15.mm: New.
* obj-c++.dg/property/synthesize-7.mm: New.
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
* objc.dg/property/dynamic-4.m: New.
* objc.dg/property/dynamic-5.m: New.
* objc.dg/property/dynamic-6.m: New.
* obj-c++.dg/property/dynamic-4.mm: New.
* obj-c++.dg/property/dynamic-5.mm: New.
* obj-c++.dg/property/dynamic-6.mm: New.
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
* objc.dg/property/synthesize-3.m: New.

View File

@ -0,0 +1,53 @@
/* 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 a local variable. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
@interface MyRootClass
{
Class isa;
int a;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
- (int) count;
- (void) setCount: (int)count;
@end
@implementation MyRootClass
+ (id) initialize { return self; }
+ (id) alloc { return class_createInstance (self, 0); }
- (id) init { return self; }
- (int) count
{
return a;
}
- (void) setCount: (int)count
{
a = count;
}
@end
int main (void)
{
MyRootClass *object = [[MyRootClass alloc] init];
int i;
for (i = 0; i < 10; i++)
{
object.count = i;
if (object.count != i)
abort ();
}
return 0;
}

View File

@ -0,0 +1,77 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* Test dot-syntax with accessors to be looked up in protocol @properties. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
@protocol ProtocolA
@property int countA;
@end
@protocol ProtocolB
@property int countB;
@end
@protocol ProtocolC
@property int countC;
@end
@interface MyRootClass
{
Class isa;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
@end
@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
@end
int function (MySubClass *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */
return object.countC; /* { dg-error "request for member .countC. in" } */
}
int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function5 (id <ProtocolA, ProtocolB> object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */
return object.countC; /* { dg-error "request for member .countC. in" } */
}

View File

@ -0,0 +1,80 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* Test dot-syntax with accessors to be looked up in protocols. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
@protocol ProtocolA
- (int) countA;
- (void) setCountA: (int)aNumber;
@end
@protocol ProtocolB
- (int) countB;
- (void) setCountB: (int)aNumber;
@end
@protocol ProtocolC
- (int) countC;
- (void) setCountC: (int)aNumber;
@end
@interface MyRootClass
{
Class isa;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
@end
@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
@end
int function (MySubClass *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */
return object.countC; /* { dg-error "request for member .countC. in" } */
}
int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function5 (id <ProtocolA, ProtocolB> object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */
return object.countC; /* { dg-error "request for member .countC. in" } */
}

View File

@ -0,0 +1,45 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
#include <objc/objc.h>
@interface MyRootClass
{
Class isa;
}
@end
@implementation MyRootClass
@end
/* Test @property/@dynamic with protocols. */
@protocol MyProtocol
@property int a;
@end
/* This class is declared to conform to the protocol, but because of
@dynamic, no warnings are issued even if the getter/setter for the
@property are missing. */
@interface MyClass1 : MyRootClass <MyProtocol>
@end
@implementation MyClass1
@dynamic a;
@end
/* This class is declared to conform to the protocol and warnings are
issued because the setter for the @property is missing. */
@interface MyClass2 : MyRootClass <MyProtocol>
@end
@implementation MyClass2
- (int) a
{
return 0;
}
@end /* { dg-warning "incomplete implementation" } */
/* { dg-warning "method definition for .-setA:. not found" "" { target *-*-* } 43 } */
/* { dg-warning "class .MyClass2. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 43 } */

View File

@ -0,0 +1,53 @@
/* 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 @dynamic in the real scenario where a class declares a
@property, uses @dynamic to avoid implementing it, then subclasses
implement it. */
#include <objc/objc.h>
#include <objc/runtime.h>
#include <stdlib.h>
@interface MyRootClass
{
Class isa;
}
@property int a;
+ (id) initialize;
+ (id) alloc;
- (id) init;
@end
@implementation MyRootClass
+ (id) initialize { return self; }
+ (id) alloc { return class_createInstance (self, 0); }
- (id) init { return self; }
@dynamic a;
@end
@interface Test : MyRootClass
{
int v1;
}
@end
@implementation Test
@synthesize a = v1;
@end
int main (void)
{
/* Note how 'object' is declared to be of class 'MyRootClass', but
actually is of the subclass which implements the property for
real. */
MyRootClass *object = [[Test alloc] init];
object.a = 40;
if (object.a != 40)
abort ();
return 0;
}

View File

@ -0,0 +1,26 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* Test case when an accessor from a @property matches a method
required by a protocol. If the @property is @dynamic, then no
warning should be generated. */
#include <objc/objc.h>
#include <objc/runtime.h>
#include <stdlib.h>
@protocol Count
- (int) count;
@end
@interface MyRootClass <Count>
{
Class isa;
}
@property int count;
@end
@implementation MyRootClass
/* This @dynamic turns off any warnings for -count and -setCount:. */
@dynamic count;
@end

View File

@ -0,0 +1,86 @@
/* 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 @synthesize with protocols of protocols. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
@protocol ProtocolA
@property int countA;
@end
@protocol ProtocolB <ProtocolA>
@property int countB;
@end
@protocol ProtocolC <ProtocolB>
@property int countC;
@end
@protocol ProtocolD
@property int countD;
@end
@interface MyRootClass <ProtocolC>
{
Class isa;
int countA;
int countB;
int countC;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
@end
@implementation MyRootClass
+ (id) initialize { return self; }
+ (id) alloc { return class_createInstance (self, 0); }
- (id) init { return self; }
@synthesize countA;
@synthesize countB;
@synthesize countC;
@end
@interface MySubClass : MyRootClass <ProtocolD>
{
int countD;
}
@end
@implementation MySubClass
@synthesize countD;
@end
int main (void)
{
MySubClass *object = [[MySubClass alloc] init];
int i;
for (i = 0; i < 10; i++)
{
object.countA += i;
object.countB += i + 1;
object.countC += i + 2;
object.countD += i + 3;
}
if (object.countA != 45)
abort ();
if (object.countB != 55)
abort ();
if (object.countC != 65)
abort ();
if (object.countD != 75)
abort ();
return 0;
}

View File

@ -0,0 +1,53 @@
/* 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 a local variable. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
@interface MyRootClass
{
Class isa;
int a;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
- (int) count;
- (void) setCount: (int)count;
@end
@implementation MyRootClass
+ (id) initialize { return self; }
+ (id) alloc { return class_createInstance (self, 0); }
- (id) init { return self; }
- (int) count
{
return a;
}
- (void) setCount: (int)count
{
a = count;
}
@end
int main (void)
{
MyRootClass *object = [[MyRootClass alloc] init];
int i;
for (i = 0; i < 10; i++)
{
object.count = i;
if (object.count != i)
abort ();
}
return 0;
}

View File

@ -0,0 +1,77 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* Test dot-syntax with accessors to be looked up in protocol @properties. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
@protocol ProtocolA
@property int countA;
@end
@protocol ProtocolB
@property int countB;
@end
@protocol ProtocolC
@property int countC;
@end
@interface MyRootClass
{
Class isa;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
@end
@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
@end
int function (MySubClass *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
}
int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function5 (id <ProtocolA, ProtocolB> object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
}

View File

@ -0,0 +1,80 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* Test dot-syntax with accessors to be looked up in protocols. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
@protocol ProtocolA
- (int) countA;
- (void) setCountA: (int)aNumber;
@end
@protocol ProtocolB
- (int) countB;
- (void) setCountB: (int)aNumber;
@end
@protocol ProtocolC
- (int) countC;
- (void) setCountC: (int)aNumber;
@end
@interface MyRootClass
{
Class isa;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
@end
@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
@end
int function (MySubClass *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
}
int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB;
return object.countC;
}
int function5 (id <ProtocolA, ProtocolB> object, int x)
{
object.countA = x;
object.countB = x;
object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
}

View File

@ -0,0 +1,45 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
#include <objc/objc.h>
@interface MyRootClass
{
Class isa;
}
@end
@implementation MyRootClass
@end
/* Test @property/@dynamic with protocols. */
@protocol MyProtocol
@property int a;
@end
/* This class is declared to conform to the protocol, but because of
@dynamic, no warnings are issued even if the getter/setter for the
@property are missing. */
@interface MyClass1 : MyRootClass <MyProtocol>
@end
@implementation MyClass1
@dynamic a;
@end
/* This class is declared to conform to the protocol and warnings are
issued because the setter for the @property is missing. */
@interface MyClass2 : MyRootClass <MyProtocol>
@end
@implementation MyClass2
- (int) a
{
return 0;
}
@end /* { dg-warning "incomplete implementation" } */
/* { dg-warning "method definition for .-setA:. not found" "" { target *-*-* } 43 } */
/* { dg-warning "class .MyClass2. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 43 } */

View File

@ -0,0 +1,53 @@
/* 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 @dynamic in the real scenario where a class declares a
@property, uses @dynamic to avoid implementing it, then subclasses
implement it. */
#include <objc/objc.h>
#include <objc/runtime.h>
#include <stdlib.h>
@interface MyRootClass
{
Class isa;
}
@property int a;
+ (id) initialize;
+ (id) alloc;
- (id) init;
@end
@implementation MyRootClass
+ (id) initialize { return self; }
+ (id) alloc { return class_createInstance (self, 0); }
- (id) init { return self; }
@dynamic a;
@end
@interface Test : MyRootClass
{
int v1;
}
@end
@implementation Test
@synthesize a = v1;
@end
int main (void)
{
/* Note how 'object' is declared to be of class 'MyRootClass', but
actually is of the subclass which implements the property for
real. */
MyRootClass *object = [[Test alloc] init];
object.a = 40;
if (object.a != 40)
abort ();
return 0;
}

View File

@ -0,0 +1,26 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
/* { dg-do compile } */
/* Test case when an accessor from a @property matches a method
required by a protocol. If the @property is @dynamic, then no
warning should be generated. */
#include <objc/objc.h>
#include <objc/runtime.h>
#include <stdlib.h>
@protocol Count
- (int) count;
@end
@interface MyRootClass <Count>
{
Class isa;
}
@property int count;
@end
@implementation MyRootClass
/* This @dynamic turns off any warnings for -count and -setCount:. */
@dynamic count;
@end

View File

@ -0,0 +1,86 @@
/* 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 @synthesize with protocols of protocols. */
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
@protocol ProtocolA
@property int countA;
@end
@protocol ProtocolB <ProtocolA>
@property int countB;
@end
@protocol ProtocolC <ProtocolB>
@property int countC;
@end
@protocol ProtocolD
@property int countD;
@end
@interface MyRootClass <ProtocolC>
{
Class isa;
int countA;
int countB;
int countC;
}
+ (id) initialize;
+ (id) alloc;
- (id) init;
@end
@implementation MyRootClass
+ (id) initialize { return self; }
+ (id) alloc { return class_createInstance (self, 0); }
- (id) init { return self; }
@synthesize countA;
@synthesize countB;
@synthesize countC;
@end
@interface MySubClass : MyRootClass <ProtocolD>
{
int countD;
}
@end
@implementation MySubClass
@synthesize countD;
@end
int main (void)
{
MySubClass *object = [[MySubClass alloc] init];
int i;
for (i = 0; i < 10; i++)
{
object.countA += i;
object.countB += i + 1;
object.countC += i + 2;
object.countD += i + 3;
}
if (object.countA != 45)
abort ();
if (object.countB != 55)
abort ();
if (object.countC != 65)
abort ();
if (object.countD != 75)
abort ();
return 0;
}