In gcc/objc/:
authornicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Nov 2010 19:50:13 +0000 (19:50 +0000)
committernicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Nov 2010 19:50:13 +0000 (19:50 +0000)
2010-11-25  Nicola Pero  <nicola.pero@meta-innovation.com>

* objc-act.c (objc_build_struct): Install TYPE_OBJC_INTERFACE
after finish_struct, not before, otherwise it may be wiped out by
it.  This fixes spurious warnings when a class has more than 15
instance variables.

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

* objc.dg/ivar-problem-1.m: New.
* obj-c++.dg/ivar-problem-1.mm: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167151 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/ivar-problem-1.mm [new file with mode: 0644]
gcc/testsuite/objc.dg/ivar-problem-1.m [new file with mode: 0644]

index e5b453b..fb1ee6a 100644 (file)
@@ -1,3 +1,10 @@
+2010-11-25  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc-act.c (objc_build_struct): Install TYPE_OBJC_INTERFACE
+       after finish_struct, not before, otherwise it may be wiped out by
+       it.  This fixes spurious warnings when a class has more than 15
+       instance variables.
+
 2010-11-23  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        PR objc/24358
index 45c9441..042fa35 100644 (file)
@@ -2137,10 +2137,15 @@ objc_build_struct (tree klass, tree fields, tree super_name)
       fields = base;
     }
 
-  /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
-     in all variants of this RECORD_TYPE to be clobbered, but it is therein
-     that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
-     Hence, we must squirrel away the ObjC-specific information before calling
+  /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC
+     fields in all variants of this RECORD_TYPE to be clobbered (this
+     is because the C frontend stores a sorted version of the list of
+     fields in lang_type if it deems appropriate, and will update and
+     propagate that list to all variants ignoring the fact that we use
+     lang_type for something else and that such propagation will wipe
+     the objc_info away), but it is therein that we store protocol
+     conformance info (e.g., 'NSObject <MyProtocol>').  Hence, we must
+     squirrel away the ObjC-specific information before calling
      finish_struct(), and then reinstate it afterwards.  */
 
   for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
@@ -2153,12 +2158,16 @@ objc_build_struct (tree klass, tree fields, tree super_name)
       VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
     }
 
-  /* Point the struct at its related Objective-C class.  */
-  INIT_TYPE_OBJC_INFO (s);
-  TYPE_OBJC_INTERFACE (s) = klass;
-
   s = objc_finish_struct (s, fields);
 
+  /* Point the struct at its related Objective-C class.  We do this
+     after calling finish_struct() because otherwise finish_struct()
+     would wipe TYPE_OBJC_INTERFACE() out.  */
+  if (!TYPE_HAS_OBJC_INFO (s))
+    INIT_TYPE_OBJC_INFO (s);
+
+  TYPE_OBJC_INTERFACE (s) = klass;
+
   for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
     {
       TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
index b19b812..9af459f 100644 (file)
@@ -1,3 +1,8 @@
+2010-11-25  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc.dg/ivar-problem-1.m: New.
+       * obj-c++.dg/ivar-problem-1.mm: New.
+
 2010-11-25  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/46637
diff --git a/gcc/testsuite/obj-c++.dg/ivar-problem-1.mm b/gcc/testsuite/obj-c++.dg/ivar-problem-1.mm
new file mode 100644 (file)
index 0000000..4ed5afa
--- /dev/null
@@ -0,0 +1,66 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do compile } */
+
+/* This test checks what happens if there are 16 instance variables.
+   In that case, the class was not created correctly.  In this testcase,
+   we have two classes, one with 15 variables and one with 16.  Older
+   GCCs would generate a bogus warning for the second class but not 
+   for the first one.  This only happened for ObjC, but it's good to
+   test ObjC++ as well.  */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+
+@interface MyRootClass1
+{
+  Class isa;
+  int v2;
+  int v3;
+  int v4;
+  int v5;
+  int v6;
+  int v7;
+  int v8;
+  int v9;
+  int v10;
+  int v11;
+  int v12;
+  int v13;
+  int v14;
+  int v15;
+}
+- (id) init;
+@end
+
+@implementation MyRootClass1
+- (id) init { return self; }
+@end
+
+
+@interface MyRootClass2
+{
+  Class isa;
+  int v2;
+  int v3;
+  int v4;
+  int v5;
+  int v6;
+  int v7;
+  int v8;
+  int v9;
+  int v10;
+  int v11;
+  int v12;
+  int v13;
+  int v14;
+  int v15;
+  /* Adding the 16th variable used to cause bogus warnings to be
+     generated.  */
+  int v16;
+}
+- (id) init;
+@end
+
+@implementation MyRootClass2
+- (id) init { return self; } /* This should not generate a bogus warning.  */
+@end
diff --git a/gcc/testsuite/objc.dg/ivar-problem-1.m b/gcc/testsuite/objc.dg/ivar-problem-1.m
new file mode 100644 (file)
index 0000000..4a87768
--- /dev/null
@@ -0,0 +1,65 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do compile } */
+
+/* This test checks what happens if there are 16 instance variables.
+   In that case, the class was not created correctly.  In this testcase,
+   we have two classes, one with 15 variables and one with 16.  Older
+   GCCs would generate a bogus warning for the second class but not 
+   for the first one.  */
+
+#include <stdlib.h>
+#include <objc/objc.h>
+
+@interface MyRootClass1
+{
+  Class isa;
+  int v2;
+  int v3;
+  int v4;
+  int v5;
+  int v6;
+  int v7;
+  int v8;
+  int v9;
+  int v10;
+  int v11;
+  int v12;
+  int v13;
+  int v14;
+  int v15;
+}
+- (id) init;
+@end
+
+@implementation MyRootClass1
+- (id) init { return self; }
+@end
+
+
+@interface MyRootClass2
+{
+  Class isa;
+  int v2;
+  int v3;
+  int v4;
+  int v5;
+  int v6;
+  int v7;
+  int v8;
+  int v9;
+  int v10;
+  int v11;
+  int v12;
+  int v13;
+  int v14;
+  int v15;
+  /* Adding the 16th variable used to cause bogus warnings to be
+     generated.  */
+  int v16;
+}
+- (id) init;
+@end
+
+@implementation MyRootClass2
+- (id) init { return self; } /* This should not generate a bogus warning.  */
+@end