ObjC/ObjC++: Fix property encoding on Apple

Jack Howarth howarth@bromo.med.uc.edu
Fri Feb 25 06:21:00 GMT 2011


On Fri, Feb 25, 2011 at 12:48:07AM +0000, Nicola Pero wrote:
> This patch removes another big FIXME that was introduced with the last  
> big ObjC patch,
> which is the fact that the property encoding is not working.  This patch 
> fixes it.
>
> The patch includes two testcases.  I ran them manually a few times on an 
> Apple 32-bit with the stock
> Apple compiler to study the output and make sure the output of our own  
> compiler matches the output
> of the stock compiler.
>
> At the moment, the testcases are conditional on #ifdef __OBJC2__, which 
> currently means only Apple
> 64-bit with the NeXT runtime (ABI 2).  In the future, it will also mean 
> the GNU runtime (when a new ABI is
> implemented).  It would be nice to run these (and many/all other!)  
> testcases with -fobjc-abi-version=1
> on Apple, but that is a separate change/rework of the ObjC testsuite.
>
> Ok to commit ?
>
> Thanks
>
> PS: I tested on Apple m32.  I don't have an Apple m64.  I'd be grateful 
> if someone could try out the
> patch on there before I commit to confirm that it all looks good there.  
> Thank! :-)

Nicola,
   Can you repost the patch as an attachment? Your emailer seems to 
have reformatted the patch so that it is considered as malformed by
patch and can't be applied against gcc trunk.
           Jack

>
> Index: objc/ChangeLog
> ===================================================================
> --- objc/ChangeLog      (revision 170464)
> +++ objc/ChangeLog      (working copy)
> @@ -1,3 +1,7 @@
> +2011-02-25  Nicola Pero  <nicola.pero@meta-innovation.com>
> +
> +       * objc-act.c (objc_v2_encode_prop_attr): Rewritten.
> +
>  2011-02-23  Nicola Pero  <nicola.pero@meta-innovation.com>
>
>         * objc-act.c (build_private_template): Do not copy the
> @@ -16,7 +20,8 @@
>
>  2011-02-21  Mike Stump  <mikestump@comcast.net>
>
> -       * Make-lang.in (check_objc_parallelize): Refine for 4 processor 
> machines.
> +       * Make-lang.in (check_objc_parallelize): Refine for 4 processor
> +       machines.
>
>  2011-02-20  Nicola Pero  <nicola.pero@meta-innovation.com>
>
> Index: objc/objc-act.c
> ===================================================================
> --- objc/objc-act.c     (revision 170464)
> +++ objc/objc-act.c     (working copy)
> @@ -10495,47 +10495,79 @@ encode_field_decl (tree field_decl, int
>       kPropertyGetter = 'G',
>       kPropertySetter = 'S',
>       kPropertyInstanceVariable = 'V',
> -     kPropertyType = 't',
> +     kPropertyType = 'T',
>       kPropertyWeak = 'W',
> -     kPropertyStrong = 'S',
> +     kPropertyStrong = 'P',
>       kPropertyNonAtomic = 'N'
> -   };
> -
> -   FIXME: Update the implementation to match.  */
> +   };  */
>  tree
>  objc_v2_encode_prop_attr (tree property)
>  {
>    const char *string;
>    tree type = TREE_TYPE (property);
> -  obstack_1grow (&util_obstack, 't');
> +
> +  obstack_1grow (&util_obstack, 'T');
>    encode_type (type, obstack_object_size (&util_obstack),
>                OBJC_ENCODE_INLINE_DEFS);
> +
>    if (PROPERTY_READONLY (property))
> -    obstack_grow (&util_obstack, ",r", 2);
> +    obstack_grow (&util_obstack, ",R", 2);
> +
> +  switch (PROPERTY_ASSIGN_SEMANTICS (property))
> +    {
> +    case OBJC_PROPERTY_COPY:
> +      obstack_grow (&util_obstack, ",C", 2);
> +      break;
> +    case OBJC_PROPERTY_RETAIN:
> +      obstack_grow (&util_obstack, ",&", 2);
> +      break;
> +    case OBJC_PROPERTY_ASSIGN:
> +    default:
> +      break;
> +    }
>
> -  if (PROPERTY_ASSIGN_SEMANTICS (property) == OBJC_PROPERTY_COPY)
> -    obstack_grow (&util_obstack, ",c", 2);
> +  if (PROPERTY_DYNAMIC (property))
> +    obstack_grow (&util_obstack, ",D", 2);
>
> -  if (PROPERTY_GETTER_NAME (property))
> +  if (PROPERTY_NONATOMIC (property))
> +    obstack_grow (&util_obstack, ",N", 2);
> +
> +  /* Here we want to encode the getter name, but only if it's not the
> +     standard one.  */
> +  if (PROPERTY_GETTER_NAME (property) != PROPERTY_NAME (property))
>      {
> -      obstack_grow (&util_obstack, ",g", 2);
> +      obstack_grow (&util_obstack, ",G", 2);
>        string = IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property));
>        obstack_grow (&util_obstack, string, strlen (string));
>      }
> -  if (PROPERTY_SETTER_NAME (property))
> +
> +  if (!PROPERTY_READONLY (property))
>      {
> -      obstack_grow (&util_obstack, ",s", 2);
> -      string = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property));
> -      obstack_grow (&util_obstack, string, strlen (string));
> +      /* Here we want to encode the setter name, but only if it's not
> +        the standard one.  */
> +      tree standard_setter = get_identifier  
> (objc_build_property_setter_name (PROPERTY_NAME (property)));
> +      if (PROPERTY_SETTER_NAME (property) != standard_setter)
> +       {
> +         obstack_grow (&util_obstack, ",S", 2);
> +         string = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property));
> +         obstack_grow (&util_obstack, string, strlen (string));
> +       }
>      }
> -  if (PROPERTY_IVAR_NAME (property))
> +
> +  /* TODO: Encode strong ('P'), weak ('W') for garbage collection.  */
> +
> +  if (!PROPERTY_DYNAMIC (property))
>      {
> -      obstack_grow (&util_obstack, ",i", 2);
> -      string = IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property));
> +      obstack_grow (&util_obstack, ",V", 2);
> +      if (PROPERTY_IVAR_NAME (property))
> +       string = IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property));
> +      else
> +       string = IDENTIFIER_POINTER (PROPERTY_NAME (property));
>        obstack_grow (&util_obstack, string, strlen (string));
>      }
> -
> -  obstack_1grow (&util_obstack, 0);    /* null terminate string */
> +
> +  /* NULL-terminate string.  */
> +  obstack_1grow (&util_obstack, 0);
>    string = XOBFINISH (&util_obstack, char *);
>    obstack_free (&util_obstack, util_firstobj);
>    return get_identifier (string);
> Index: testsuite/ChangeLog
> ===================================================================
> --- testsuite/ChangeLog (revision 170464)
> +++ testsuite/ChangeLog (working copy)
> @@ -1,3 +1,11 @@
> +2011-02-25  Nicola Pero  <nicola.pero@meta-innovation.com>
> +
> +       * objc.dg/gnu-api-2-property.m: Added tests for  
> property_getName()
> +       and property_getAttributes() if __OBJC2__.
> +       * obj-c++.dg/gnu-api-2-property.mm: Likewise.
> +       * objc.dg/property/property-encoding-1.m: New.
> +       * obj-c++.dg/property/property-encoding-1.mm: New.
> +
>  2011-02-24  Richard Guenther  <rguenther@suse.de>
>
>         PR fortran/47839
> Index: testsuite/objc.dg/property/property-encoding-1.m
> ===================================================================
> --- testsuite/objc.dg/property/property-encoding-1.m    (revision 0)
> +++ testsuite/objc.dg/property/property-encoding-1.m    (revision 0)
> @@ -0,0 +1,160 @@
> +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>,  
> February 2011.  */
> +/* Test encoding properties.  */
> +/* { dg-do run } */
> +/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext- 
> runtime" } { "" } } */
> +
> +#include <objc/runtime.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +
> +@interface MyRootClass
> +{ Class isa; }
> ++ alloc;
> +- init;
> ++ initialize;
> +@end
> +
> +@implementation MyRootClass
> ++ alloc { return class_createInstance (self, 0); }
> +- init  { return self; }
> ++ initialize { return self; }
> +@end
> +
> +@interface MySubClass : MyRootClass
> +{
> +  char char_property;
> +  short short_property;
> +  int int_property;
> +  long long_property;
> +  float float_property;
> +  double double_property;
> +  int *int_pointer_property;
> +
> +  id propertyA;
> +  id propertyB;
> +  id propertyC;
> +  id propertyD;
> +  int propertyE;
> +  id propertyF;
> +
> +  id other_variable;
> +}
> +@property char char_property;
> +@property short short_property;
> +@property int int_property;
> +@property long long_property;
> +@property float float_property;
> +@property double double_property;
> +@property int *int_pointer_property;
> +
> +@property (assign, getter=getP, setter=setP:) id propertyA;
> +@property (assign) id propertyB;
> +@property (copy) id propertyC;
> +@property (retain) id propertyD;
> +@property (nonatomic) int propertyE;
> +@property (nonatomic, readonly, copy) id propertyF;
> +
> +@property (assign) id propertyG;
> +@property (assign, readonly, getter=X) id propertyH;
> +@end
> +
> +@implementation MySubClass
> +@synthesize char_property;
> +@synthesize short_property;
> +@synthesize int_property;
> +@synthesize long_property;
> +@synthesize float_property;
> +@synthesize double_property;
> +@synthesize int_pointer_property;
> +
> +@synthesize propertyA;
> +@synthesize propertyB;
> +@synthesize propertyC;
> +@synthesize propertyD;
> +@synthesize propertyE;
> +@synthesize propertyF;
> +
> +@synthesize propertyG = other_variable;
> +@dynamic propertyH;
> +@end
> +
> +#ifdef __OBJC2__
> +void error (objc_property_t p)
> +{
> +  printf ("Error - property_getAttributes (\"%s\") returns \"%s\"\n",
> +         property_getName (p),
> +         property_getAttributes (p));
> +  abort ();
> +}
> +#endif
> +
> +int main(int argc, void **args)
> +{
> +#ifdef __OBJC2__
> +  Class c = objc_getClass ("MySubClass");
> +  objc_property_t p;
> +
> +  p = class_getProperty (c, "char_property");
> +  if (strcmp ("Tc,Vchar_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "short_property");
> +  if (strcmp ("Ts,Vshort_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "int_property");
> +  if (strcmp ("Ti,Vint_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "long_property");
> +  if (strcmp ("Tl,Vlong_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "float_property");
> +  if (strcmp ("Tf,Vfloat_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "double_property");
> +  if (strcmp ("Td,Vdouble_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "int_pointer_property");
> +  if (strcmp ("T^i,Vint_pointer_property", property_getAttributes (p)) 
> != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyA");
> +  if (strcmp ("T@,GgetP,SsetP:,VpropertyA", property_getAttributes (p)) 
> != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyB");
> +  if (strcmp ("T@,VpropertyB", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyC");
> +  if (strcmp ("T@,C,VpropertyC", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyD");
> +  if (strcmp ("T@,&,VpropertyD", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyE");
> +  if (strcmp ("Ti,N,VpropertyE", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyF");
> +  if (strcmp ("T@,R,C,N,VpropertyF", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyG");
> +  if (strcmp ("T@,Vother_variable", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyH");
> +  if (strcmp ("T@,R,D,GX", property_getAttributes (p)) != 0)
> +    error (p);
> +#endif
> +
> +  return 0;
> +}
> Index: testsuite/objc.dg/gnu-api-2-property.m
> ===================================================================
> --- testsuite/objc.dg/gnu-api-2-property.m      (revision 170464)
> +++ testsuite/objc.dg/gnu-api-2-property.m      (working copy)
> @@ -25,23 +25,18 @@
>  + initialize { return self; }
>  @end
>
> -@protocol MyProtocol
> -- (id) variable;
> -@end
> -
> -@protocol MySecondProtocol
> -- (id) setVariable: (id)value;
> -@end
> -
> -@interface MySubClass : MyRootClass <MyProtocol>
> -{ id variable_ivar; }
> -- (void) setVariable: (id)value;
> -- (id) variable;
> +@interface MySubClass : MyRootClass
> +{
> +  id propertyA;
> +  id propertyB;
> +}
> +@property (assign, getter=getP, setter=setP:) id propertyA;
> +@property (assign, nonatomic) id propertyB;
>  @end
>
>  @implementation MySubClass
> -- (void) setVariable: (id)value { variable_ivar = value; }
> -- (id) variable { return variable_ivar; }
> +@synthesize propertyA;
> +@synthesize propertyB;
>  @end
>
>
> @@ -49,7 +44,6 @@ int main(int argc, void **args)
>  {
>    /* Functions are tested in alphabetical order.  */
>
> -  /* TODO: Test new ABI (when available).  */
>    printf ("Testing property_getAttributes () ...\n");
>    {
>      /* The Apple/NeXT runtime seems to crash on the following.  */
> @@ -57,9 +51,26 @@ int main(int argc, void **args)
>      if (property_getAttributes (NULL) != NULL)
>        abort ();
>  #endif
> +
> +    /* The GNU runtime doesn't support looking up properties at
> +       runtime yet.  */
> +#ifdef __OBJC2__
> +    {
> +      objc_property_t property;
> +
> +      property = class_getProperty (objc_getClass ("MySubClass"),  
> "propertyA");
> +      if (strcmp (property_getAttributes (property),
> +                 "T@,GgetP,SsetP:,VpropertyA") != 0)
> +       abort ();
> +
> +      property = class_getProperty (objc_getClass ("MySubClass"),  
> "propertyB");
> +      if (strcmp (property_getAttributes (property),
> +                 "T@,N,VpropertyB") != 0)
> +       abort ();
> +    }
> +#endif
>    }
>
> -  /* TODO: Test new ABI (when available).  */
>    printf ("Testing property_getName () ...\n");
>    {
>      /* The Apple/NeXT runtime seems to crash on the following.  */
> @@ -67,6 +78,22 @@ int main(int argc, void **args)
>      if (property_getName (NULL) != NULL)
>        abort ();
>  #endif
> +
> +    /* The GNU runtime doesn't support looking up properties at
> +       runtime yet.  */
> +#ifdef __OBJC2__
> +    {
> +      objc_property_t property;
> +
> +      property = class_getProperty (objc_getClass ("MySubClass"),  
> "propertyA");
> +      if (strcmp (property_getName (property), "propertyA") != 0)
> +       abort ();
> +
> +      property = class_getProperty (objc_getClass ("MySubClass"),  
> "propertyB");
> +      if (strcmp (property_getName (property), "propertyB") != 0)
> +       abort ();
> +    }
> +#endif
>    }
>
>    return 0;
> Index: testsuite/obj-c++.dg/property/property-encoding-1.mm
> ===================================================================
> --- testsuite/obj-c++.dg/property/property-encoding-1.mm         
> (revision 0)
> +++ testsuite/obj-c++.dg/property/property-encoding-1.mm         
> (revision 0)
> @@ -0,0 +1,160 @@
> +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>,  
> February 2011.  */
> +/* Test encoding properties.  */
> +/* { dg-do run } */
> +/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext- 
> runtime" } { "" } } */
> +
> +#include <objc/runtime.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +
> +@interface MyRootClass
> +{ Class isa; }
> ++ alloc;
> +- init;
> ++ initialize;
> +@end
> +
> +@implementation MyRootClass
> ++ alloc { return class_createInstance (self, 0); }
> +- init  { return self; }
> ++ initialize { return self; }
> +@end
> +
> +@interface MySubClass : MyRootClass
> +{
> +  char char_property;
> +  short short_property;
> +  int int_property;
> +  long long_property;
> +  float float_property;
> +  double double_property;
> +  int *int_pointer_property;
> +
> +  id propertyA;
> +  id propertyB;
> +  id propertyC;
> +  id propertyD;
> +  int propertyE;
> +  id propertyF;
> +
> +  id other_variable;
> +}
> +@property char char_property;
> +@property short short_property;
> +@property int int_property;
> +@property long long_property;
> +@property float float_property;
> +@property double double_property;
> +@property int *int_pointer_property;
> +
> +@property (assign, getter=getP, setter=setP:) id propertyA;
> +@property (assign) id propertyB;
> +@property (copy) id propertyC;
> +@property (retain) id propertyD;
> +@property (nonatomic) int propertyE;
> +@property (nonatomic, readonly, copy) id propertyF;
> +
> +@property (assign) id propertyG;
> +@property (assign, readonly, getter=X) id propertyH;
> +@end
> +
> +@implementation MySubClass
> +@synthesize char_property;
> +@synthesize short_property;
> +@synthesize int_property;
> +@synthesize long_property;
> +@synthesize float_property;
> +@synthesize double_property;
> +@synthesize int_pointer_property;
> +
> +@synthesize propertyA;
> +@synthesize propertyB;
> +@synthesize propertyC;
> +@synthesize propertyD;
> +@synthesize propertyE;
> +@synthesize propertyF;
> +
> +@synthesize propertyG = other_variable;
> +@dynamic propertyH;
> +@end
> +
> +#ifdef __OBJC2__
> +void error (objc_property_t p)
> +{
> +  printf ("Error - property_getAttributes (\"%s\") returns \"%s\"\n",
> +         property_getName (p),
> +         property_getAttributes (p));
> +  abort ();
> +}
> +#endif
> +
> +int main(int argc, char **args)
> +{
> +#ifdef __OBJC2__
> +  Class c = objc_getClass ("MySubClass");
> +  objc_property_t p;
> +
> +  p = class_getProperty (c, "char_property");
> +  if (strcmp ("Tc,Vchar_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "short_property");
> +  if (strcmp ("Ts,Vshort_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "int_property");
> +  if (strcmp ("Ti,Vint_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "long_property");
> +  if (strcmp ("Tl,Vlong_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "float_property");
> +  if (strcmp ("Tf,Vfloat_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "double_property");
> +  if (strcmp ("Td,Vdouble_property", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "int_pointer_property");
> +  if (strcmp ("T^i,Vint_pointer_property", property_getAttributes (p)) 
> != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyA");
> +  if (strcmp ("T@,GgetP,SsetP:,VpropertyA", property_getAttributes (p)) 
> != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyB");
> +  if (strcmp ("T@,VpropertyB", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyC");
> +  if (strcmp ("T@,C,VpropertyC", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyD");
> +  if (strcmp ("T@,&,VpropertyD", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyE");
> +  if (strcmp ("Ti,N,VpropertyE", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyF");
> +  if (strcmp ("T@,R,C,N,VpropertyF", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyG");
> +  if (strcmp ("T@,Vother_variable", property_getAttributes (p)) != 0)
> +    error (p);
> +
> +  p = class_getProperty (c, "propertyH");
> +  if (strcmp ("T@,R,D,GX", property_getAttributes (p)) != 0)
> +    error (p);
> +#endif
> +
> +  return 0;
> +}
> Index: testsuite/obj-c++.dg/gnu-api-2-property.mm
> ===================================================================
> --- testsuite/obj-c++.dg/gnu-api-2-property.mm  (revision 170464)
> +++ testsuite/obj-c++.dg/gnu-api-2-property.mm  (working copy)
> @@ -25,23 +25,18 @@
>  + initialize { return self; }
>  @end
>
> -@protocol MyProtocol
> -- (id) variable;
> -@end
> -
> -@protocol MySecondProtocol
> -- (id) setVariable: (id)value;
> -@end
> -
> -@interface MySubClass : MyRootClass <MyProtocol>
> -{ id variable_ivar; }
> -- (void) setVariable: (id)value;
> -- (id) variable;
> +@interface MySubClass : MyRootClass
> +{
> +  id propertyA;
> +  id propertyB;
> +}
> +@property (assign, getter=getP, setter=setP:) id propertyA;
> +@property (assign, nonatomic) id propertyB;
>  @end
>
>  @implementation MySubClass
> -- (void) setVariable: (id)value { variable_ivar = value; }
> -- (id) variable { return variable_ivar; }
> +@synthesize propertyA;
> +@synthesize propertyB;
>  @end
>
>
> @@ -49,7 +44,6 @@ int main ()
>  {
>    /* Functions are tested in alphabetical order.  */
>
> -  /* TODO: Test new ABI (when available).  */
>    std::cout << "Testing property_getAttributes () ...\n";
>    {
>      /* The Apple/NeXT runtime seems to crash on the following.  */
> @@ -57,9 +51,26 @@ int main ()
>      if (property_getAttributes (NULL) != NULL)
>        abort ();
>  #endif
> +
> +    /* The GNU runtime doesn't support looking up properties at
> +       runtime yet.  */
> +#ifdef __OBJC2__
> +    {
> +      objc_property_t property;
> +
> +      property = class_getProperty (objc_getClass ("MySubClass"),  
> "propertyA");
> +      if (std::strcmp (property_getAttributes (property),
> +                 "T@,GgetP,SsetP:,VpropertyA") != 0)
> +       abort ();
> +
> +      property = class_getProperty (objc_getClass ("MySubClass"),  
> "propertyB");
> +      if (std::strcmp (property_getAttributes (property),
> +                 "T@,N,VpropertyB") != 0)
> +       abort ();
> +    }
> +#endif
>    }
>
> -  /* TODO: Test new ABI (when available).  */
>    std::cout << "Testing property_getName () ...\n";
>    {
>      /* The Apple/NeXT runtime seems to crash on the following.  */
> @@ -68,6 +79,22 @@ int main ()
>      if (property_getName (NULL) != NULL)
>        abort ();
>  #endif
> +
> +    /* The GNU runtime doesn't support looking up properties at
> +       runtime yet.  */
> +#ifdef __OBJC2__
> +    {
> +      objc_property_t property;
> +
> +      property = class_getProperty (objc_getClass ("MySubClass"),  
> "propertyA");
> +      if (std::strcmp (property_getName (property), "propertyA") != 0)
> +       abort ();
> +
> +      property = class_getProperty (objc_getClass ("MySubClass"),  
> "propertyB");
> +      if (std::strcmp (property_getName (property), "propertyB") != 0)
> +       abort ();
> +    }
> +#endif
>    }
>
>    return (0);



More information about the Gcc-patches mailing list