Index: objc/objc-act.c
===================================================================
--- objc/objc-act.c     (revision 167099)
+++ objc/objc-act.c     (working copy)
@@ -2137,10 +2137,15 @@ objc_build_struct (tree klass, tree fields, tree s
       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 s
       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);
+  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;
 
-  s = objc_finish_struct (s, fields);
-
   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: objc/ChangeLog
===================================================================
--- objc/ChangeLog      (revision 167099)
+++ objc/ChangeLog      (working copy)
@@ -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: testsuite/ChangeLog
===================================================================
--- testsuite/ChangeLog (revision 167099)
+++ testsuite/ChangeLog (working copy)
@@ -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-23  Iain Sandoe  <iains@gcc.gnu.org>
 
        * gcc.dg/darwin-cfstring-1.c: Adjust format messages.
Index: testsuite/objc.dg/ivar-problem-1.m
===================================================================
--- testsuite/objc.dg/ivar-problem-1.m  (revision 0)
+++ testsuite/objc.dg/ivar-problem-1.m  (revision 0)
@@ -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
Index: testsuite/obj-c++.dg/ivar-problem-1.mm
===================================================================
--- testsuite/obj-c++.dg/ivar-problem-1.mm      (revision 0)
+++ testsuite/obj-c++.dg/ivar-problem-1.mm      (revision 0)
@@ -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
