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 ObjC protocol qualification lossage


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 (is_id): New stub.
* c-tree.h (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.
(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
+ 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 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 || !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
+ 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


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