Patchwork ObjC/ObjC++: Fix property encoding on Apple

login
register
mail settings
Submitter Nicola Pero
Date March 2, 2011, 6:34 p.m.
Message ID <6424477D-9FB9-4655-9975-EE0921096B67@meta-innovation.com>
Download mbox | patch
Permalink /patch/85125/
State New
Headers show

Comments

Nicola Pero - March 2, 2011, 6:34 p.m.
Jack

thanks for your help and sorry about the confusion.  In attach a patch  
that should apply clean to trunk.
Can you apply it and try out the testsuite on Apple m64 ?

Thanks

Patch

Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog	(revision 170621)
+++ gcc/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-03-01  Jason Merrill  <jason@redhat.com>
 
 	* g++.dg/cpp0x/lambda/lambda-98.C: New.
Index: gcc/testsuite/objc.dg/property/property-encoding-1.m
===================================================================
--- gcc/testsuite/objc.dg/property/property-encoding-1.m	(revision 0)
+++ gcc/testsuite/objc.dg/property/property-encoding-1.m	(revision 0)
@@ -0,0 +1,183 @@ 
+/* 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 ();
+}
+
+/* Concatenate 3 strings and return the result.  */
+char *concat (char *a, char *b, char *c)
+{
+  /* We happily leak memory here.  This is a test.  */
+  char *x = malloc (sizeof (char) * 128);
+  snprintf (x, 128, "%s%s%s", a, b, c);
+  return x;
+}
+
+#endif
+
+int main(int argc, void **args)
+{
+#ifdef __OBJC2__
+  Class c = objc_getClass ("MySubClass");
+  objc_property_t p;
+  const char *expected_result;
+
+  p = class_getProperty (c, "char_property");
+  /* Usually we expect "Tc,Vchar_property", but if a char is of
+     different size, it may be encoded differently than "c".  */
+  if (strcmp (concat ("T", @encode (char), ",Vchar_property"),
+	      property_getAttributes (p)) != 0)
+    error (p);
+
+  p = class_getProperty (c, "short_property");
+  if (strcmp (concat ("T", @encode (short), ",Vshort_property"),
+	      property_getAttributes (p)) != 0)
+    error (p);
+
+  p = class_getProperty (c, "int_property");
+  if (strcmp (concat ("T", @encode (int), ",Vint_property"),
+	      property_getAttributes (p)) != 0)
+    error (p);
+
+  p = class_getProperty (c, "long_property");
+  if (strcmp (concat ("T", @encode (long), ",Vlong_property"),
+	      property_getAttributes (p)) != 0)
+    error (p);
+
+  p = class_getProperty (c, "float_property");
+  if (strcmp (concat ("T", @encode (float), ",Vfloat_property"),
+	      property_getAttributes (p)) != 0)
+    error (p);
+
+  p = class_getProperty (c, "double_property");
+  if (strcmp (concat ("T", @encode (double), ",Vdouble_property"),
+	      property_getAttributes (p)) != 0)
+    error (p);
+
+  p = class_getProperty (c, "int_pointer_property");
+  if (strcmp (concat ("T", @encode (int *), ",Vint_pointer_property"),
+	      property_getAttributes (p)) != 0)
+    error (p);
+
+  /* Objects are always encoded as '@' hence the string does not
+     depend on the architecture.  */
+  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 (concat ("T", @encode (int), ",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: gcc/testsuite/objc.dg/gnu-api-2-property.m
===================================================================
--- gcc/testsuite/objc.dg/gnu-api-2-property.m	(revision 170621)
+++ gcc/testsuite/objc.dg/gnu-api-2-property.m	(working copy)
@@ -25,23 +25,18 @@ 
 + initialize { return self; }
 @end
 
-@protocol MyProtocol
-- (id) variable;
+@interface MySubClass : MyRootClass
+{
+  id propertyA;
+  id propertyB;
+}
+@property (assign, getter=getP, setter=setP:) id propertyA;
+@property (assign, nonatomic) id propertyB;
 @end
 
-@protocol MySecondProtocol
-- (id) setVariable: (id)value;
-@end
-
-@interface MySubClass : MyRootClass <MyProtocol>
-{ id variable_ivar; }
-- (void) setVariable: (id)value;
-- (id) variable;
-@end
-
 @implementation MySubClass
-- (void) setVariable: (id)value { variable_ivar = value; }
-- (id) variable { return variable_ivar; }
+@synthesize propertyA;
+@synthesize propertyB;
 @end
 
 
@@ -49,7 +44,6 @@ 
 {
   /* 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 @@ 
     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 @@ 
     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: gcc/testsuite/obj-c++.dg/property/property-encoding-1.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/property/property-encoding-1.mm	(revision 0)
+++ gcc/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: gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm	(revision 170621)
+++ gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm	(working copy)
@@ -25,23 +25,18 @@ 
 + initialize { return self; }
 @end
 
-@protocol MyProtocol
-- (id) variable;
+@interface MySubClass : MyRootClass
+{
+  id propertyA;
+  id propertyB;
+}
+@property (assign, getter=getP, setter=setP:) id propertyA;
+@property (assign, nonatomic) id propertyB;
 @end
 
-@protocol MySecondProtocol
-- (id) setVariable: (id)value;
-@end
-
-@interface MySubClass : MyRootClass <MyProtocol>
-{ id variable_ivar; }
-- (void) setVariable: (id)value;
-- (id) variable;
-@end
-
 @implementation MySubClass
-- (void) setVariable: (id)value { variable_ivar = value; }
-- (id) variable { return variable_ivar; }
+@synthesize propertyA;
+@synthesize propertyB;
 @end
 
 
@@ -49,7 +44,6 @@ 
 {
   /* 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 @@ 
     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 @@ 
     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);