Commit d36dba07 by Nicola Pero Committed by Nicola Pero

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
parent 4741888d
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com> 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): * objc-act.c (objc_add_synthesize_declaration_for_property):
Iterate over IMPL_PROPERTY_DECL, not CLASS_PROPERTY_DECL, when Iterate over IMPL_PROPERTY_DECL, not CLASS_PROPERTY_DECL, when
checking for an existing @synthesize or @dynamic declaration. checking for an existing @synthesize or @dynamic declaration.
......
...@@ -8738,9 +8738,19 @@ check_methods (tree chain, tree implementation, int mtype) ...@@ -8738,9 +8738,19 @@ check_methods (tree chain, tree implementation, int mtype)
{ {
/* If the method is associated with a dynamic property, then it /* If the method is associated with a dynamic property, then it
is Ok not to have the method implementation, as it will be is Ok not to have the method implementation, as it will be
generated dynamically at runtime. */ generated dynamically at runtime. To decide if the method is
tree property = METHOD_PROPERTY_CONTEXT (chain); associated with a @dynamic property, we search the list of
if (property != NULL_TREE && PROPERTY_DYNAMIC (property)) @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... */ chain = TREE_CHAIN (chain); /* next method... */
continue; continue;
...@@ -8751,6 +8761,7 @@ check_methods (tree chain, tree implementation, int mtype) ...@@ -8751,6 +8761,7 @@ check_methods (tree chain, tree implementation, int mtype)
/* If the method is a property setter/getter, we'll still /* If the method is a property setter/getter, we'll still
allow it to be missing if it is implemented by allow it to be missing if it is implemented by
'interface' or any of its superclasses. */ 'interface' or any of its superclasses. */
tree property = METHOD_PROPERTY_CONTEXT (chain);
if (property) if (property)
{ {
/* Note that since this is a property getter/setter, it /* Note that since this is a property getter/setter, it
...@@ -8864,9 +8875,17 @@ check_methods_accessible (tree chain, tree context, int mtype) ...@@ -8864,9 +8875,17 @@ check_methods_accessible (tree chain, tree context, int mtype)
{ {
/* If the method is associated with a dynamic property, then it /* If the method is associated with a dynamic property, then it
is Ok not to have the method implementation, as it will be is Ok not to have the method implementation, as it will be
generated dynamically at runtime. */ generated dynamically at runtime. Search for any @dynamic
tree property = METHOD_PROPERTY_CONTEXT (chain); property with the same setter or getter name as this
if (property != NULL_TREE && PROPERTY_DYNAMIC (property)) 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... */ chain = TREE_CHAIN (chain); /* next method... */
continue; continue;
...@@ -9910,11 +9929,9 @@ objc_add_dynamic_declaration_for_property (location_t location, tree interface, ...@@ -9910,11 +9929,9 @@ objc_add_dynamic_declaration_for_property (location_t location, tree interface,
return; return;
} }
/* Check that the property is declared in the corresponding /* Check that the property is declared in the interface. It could
interface. */ also be declared in a superclass or protocol. */
for (property = CLASS_PROPERTY_DECL (interface); property; property = TREE_CHAIN (property)) property = lookup_property (interface, property_name);
if (PROPERTY_NAME (property) == property_name)
break;
if (!property) if (!property)
{ {
...@@ -9924,17 +9941,6 @@ objc_add_dynamic_declaration_for_property (location_t location, tree interface, ...@@ -9924,17 +9941,6 @@ objc_add_dynamic_declaration_for_property (location_t location, tree interface,
} }
else 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 /* We have to copy the property, because we want to chain it to
the implementation context, and we want to store the source the implementation context, and we want to store the source
location of the @synthesize, not of the original location of the @synthesize, not of the original
......
...@@ -100,8 +100,7 @@ typedef enum objc_property_assign_semantics { ...@@ -100,8 +100,7 @@ typedef enum objc_property_assign_semantics {
#define PROPERTY_IVAR_NAME(DECL) ((DECL)->decl_common.initial) #define PROPERTY_IVAR_NAME(DECL) ((DECL)->decl_common.initial)
/* PROPERTY_DYNAMIC can be 0 or 1. This is 1 if the PROPERTY_DECL /* 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 represents a @dynamic; otherwise, it is set to 0. */
declaration has been parsed); otherwise, it is set to 0. */
#define PROPERTY_DYNAMIC(DECL) DECL_LANG_FLAG_2 (DECL) #define PROPERTY_DYNAMIC(DECL) DECL_LANG_FLAG_2 (DECL)
/* PROPERTY_HAS_NO_GETTER can be 0 or 1. Normally it is 0, but if /* PROPERTY_HAS_NO_GETTER can be 0 or 1. Normally it is 0, but if
......
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com> 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. * objc.dg/property/synthesize-3.m: New.
* objc.dg/property/synthesize-4.m: New. * objc.dg/property/synthesize-4.m: New.
* objc.dg/property/synthesize-5.m: New. * objc.dg/property/synthesize-5.m: New.
......
/* 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;
}
/* 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" } */
}
/* 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" } */
}
/* 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 } */
/* 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;
}
/* 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
/* 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;
}
/* 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;
}
/* 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" } */
}
/* 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" } */
}
/* 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 } */
/* 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;
}
/* 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
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment