This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Fix ObjC protocol qualification lossage (Take 2)
- From: Ziemowit Laski <zlaski at apple dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 6 Sep 2002 16:13:21 -0700
- Subject: PATCH: Fix ObjC protocol qualification lossage (Take 2)
(Renamed is_id to objc_is_id, per Neil's suggestion)
The following patch addresses a bug whereby the protocol
qualifications of ObjC objects were sometimes forgotten,
leading to erroneous warning messages. This issue was raised
on the gcc list a few days ago, and I believe it to be a regression
from 2.95.x.
Bootstrapped on i686-pc-linux-gnu with no regressions, plus there
is a test case. OK?
[gcc/ChangeLog]
2002-09-06 Ziemowit Laski <zlaski@apple.com>
* c-lang.c (objc_is_id): New stub.
* c-tree.h (objc_is_id): New forward declaration.
* c-typeck.c (build_c_cast): Do not strip protocol
qualifiers from 'id' type.
* objc/objc-act.c (objc_comptypes): Correct handling
of protocol qualifiers.
(objc_is_id): New.
[gcc/testsuite/ChangeLog]
2002-09-05 Ziemowit Laski <zlaski@apple.com>
* objc.dg/proto-lossage-1.m: New test.
Index: gcc/c-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lang.c,v
retrieving revision 1.99
diff -c -3 -p -r1.99 c-lang.c
*** gcc/c-lang.c 3 Sep 2002 16:40:29 -0000 1.99
--- gcc/c-lang.c 6 Sep 2002 19:14:12 -0000
*************** is_class_name (arg)
*** 174,179 ****
--- 174,186 ----
return 0;
}
+ tree
+ objc_is_id (arg)
+ tree arg ATTRIBUTE_UNUSED;
+ {
+ return 0;
+ }
+
void
objc_check_decl (decl)
tree decl ATTRIBUTE_UNUSED;
Index: gcc/c-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-tree.h,v
retrieving revision 1.106
diff -c -3 -p -r1.106 c-tree.h
*** gcc/c-tree.h 3 Sep 2002 16:40:29 -0000 1.106
--- gcc/c-tree.h 6 Sep 2002 19:14:12 -0000
*************** struct lang_type GTY(())
*** 165,170 ****
--- 165,171 ----
/* in c-lang.c and objc-act.c */
extern tree lookup_interface PARAMS ((tree));
extern tree is_class_name PARAMS ((tree));
+ extern tree objc_is_id PARAMS ((tree));
extern void objc_check_decl PARAMS ((tree));
extern void finish_file PARAMS ((void));
extern int objc_comptypes PARAMS ((tree, tree,
int));
Index: gcc/c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.204
diff -c -3 -p -r1.204 c-typeck.c
*** gcc/c-typeck.c 3 Sep 2002 16:40:29 -0000 1.204
--- gcc/c-typeck.c 6 Sep 2002 19:14:22 -0000
*************** build_c_cast (type, expr)
*** 3577,3583 ****
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
! type = TYPE_MAIN_VARIANT (type);
#if 0
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
--- 3577,3588 ----
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
!
! /* The ObjC front-end uses TYPE_MAIN_VARIANT to tie together types
differing
! only in <protocol> qualifications. But when constructing cast
expressions,
! the protocols do matter and must be kept around. */
! if (!flag_objc || !objc_is_id (type))
! type = TYPE_MAIN_VARIANT (type);
#if 0
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.155
diff -c -3 -p -r1.155 objc-act.c
*** gcc/objc/objc-act.c 3 Sep 2002 10:39:40 -0000 1.155
--- gcc/objc/objc-act.c 6 Sep 2002 19:14:23 -0000
*************** objc_comptypes (lhs, rhs, reflexive)
*** 648,660 ****
tree cat;
rproto_list = CLASS_PROTOCOL_LIST (rinter);
- /* If the underlying ObjC class does not have
- protocols attached to it, perhaps there are
- "one-off" protocols attached to the rhs?
- E.g., 'id<MyProt> foo;'. */
- if (!rproto_list)
- rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE
(rhs));
rproto = lookup_protocol_in_reflist (rproto_list,
p);
/* Check for protocols adopted by categories. */
cat = CLASS_CATEGORY_LIST (rinter);
--- 648,663 ----
tree cat;
rproto_list = CLASS_PROTOCOL_LIST (rinter);
rproto = lookup_protocol_in_reflist (rproto_list,
p);
+ /* If the underlying ObjC class does not have
+ the protocol we're looking for, check for
"one-off"
+ protocols (e.g., `NSObject<MyProt> foo;')
attached
+ to the rhs. */
+ if (!rproto)
+ {
+ rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE
(rhs));
+ rproto = lookup_protocol_in_reflist
(rproto_list, p);
+ }
/* Check for protocols adopted by categories. */
cat = CLASS_CATEGORY_LIST (rinter);
*************** is_class_name (ident)
*** 2259,2264 ****
--- 2262,2278 ----
}
return 0;
+ }
+
+ tree
+ objc_is_id (ident)
+ tree ident;
+ {
+ /* NB: This function may be called before the ObjC front-end
+ has been initialized, in which case ID_TYPE will be NULL. */
+ return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
+ ? id_type
+ : NULL_TREE;
}
Index: gcc/testsuite/objc.dg/proto-lossage-1.m
===================================================================
RCS file: gcc/testsuite/objc.dg/proto-lossage-1.m
diff -N gcc/testsuite/objc.dg/proto-lossage-1.m
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/objc.dg/proto-lossage-1.m 6 Sep 2002 22:06:31
-0000
***************
*** 0 ****
--- 1,44 ----
+ /* Test for situations in which protocol conformance information
+ may be lost, leading to superfluous warnings. */
+ /* Author: Ziemowit Laski <zlaski@apple.com>. */
+ /* { dg-do compile } */
+ /* { dg-options "-Werror" } */
+
+ /* One-line substitute for objc/objc.h */
+ typedef struct objc_object { struct objc_class *class_pointer; } *id;
+
+ @protocol NSObject
+ - (int)someValue;
+ @end
+
+ @interface NSObject <NSObject>
+ @end
+
+ @protocol PlateMethods
+ - (void)someMethod;
+ @end
+
+ @interface Foo {
+ NSObject <PlateMethods> *plate;
+ id <PlateMethods> plate1;
+ NSObject *plate2;
+ }
+ - (id <PlateMethods>) getPlate;
+ - (id <NSObject>) getPlate1;
+ - (int) getValue;
+ @end
+
+ @implementation Foo
+ - (id <PlateMethods>) getPlate {
+ return plate; /* { dg-bogus "does not implement" } */
+ }
+ - (id <NSObject>) getPlate1 {
+ return (id <NSObject>)plate1; /* { dg-bogus "does not conform" } */
+ }
+ - (int) getValue {
+ int i = [plate1 someValue]; /* { dg-warning "not implemented by
protocol" } */
+ int j = [(id <NSObject>)plate1 someValue]; /* { dg-bogus "not
implemented by protocol" } */
+ int k = [(id)plate1 someValue]; /* { dg-bogus "not implemented by
protocol" } */
+ return i + j + k;
+ }
+ @end
--------------------------------------------------------------
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