This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Fix yet another ObjC/ObjC++ ICE...


This is somewhat related to my earlier protocol lookup patch, and
more generally stems from the so-called "comptypes rewrite" done
a bit earlier.  We need to be able to deal with protocol-qualified
class names that were only forward-declared.

Bootstrapped on powerpc-apple-darwin; will do an i686-pc-linux-gnu
bootstrap as well before check-in.

--Zem

[gcc/objc/ChangeLog]
2005-07-07  Ziemowit Laski  <zlaski@apple.com>

        * objc-act.c (objc_build_struct): Pass in an actual @interface
        instead of its name, and annotate the struct created (and all
        existing variants thereof) with the @interface.
        (objc_compare_types): Treat forward-declared ObjC classes
        as stand-alone (root) classes for purposes of type comparisons.
        (build_private_template): Move some code to objc_build_struct().

[gcc/testsuite/ChangeLog]
2005-07-07  Ziemowit Laski  <zlaski@apple.com>

        * obj-c++.dg/proto-lossage-6.mm: New.
        * objc.dg/proto-lossage-6.m: New.

Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.285
diff -u -3 -p -r1.285 objc-act.c
--- gcc/objc/objc-act.c 7 Jul 2005 06:25:34 -0000       1.285
+++ gcc/objc/objc-act.c 7 Jul 2005 22:39:10 -0000
@@ -794,12 +794,13 @@ objc_is_class_id (tree type)
   return OBJC_TYPE_NAME (type) == objc_class_id;
 }

-/* Construct a C struct with tag NAME, a base struct with tag
+/* Construct a C struct with same name as CLASS, a base struct with tag
    SUPER_NAME (if any), and FIELDS indicated.  */

static tree
-objc_build_struct (tree name, tree fields, tree super_name)
+objc_build_struct (tree class, tree fields, tree super_name)
{
+ tree name = CLASS_NAME (class);
tree s = start_struct (RECORD_TYPE, name);
tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
tree t, objc_info = NULL_TREE;
@@ -857,15 +858,26 @@ objc_build_struct (tree name, tree field
= chainon (objc_info,
build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));


+  /* Point the struct at its related Objective-C class.  */
+  INIT_TYPE_OBJC_INFO (s);
+  TYPE_OBJC_INTERFACE (s) = class;
+
   s = finish_struct (s, fields, NULL_TREE);

   for (t = TYPE_NEXT_VARIANT (s); t;
        t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
-    TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
+    {
+      TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
+      /* Replace the IDENTIFIER_NODE with an actual @interface.  */
+      TYPE_OBJC_INTERFACE (t) = class;
+    }

   /* Use TYPE_BINFO structures to point at the super class, if any.  */
   objc_xref_basetypes (s, super);

+  /* Mark this struct as a class template.  */
+  CLASS_STATIC_TEMPLATE (class) = s;
+
   return s;
 }

@@ -1099,6 +1111,16 @@ objc_compare_types (tree ltyp, tree rtyp
   else
     rcls = rproto = NULL_TREE;

+  /* If we could not find an @interface declaration, we must have
+     only seen a @class declaration; for purposes of type comparison,
+     treat it as a stand-alone (root) class.  */
+
+  if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
+    lcls = NULL_TREE;
+
+  if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
+    rcls = NULL_TREE;
+
   /* If either type is an unqualified 'id', we're done.  */
   if ((!lproto && objc_is_object_id (ltyp))
       || (!rproto && objc_is_object_id (rtyp)))
@@ -4109,15 +4131,10 @@ build_private_template (tree class)
 {
   if (!CLASS_STATIC_TEMPLATE (class))
     {
-      tree record = objc_build_struct (CLASS_NAME (class),
+      tree record = objc_build_struct (class,
                                       get_class_ivars (class, false),
                                       CLASS_SUPER_NAME (class));

- /* mark this record as class template - for class type checking */
- INIT_TYPE_OBJC_INFO (record);
- TYPE_OBJC_INTERFACE (record) = class;
- CLASS_STATIC_TEMPLATE (class) = record;
-
/* Set the TREE_USED bit for this struct, so that stab generator
can emit stabs for this struct type. */
if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
Index: gcc/testsuite/obj-c++.dg/proto-lossage-6.mm
===================================================================
RCS file: gcc/testsuite/obj-c++.dg/proto-lossage-6.mm
diff -N gcc/testsuite/obj-c++.dg/proto-lossage-6.mm
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/obj-c++.dg/proto-lossage-6.mm 7 Jul 2005 22:39:15 -0000
@@ -0,0 +1,17 @@
+@class Base;
+@protocol _Protocol;
+
+@interface ClassA {
+}
+-(void) func1:(Base<_Protocol> *)inTarget;
+@end
+
+int main()
+{
+ ClassA* theA = 0;
+ Base<_Protocol>* myBase = 0;
+ [theA func1:myBase];
+
+ return 0;
+}
+
Index: gcc/testsuite/objc.dg/proto-lossage-6.m
===================================================================
RCS file: gcc/testsuite/objc.dg/proto-lossage-6.m
diff -N gcc/testsuite/objc.dg/proto-lossage-6.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/objc.dg/proto-lossage-6.m 7 Jul 2005 22:39:15 -0000
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+@class Base;
+@protocol _Protocol;
+
+@interface ClassA {
+}
+-(void) func1:(Base<_Protocol> *)inTarget;
+@end
+
+int main()
+{
+ ClassA* theA = 0;
+ Base<_Protocol>* myBase = 0;
+ [theA func1:myBase];
+
+ return 0;
+}
+


--------------------------------------------------------------
Ziemowit Laski                 1 Infinite Loop, MS 301-2K
Mac OS X Compiler Group        Cupertino, CA USA  95014-2083
Apple Computer, Inc.           +1.408.974.6229  Fax .5477


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]