7993 – [3.4/4.0 regression] private variables cannot be shadowed in subclasses (original) (raw)
If an instance variable is declared @private, the same variable name can't be reused as name for local variables when implementing methods of subclasses.
This is wrong, because when writing subclasses you should not have to worry about private implementation details of the superclass, such as names of private variables. (I don't know, however, any official specification of the Objective-C language, and therefore can't refer to any document confirming my claim about the purpose of @private.)
The problem occurs in any of the gcc 3.x-versions I tested.
Release: 3.3 20020916 (experimental)
Environment: System: Linux fanzthesecond 2.4.18 #33 Thu Jul 18 04:56:44 CEST 2002 i686 unknown Architecture: i686
host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: ../gcc-20020916/configure --enable-languages=objc
How-To-Repeat:
The following code reproduces the problem:
@interface Base { @private int f; } @end
@interface Sub : Base { } -(float)squareOf:(float)f; @end
@implementation Sub
-(float)squareOf:(float)g { float f = g; return f*f; } @end
Compiling this I get the following error messages:
test1.m: In function -[Sub squareOf:]': test1.m:17: error: instance variable f' is declared private
test1.m:17: warning: local declaration of f' hides instance variable test1.m:17: error: instance variable f' is declared private
test1.m:17: warning: local declaration of `f' hides instance variable
Comment 1 Drea Pinski 2003-05-25 22:14:43 UTC
confirmed error on mainline (20030525). confirmed working on gcc version 2.95.3 20010125 (prerelease). There fore this is regression from 2.95.3.
Comment 2 Drea Pinski 2003-06-24 00:04:10 UTC
The error happens also happens in 3.0.4.
Comment 3 Drea Pinski 2003-06-24 00:13:51 UTC
For some reason on powerpc-apple-darwin6.6 this testcase passes with the mainline (20030623) and 3.3.1 (20030616), yes this does not make sense (except that on darwin some things dealing with objective-c is different but it even passes with -fgnu-runtime).
Comment 4 Drea Pinski 2003-07-12 00:05:28 UTC
This happens every where except on --darwin*.
Comment 6 Mark Mitchell 2003-07-20 01:12:06 UTC
Stan Shebs wrote this message:
http://gcc.gnu.org/ml/gcc/2003-07/msg01168.html
Hopefully, his pondering will yield a decision soon. :-)
In the meantime, I'm postponing this PR until GCC 3.3.2. If Stan makes a decision soon we can still put this patch in GCC 3.3.1.
Comment 7 Stan Shebs 2003-09-09 21:12:07 UTC
Yes, this change should be made, and would be reasonable for 3.3.2. (It looks like a side effect of a long-ago reorg by Zack.)
Comment 8 Steven Bosscher 2003-10-04 07:13:15 UTC
Stan,
This Bug 7993 is targeted for 3.3.2, and a patch has been pending for more than a year now!!! (http://gcc.gnu.org/ml/gcc-patches/2002-09/msg01497.html)
You said about the patch: "Yes, this change should be made, and would be reasonable for 3.3.2. (It looks like a side effect of a long-ago reorg by Zack.)"
So, why hasn't the patch been commited (or has it) and the bug been closed?
Comment 9 Mark Mitchell 2003-10-16 02:36:51 UTC
I have no idea why the patch hasn't been applied, but I'm not going to take chances. Postponed until GCC 3.3.3.
Stan, can you at least put this in on the mainline?
Comment 10 Drea Pinski 2003-10-30 09:36:43 UTC
Zem could you look at this bug, there is a patch that Stan says is okay but he has not applied it yet, there is a whole history, it even been okayed for 3.3.3, could you apply it on the mainline and the 3.3 branch. Thanks.
Comment 11 Zack Weinberg 2003-12-02 00:13:49 UTC
Brief experimentation on x86-linux indicates that mainline still has the issue and that the patch doesn't fit on mainline anymore. I'd like to ask that this not be addressed on mainline just yet as I am about to undertake more work on c-decl.c which may affect the patch.
I don't see any reason why this shouldn't be applied at once to the 3.3 branch.
Comment 12 Gabriel Dos Reis 2003-12-21 18:22:10 UTC
Zack, Stan and Zem --
Can anyone of you tell me if I should close this on 3.3.3 as WONTFIX? It looks to me that it is taking long to make decision on this bug and related patch.
-- Gaby
Comment 13 Zack Weinberg 2003-12-21 18:44:03 UTC
As I said in my earlier comment, I don't see any reason why the existing patch should not be applied at once to the 3.3 branch. The bug should then be retitled a 3.4 regression and reassigned to me.
zw
Comment 14 Gabriel Dos Reis 2003-12-21 18:58:13 UTC
Subject: Re: [3.3/3.4 regression] private variables cannot be shadowed in subclasses
"zack at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes:
| As I said in my earlier comment, I don't see any reason why the | existing patch should not be applied at once to the 3.3 branch. The | bug should then be retitled a 3.4 regression and reassigned to me.
Thanks for the prompt reply.
-- Gaby
Comment 16 Gabriel Dos Reis 2004-01-14 07:54:37 UTC
Fixed for 3.3.3 (applied patch referenced in audit trail).
Reassigned to ZAck -- per his request
Comment 17 Gabriel Dos Reis 2004-01-14 07:58:57 UTC
Gloops. This is not fixed in 3.4.0 Looks like one can't set things straight with bugzilla and one has to click,reload, click, ... for every single of informatiion.
Comment 18 Gabriel Dos Reis 2004-01-14 08:00:41 UTC
balh.
bugzilla seems to require noise traffic for every single piece of information.
Comment 19 Mark Mitchell 2004-03-16 22:35:58 UTC
As sad as it is that this bug has not yet been fixed, it is still not a showstopper. So, I've postponed it until 3.4.1.
Comment 20 Mark Mitchell 2004-05-31 22:26:50 UTC
Zack --
Is it practical to fix this in 3.4.1? Or, is that going to require a bunch of your c-decl.c patches? In fact, in general, would you please go through the 3.4.1 regressions and indicate which you think are impractical to fix without the c-decl.c surgery?
Thanks,
-- Mark
Comment 21 Zack Weinberg 2004-06-01 04:19:20 UTC
This patch can be fixed in 3.4 without the c-decl.c rewrite. The existing patch will work with only minor tweaks. I am testing 3.4 and mainline patches for this bug right now.
Comment 22 Zack Weinberg 2004-06-01 07:28:41 UTC
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](show%5Fbug.cgi?id=7993 "RESOLVED FIXED - [3.4/4.0 regression] private variables cannot be shadowed in subclasses")
* 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
Comment 25 Zack Weinberg 2004-06-01 07:41:33 UTC
fixed.