In gcc/objc/: 2010-12-30 Nicola Pero <nicola.pero@meta-innovation.com>

In gcc/objc/:
2010-12-30  Nicola Pero  <nicola.pero@meta-innovation.com>

	* objc-act.c (objc_types_are_equivalent): Fixed comparing protocol
	lists.  Check them two-ways to fix comparisons when one protocol
	implements the other one, or when one list contains duplicated
	protocols.

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

	* objc.dg/method-conflict-3.m: New.
	* objc.dg/method-conflict-4.m: New.	
	* obj-c++.dg/method-conflict-3.m: New.	
	* obj-c++.dg/method-conflict-4.mm: New.

From-SVN: r168356
This commit is contained in:
Nicola Pero 2010-12-30 22:02:09 +00:00 committed by Nicola Pero
parent 8abf21313f
commit 27e09ff9fc
7 changed files with 264 additions and 7 deletions

View File

@ -1,3 +1,10 @@
2010-12-30 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-act.c (objc_types_are_equivalent): Fixed comparing protocol
lists. Check them two-ways to fix comparisons when one protocol
implements the other one, or when one list contains duplicated
protocols.
2010-12-30 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-act.c (objc_add_method): When emitting an error because a

View File

@ -11925,9 +11925,8 @@ start_method_def (tree method)
really_start_method (objc_method_context, parm_info);
}
/* Return 1 if TYPE1 is equivalent to TYPE2
for purposes of method overloading. */
/* Return 1 if TYPE1 is equivalent to TYPE2 for purposes of method
overloading. */
static int
objc_types_are_equivalent (tree type1, tree type2)
{
@ -11941,6 +11940,7 @@ objc_types_are_equivalent (tree type1, tree type2)
if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
return 0;
/* Compare the protocol lists. */
type1 = (TYPE_HAS_OBJC_INFO (type1)
? TYPE_OBJC_PROTOCOL_LIST (type1)
: NULL_TREE);
@ -11948,14 +11948,34 @@ objc_types_are_equivalent (tree type1, tree type2)
? TYPE_OBJC_PROTOCOL_LIST (type2)
: NULL_TREE);
if (list_length (type1) == list_length (type2))
{
for (; type2; type2 = TREE_CHAIN (type2))
if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
/* If there are no protocols (most common case), the types are
identical. */
if (type1 == NULL_TREE && type2 == NULL_TREE)
return 1;
/* If one has protocols, and the other one hasn't, they are not
identical. */
if ((type1 == NULL_TREE && type2 != NULL_TREE)
|| (type1 != NULL_TREE && type2 == NULL_TREE))
return 0;
else
{
/* Else, both have protocols, and we need to do the full
comparison. It is possible that either type1 or type2
contain some duplicate protocols in the list, so we can't
even just compare list_length as a first check. */
tree t;
for (t = type2; t; t = TREE_CHAIN (t))
if (!lookup_protocol_in_reflist (type1, TREE_VALUE (t)))
return 0;
for (t = type1; t; t = TREE_CHAIN (t))
if (!lookup_protocol_in_reflist (type2, TREE_VALUE (t)))
return 0;
return 1;
}
return 0;
}
/* Return 1 if TYPE1 has the same size and alignment as TYPE2. */

View File

@ -1,3 +1,10 @@
2010-12-30 Nicola Pero <nicola.pero@meta-innovation.com>
* objc.dg/method-conflict-3.m: New.
* objc.dg/method-conflict-4.m: New.
* obj-c++.dg/method-conflict-3.m: New.
* obj-c++.dg/method-conflict-4.mm: New.
2010-12-30 Nicola Pero <nicola.pero@meta-innovation.com>
* objc.dg/class-extension-3.m: Updated.

View File

@ -0,0 +1,65 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
#include <objc/objc.h>
/* Test that the compiler can correctly compare protocols in types of
method signatures. */
@protocol A, B, C;
@interface MyClass
- (void) method1: (id)x;
- (void) method1: (id)x; /* Ok */
- (void) method2: (id <A>)x;
- (void) method2: (id <A>)x; /* Ok */
- (void) method3: (id <A, B>)x;
- (void) method3: (id <A, B>)x; /* Ok */
- (void) method4: (id <A, B>)x;
- (void) method4: (id <A, B, B>)x; /* Ok */
- (void) method5: (id <A, A, B>)x;
- (void) method5: (id <A, B, B>)x; /* Ok */
- (void) method6: (id <A, A, B, B, C, C>)x;
- (void) method6: (id <C, A, B>)x; /* Ok */
- (void) method7: (id)x; /* { dg-warning "previous declaration" } */
- (void) method7: (id <A>)x; /* { dg-error "duplicate declaration" } */
- (void) method8: (id <A>)x; /* { dg-warning "previous declaration" } */
- (void) method8: (id)x; /* { dg-error "duplicate declaration" } */
- (void) method9: (id <A>)x; /* { dg-warning "previous declaration" } */
- (void) method9: (id <B>)x; /* { dg-error "duplicate declaration" } */
- (void) methodA: (id <A>)x; /* { dg-warning "previous declaration" } */
- (void) methodA: (id <A, B>)x; /* { dg-error "duplicate declaration" } */
/* FIXME: Bug in the testsuite - the following are done Ok by the compiler, but
the testsuite barfs so we have to comment out the tests. */
/* - (void) methodB: (id <A, B>)x; dg-warning "previous declaration" */
/* - (void) methodB: (id <A>)x; dg-error "duplicate declaration" */
/* - (void) methodC: (id <A, B, C>)x; dg-warning "previous declaration" */
/* - (void) methodC: (id <A, B>)x; dg-error "duplicate declaration" */
/* - (void) methodD: (id <A, B, C>)x; dg-warning "previous declaration" */
/* - (void) methodD: (id <A, B, A>)x; dg-error "duplicate declaration" */
/* - (void) methodE: (MyClass <A, B, C> *)x; dg-warning "previous declaration" */
/* - (void) methodE: (MyClass <A, B, A> *)x; dg-error "duplicate declaration" */
- (void) methodF: (MyClass <A, B, A> *)x;
- (void) methodF: (MyClass <A, B, A> *)x; /* Ok */
/* - (void) methodG: (MyClass *)x; dg-warning "previous declaration" */
/* - (void) methodG: (MyClass <A, B, C> *)x; dg-error "duplicate declaration" */
/* - (void) methodH: (MyClass <A, C>*)x; dg-warning "previous declaration" */
/* - (void) methodH: (MyClass *)x; dg-error "duplicate declaration" */
@end

View File

@ -0,0 +1,48 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
#include <objc/objc.h>
/* Test that the compiler can correctly compare protocols in types of
method signatures. In this test we look at protocols implementing
other protocols. The fact that one protocol implements another one
doesn't mean that they are identical. */
@protocol A
- (void) doSomething;
@end
@protocol B <A>
- (void) doSomethingElse;
@end
@protocol C <A>
- (void) doYetSomethingElse;
@end
@interface MyClass2
- (void) aMethod: (id <A>)x; /* { dg-error "previous declaration" } */
- (void) aMethod: (id <B>)x; /* { dg-error "duplicate declaration" } */
- (void) bMethod: (id <B>)x; /* { dg-error "previous declaration" } */
- (void) bMethod: (id <A>)x; /* { dg-error "duplicate declaration" } */
- (void) cMethod: (id <A, B>)x;
- (void) cMethod: (id <B>)x; /* Ok - because if you implement B, then you also implement A, so <B> == <A, B> */
- (void) dMethod: (id <A, B>)x;
- (void) dMethod: (id <B, A>)x; /* Ok */
/* FIXME: The compiler works, but the testsuite produces errors anyway. */
/* - (void) eMethod: (id <A>)x; dg-error "previous declaration" */
/* - (void) eMethod: (id <B, C>)x; dg-error "duplicate declaration" */
/*- (void) fMethod: (id <B, C>)x; dg-error "previous declaration" */
/*- (void) fMethod: (id <A>)x; dg-error "duplicate declaration" */
/* - (void) gMethod: (id <A>)x; dg-error "previous declaration" */
/* - (void) gMethod: (id <A, B, C>)x; dg-error "duplicate declaration" */
/* - (void) hMethod: (id <A, B, C>)x; dg-error "previous declaration" */
/* - (void) hMethod: (id <A>)x; dg-error "duplicate declaration" */
@end

View File

@ -0,0 +1,63 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
#include <objc/objc.h>
/* Test that the compiler can correctly compare protocols in types of
method signatures. */
@protocol A, B, C;
@interface MyClass
- (void) method1: (id)x;
- (void) method1: (id)x; /* Ok */
- (void) method2: (id <A>)x;
- (void) method2: (id <A>)x; /* Ok */
- (void) method3: (id <A, B>)x;
- (void) method3: (id <A, B>)x; /* Ok */
- (void) method4: (id <A, B>)x;
- (void) method4: (id <A, B, B>)x; /* Ok */
- (void) method5: (id <A, A, B>)x;
- (void) method5: (id <A, B, B>)x; /* Ok */
- (void) method6: (id <A, A, B, B, C, C>)x;
- (void) method6: (id <C, A, B>)x; /* Ok */
- (void) method7: (id)x; /* { dg-message "previous declaration" } */
- (void) method7: (id <A>)x; /* { dg-error "duplicate declaration" } */
- (void) method8: (id <A>)x; /* { dg-message "previous declaration" } */
- (void) method8: (id)x; /* { dg-error "duplicate declaration" } */
- (void) method9: (id <A>)x; /* { dg-message "previous declaration" } */
- (void) method9: (id <B>)x; /* { dg-error "duplicate declaration" } */
- (void) methodA: (id <A>)x; /* { dg-message "previous declaration" } */
- (void) methodA: (id <A, B>)x; /* { dg-error "duplicate declaration" } */
- (void) methodB: (id <A, B>)x; /* { dg-message "previous declaration" } */
- (void) methodB: (id <A>)x; /* { dg-error "duplicate declaration" } */
- (void) methodC: (id <A, B, C>)x; /* { dg-message "previous declaration" } */
- (void) methodC: (id <A, B>)x; /* { dg-error "duplicate declaration" } */
- (void) methodD: (id <A, B, C>)x; /* { dg-message "previous declaration" } */
- (void) methodD: (id <A, B, A>)x; /* { dg-error "duplicate declaration" } */
- (void) methodE: (MyClass <A, B, C> *)x; /* { dg-message "previous declaration" } */
- (void) methodE: (MyClass <A, B, A> *)x; /* { dg-error "duplicate declaration" } */
- (void) methodF: (MyClass <A, B, A> *)x;
- (void) methodF: (MyClass <A, B, A> *)x; /* Ok */
- (void) methodG: (MyClass *)x; /* { dg-message "previous declaration" } */
- (void) methodG: (MyClass <A, B, C> *)x; /* { dg-error "duplicate declaration" } */
- (void) methodH: (MyClass <A, C>*)x; /* { dg-message "previous declaration" } */
- (void) methodH: (MyClass *)x; /* { dg-error "duplicate declaration" } */
@end

View File

@ -0,0 +1,47 @@
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
/* { dg-do compile } */
#include <objc/objc.h>
/* Test that the compiler can correctly compare protocols in types of
method signatures. In this test we look at protocols implementing
other protocols. The fact that one protocol implements another one
doesn't mean that they are identical. */
@protocol A
- (void) doSomething;
@end
@protocol B <A>
- (void) doSomethingElse;
@end
@protocol C <A>
- (void) doYetSomethingElse;
@end
@interface MyClass2
- (void) aMethod: (id <A>)x; /* { dg-message "previous declaration" } */
- (void) aMethod: (id <B>)x; /* { dg-error "duplicate declaration" } */
- (void) bMethod: (id <B>)x; /* { dg-message "previous declaration" } */
- (void) bMethod: (id <A>)x; /* { dg-error "duplicate declaration" } */
- (void) cMethod: (id <A, B>)x;
- (void) cMethod: (id <B>)x; /* Ok - because if you implement B, then you also implement A, so <B> == <A, B> */
- (void) dMethod: (id <A, B>)x;
- (void) dMethod: (id <B, A>)x; /* Ok */
- (void) eMethod: (id <A>)x; /* { dg-message "previous declaration" } */
- (void) eMethod: (id <B, C>)x; /* { dg-error "duplicate declaration" } */
- (void) fMethod: (id <B, C>)x; /* { dg-message "previous declaration" } */
- (void) fMethod: (id <A>)x; /* { dg-error "duplicate declaration" } */
- (void) gMethod: (id <A>)x; /* { dg-message "previous declaration" } */
- (void) gMethod: (id <A, B, C>)x; /* { dg-error "duplicate declaration" } */
- (void) hMethod: (id <A, B, C>)x; /* { dg-message "previous declaration" } */
- (void) hMethod: (id <A>)x; /* { dg-error "duplicate declaration" } */
@end