This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug objc/7993] [3.4/3.5 regression] private variables cannot be shadowed in subclasses
- From: "zack at codesourcery dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 1 Jun 2004 07:28:58 -0000
- Subject: [Bug objc/7993] [3.4/3.5 regression] private variables cannot be shadowed in subclasses
- References: <20020920175601.7993.lminder@gmx.net>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From zack at codesourcery dot com 2004-06-01 07:28 -------
Subject: 3.4/HEAD patches for PR 7993
PR 7993 (objc should allow shadowing private instance variables in
subclasses) has been hanging around for a long time now, mainly
because I thought the fix would be more work than "grab the patch out
of the PR and tweak it a little to fit on mainline." I was wrong.
Appended is the patch - basically the same as the one Nicola Pero
wrote back in 2002 - I'm checking onto mainline and 3.4 branch.
Tested on i686-linux.
zw
2004-06-01 Nicola Pero <nicola@brainstorm.co.uk>
PR objc/7993
* objc-act.c (is_private): Do not emit the 'instance variable %s
is declared private' error.
(is_public): Emit the error after calling is_private.
(lookup_objc_ivar): If the instance variable is private, return 0
- the instance variable is invisible here.
testsuite:
* objc.dg/private-1.m, objc-dg/private-2.m: New testcases.
===================================================================
Index: objc/objc-act.c
--- objc/objc-act.c 15 May 2004 23:07:53 -0000 1.214
+++ objc/objc-act.c 1 Jun 2004 05:28:46 -0000
@@ -6467,15 +6467,9 @@ is_ivar (tree decl_chain, tree ident)
int
is_private (tree decl)
{
- if (TREE_PRIVATE (decl)
- && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
- {
- error ("instance variable `%s' is declared private",
- IDENTIFIER_POINTER (DECL_NAME (decl)));
- return 1;
- }
- else
- return 0;
+ return (TREE_PRIVATE (decl)
+ && ! is_ivar (CLASS_IVARS (implementation_template),
+ DECL_NAME (decl)));
}
/* We have an instance variable reference;, check to see if it is public. */
@@ -6513,7 +6507,14 @@ is_public (tree expr, tree identifier)
== CATEGORY_IMPLEMENTATION_TYPE))
&& (CLASS_NAME (objc_implementation_context)
== OBJC_TYPE_NAME (basetype))))
- return ! is_private (decl);
+ {
+ int private = is_private (decl);
+
+ if (private)
+ error ("instance variable `%s' is declared private",
+ IDENTIFIER_POINTER (DECL_NAME (decl)));
+ return !private;
+ }
/* The 2.95.2 compiler sometimes allowed C functions to access
non-@public ivars. We will let this slide for now... */
@@ -9066,7 +9067,7 @@ lookup_objc_ivar (tree id)
else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
{
if (is_private (decl))
- return error_mark_node;
+ return 0;
else
return build_ivar_reference (id);
}
===================================================================
Index: testsuite/objc.dg/private-1.m
--- testsuite/objc.dg/private-1.m 1 Jan 1970 00:00:00 -0000
+++ testsuite/objc.dg/private-1.m 1 Jun 2004 05:28:47 -0000
@@ -0,0 +1,59 @@
+/* Test errors for accessing @private and @protected variables. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@interface MySuperClass
+{
+@private
+ int private;
+
+@protected
+ int protected;
+
+@public
+ int public;
+}
+- (void) test;
+@end
+
+@implementation MySuperClass
+- (void) test
+{
+ private = 12; /* Ok */
+ protected = 12; /* Ok */
+ public = 12; /* Ok */
+}
+@end
+
+
+@interface MyClass : MySuperClass
+@end
+
+@implementation MyClass
+- (void) test
+{
+ /* Private variables simply don't exist in the subclass. */
+ private = 12;/* { dg-error "undeclared" } */
+ /* { dg-error "function it appears in" "" { target *-*-* } { 37 } } */
+
+ protected = 12; /* Ok */
+ public = 12; /* Ok */
+}
+@end
+
+int main (void)
+{
+ MyClass *m = nil;
+
+ if (m != nil)
+ {
+ int access;
+
+ access = m->private; /* { dg-error "is @private" } */
+ access = m->protected; /* { dg-error "is @protected" } */
+ access = m->public; /* Ok */
+ }
+
+ return 0;
+}
===================================================================
Index: testsuite/objc.dg/private-2.m
--- testsuite/objc.dg/private-2.m 1 Jan 1970 00:00:00 -0000
+++ testsuite/objc.dg/private-2.m 1 Jun 2004 05:28:47 -0000
@@ -0,0 +1,54 @@
+/* Test warnings for shadowing instance variables. */
+/* Author: Nicola Pero <nicola@brainstorm.co.uk>. */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@interface MySuperClass
+{
+@private
+ int private;
+
+@protected
+ int protected;
+
+@public
+ int public;
+}
+- (void) test;
+@end
+
+@implementation MySuperClass
+- (void) test
+{
+ /* FIXME: I wonder if the warnings shouldn't be better generated
+ when the variable is declared, rather than used! */
+ int private = 12;
+ int protected = 12;
+ int public = 12;
+ int a;
+
+ a = private; /* { dg-warning "hides instance variable" } */
+ a = protected; /* { dg-warning "hides instance variable" } */
+ a = public; /* { dg-warning "hides instance variable" } */
+}
+@end
+
+
+@interface MyClass : MySuperClass
+@end
+
+@implementation MyClass
+- (void) test
+{
+ int private = 12;
+ int protected = 12;
+ int public = 12;
+ int a;
+
+ /* The private variable can be shadowed without warnings, because
+ * it's invisible, and not accessible, to the subclass! */
+ a = private; /* Ok */
+ a = protected; /* { dg-warning "hides instance variable" } */
+ a = public; /* { dg-warning "hides instance variable" } */
+}
+@end
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=7993