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
confirmed error on mainline (20030525). confirmed working on gcc version 2.95.3 20010125 (prerelease). There fore this is regression from 2.95.3.
The error happens also happens in 3.0.4.
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).
This happens every where except on *-*-darwin*.
A patch for this has been submitted a long time ago here: http://gcc.gnu.org/ml/gcc-patches/2002-09/msg01497.html
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.
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.)
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?
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?
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.
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.
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
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
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
Subject: Bug 7993 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_3-branch Changes by: gdr@gcc.gnu.org 2004-01-14 07:52:39 Modified files: gcc : ChangeLog gcc/objc : objc-act.c Added files: gcc/testsuite/objc.dg: private-1.m private-2.m Log message: 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. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.16114.2.879&r2=1.16114.2.880 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/objc/objc-act.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.160&r2=1.160.4.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-1.m.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-2.m.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.1.2.1
Fixed for 3.3.3 (applied patch referenced in audit trail). Reassigned to ZAck -- per his request
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.
balh. bugzilla seems to require noise traffic for every single piece of information.
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.
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
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.
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
Subject: Bug 7993 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: zack@gcc.gnu.org 2004-06-01 07:34:40 Modified files: gcc : ChangeLog gcc/objc : objc-act.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/objc.dg: private-1.m private-2.m Log message: 2004-06-01 Nicola Pero <nicola@brainstorm.co.uk> Fix 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. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.2326.2.463&r2=2.2326.2.464 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/objc/objc-act.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.202.4.1&r2=1.202.4.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.193&r2=1.3389.2.194 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-1.m.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.8.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-2.m.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.8.1
Subject: Bug 7993 CVSROOT: /cvs/gcc Module name: gcc Changes by: zack@gcc.gnu.org 2004-06-01 07:40:03 Modified files: gcc : ChangeLog gcc/objc : objc-act.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/objc.dg: private-1.m private-2.m Log message: 2004-06-01 Nicola Pero <nicola@brainstorm.co.uk> Fix 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. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.3811&r2=2.3812 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/objc/objc-act.c.diff?cvsroot=gcc&r1=1.214&r2=1.215 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3800&r2=1.3801 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-1.m.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-2.m.diff?cvsroot=gcc&r1=1.1&r2=1.2
fixed.