diff mbox

ObjC/ObjC++: fix ICE on duplicate @implementation of the same class

Message ID 1291056091.12541206@192.168.2.228
State New
Headers show

Commit Message

Nicola Pero Nov. 29, 2010, 6:41 p.m. UTC
This patch fixes the ObjC/ObjC++ ICE when there is a duplicate @implementation
of the same Objective-C class.  Testcases included.

Ok to commit ?

Thanks

Comments

Mike Stump Nov. 29, 2010, 8:28 p.m. UTC | #1
On Nov 29, 2010, at 10:41 AM, Nicola Pero wrote:
> This patch fixes the ObjC/ObjC++ ICE when there is a duplicate @implementation
> of the same Objective-C class.  Testcases included.
> 
> Ok to commit ?

Ok.
diff mbox

Patch

Index: objc/objc-act.c
===================================================================
--- objc/objc-act.c     (revision 167242)
+++ objc/objc-act.c     (working copy)
@@ -9540,10 +9540,13 @@  start_class (enum tree_code code, tree class_name,
            {
              error ("reimplementation of class %qE",
                     class_name);
-             return error_mark_node;
+             /* TODO: error message saying where it was previously
+                implemented.  */
+             break;
            }
-       implemented_classes = tree_cons (NULL_TREE, class_name,
-                                        implemented_classes);
+       if (chain == NULL_TREE)
+         implemented_classes = tree_cons (NULL_TREE, class_name,
+                                          implemented_classes);
       }
 
       /* Reset for multiple classes per file.  */
Index: objc/ChangeLog
===================================================================
--- objc/ChangeLog      (revision 167242)
+++ objc/ChangeLog      (working copy)
@@ -1,5 +1,11 @@ 
 2010-11-29  Nicola Pero  <nicola.pero@meta-innovation.com>
 
+       * objc-act.c (start_class): When a class is reimplemented,
+       generate an error and avoid adding the class to the list of
+       implemented classes again, but do not return error_mark_node.
+
+2010-11-29  Nicola Pero  <nicola.pero@meta-innovation.com>
+
        * objc-act.c (objc_eh_runtime_type): Avoid ICE if error_mark_node
        is passed as argument.
        (objc_begin_catch_clause): Added code to deal with an
Index: testsuite/ChangeLog
===================================================================
--- testsuite/ChangeLog (revision 167242)
+++ testsuite/ChangeLog (working copy)
@@ -1,3 +1,8 @@ 
+2010-11-29  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc.dg/duplicate-class-1.m: New.
+       * obj-c++.dg/duplicate-class-1.mm: New.
+
 2010-11-29  Iain Sandoe  <iains@gcc.gnu.org>
            Mike Stump  <mrs@gcc.gnu.org>
 
Index: testsuite/objc.dg/duplicate-class-1.m
===================================================================
--- testsuite/objc.dg/duplicate-class-1.m       (revision 0)
+++ testsuite/objc.dg/duplicate-class-1.m       (revision 0)
@@ -0,0 +1,31 @@ 
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do compile } */
+
+/* Test that a duplicated @implementation for the same class does not
+   crash the compiler.  */
+
+@interface Test
+{
+  Class isa;
+}
+- (int) test;
+@end
+
+@implementation Test
+- (int) test
+{
+  return 4;
+}
+@end
+
+/* The most likely cause is that the programmer meant this to be a
+   category, so check what happens if we have some different methods
+   in there.  */
+@implementation Test
+- (int) test2  /* { dg-error "reimplementation of class .Test." } */
+{
+  return [self test];
+}
+@end
+/* { dg-warning "incomplete implementation" "" { target *-*-* } 29 } */
+/* { dg-warning "not found" "" { target *-*-* } 29 } */
Index: testsuite/obj-c++.dg/duplicate-class-1.mm
===================================================================
--- testsuite/obj-c++.dg/duplicate-class-1.mm   (revision 0)
+++ testsuite/obj-c++.dg/duplicate-class-1.mm   (revision 0)
@@ -0,0 +1,31 @@ 
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do compile } */
+
+/* Test that a duplicated @implementation for the same class does not
+   crash the compiler.  */
+
+@interface Test
+{
+  Class isa;
+}
+- (int) test;
+@end
+
+@implementation Test
+- (int) test
+{
+  return 4;
+}
+@end
+
+/* The most likely cause is that the programmer meant this to be a
+   category, so check what happens if we have some different methods
+   in there.  */
+@implementation Test /* { dg-error "reimplementation of class .Test." } */
+- (int) test2
+{
+  return [self test];
+}
+@end
+/* { dg-warning "incomplete implementation" "" { target *-*-* } 29 } */
+/* { dg-warning "not found" "" { target *-*-* } 29 } */